CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PluginFactoryBase.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: PluginManager
4 // Class : PluginFactoryBase
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Wed Apr 4 13:09:50 EDT 2007
11 //
12 
13 // system include files
14 #include <cassert>
15 
16 // user include files
21 
22 namespace edmplugin {
23  //
24  // constants, enums and typedefs
25  //
26 
27  //
28  // static data member definitions
29  //
30 
31  //
32  // constructors and destructor
33  //
34 
35  // PluginFactoryBase::PluginFactoryBase(const PluginFactoryBase& rhs)
36  // {
37  // // do actual copying here;
38  // }
39 
41 
42  //
43  // assignment operators
44  //
45  // const PluginFactoryBase& PluginFactoryBase::operator=(const PluginFactoryBase& rhs)
46  // {
47  // //An exception safe implementation is
48  // PluginFactoryBase temp(rhs);
49  // swap(rhs);
50  //
51  // return *this;
52  // }
53 
54  //
55  // member functions
56  //
58 
62  info.name_ = iName;
63  newPluginAdded_(category(), info);
64  }
65 
66  void* PluginFactoryBase::findPMaker(const std::string& iName) const {
67  //do we already have it?
68  Plugins::const_iterator itFound = m_plugins.find(iName);
69  if (itFound == m_plugins.end()) {
70  std::string lib = PluginManager::get()->load(this->category(), iName).path().string();
71  itFound = m_plugins.find(iName);
72  if (itFound == m_plugins.end()) {
73  throw cms::Exception("PluginCacheError")
74  << "The plugin '" << iName << "' should have been in loadable\n '" << lib
75  << "'\n but was not there. This means the plugin cache is incorrect. Please run 'EdmPluginRefresh " << lib
76  << "'";
77  }
78  //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
79  auto const& value = itFound->second.front();
80  while (value.m_ptr.load(std::memory_order_acquire) == nullptr) {
81  }
82  } else {
83  //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
84  auto const& value = itFound->second.front();
85  while (value.m_ptr.load(std::memory_order_acquire) == nullptr) {
86  }
87  checkProperLoadable(iName, value.m_name);
88  }
89  return itFound->second.front().m_ptr.load(std::memory_order_acquire);
90  }
91 
92  void* PluginFactoryBase::tryToFindPMaker(const std::string& iName) const {
93  //do we already have it?
94  Plugins::const_iterator itFound = m_plugins.find(iName);
95  if (itFound == m_plugins.end()) {
96  const SharedLibrary* slib = PluginManager::get()->tryToLoad(this->category(), iName);
97  if (nullptr != slib) {
98  std::string lib = slib->path().string();
99  itFound = m_plugins.find(iName);
100  if (itFound == m_plugins.end()) {
101  throw cms::Exception("PluginCacheError")
102  << "The plugin '" << iName << "' should have been in loadable\n '" << lib
103  << "'\n but was not there. This means the plugin cache is incorrect. Please run 'EdmPluginRefresh "
104  << lib << "'";
105  }
106  }
107  } else {
108  //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
109  auto const& value = itFound->second.front();
110  while (value.m_ptr.load(std::memory_order_acquire) == nullptr) {
111  }
112  checkProperLoadable(iName, value.m_name);
113  }
114  return itFound != m_plugins.end() ? itFound->second.front().m_ptr.load(std::memory_order_acquire) : nullptr;
115  }
116 
117  void PluginFactoryBase::fillInfo(const PMakers& makers, PluginInfo& iInfo, std::vector<PluginInfo>& iReturn) const {
118  for (PMakers::const_iterator it = makers.begin(); it != makers.end(); ++it) {
119  while (nullptr == it->m_ptr.load(std::memory_order_acquire))
120  ;
121  iInfo.loadable_ = it->m_name;
122  iReturn.push_back(iInfo);
123  }
124  }
125 
126  void PluginFactoryBase::fillAvailable(std::vector<PluginInfo>& iReturn) const {
128  for (Plugins::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it) {
129  info.name_ = it->first;
130  fillInfo(it->second, info, iReturn);
131  }
132  }
133 
134  void PluginFactoryBase::checkProperLoadable(const std::string& iName, const std::string& iLoadedFrom) const {
135  //should check to see if this is from the proper loadable if it
136  // was not statically linked
138  if (iLoadedFrom != PluginManager::get()->loadableFor(category(), iName).string()) {
139  throw cms::Exception("WrongPluginLoaded")
140  << "The plugin '" << iName << "' should have been loaded from\n '"
141  << PluginManager::get()->loadableFor(category(), iName).string()
142  << "'\n but instead it was already loaded from\n '" << iLoadedFrom
143  << "'\n because some other plugin was loaded from the latter loadables.\n"
144  "To work around the problem the plugin '"
145  << iName << "' should only be defined in one of these loadables.";
146  }
147  }
148  }
149 
150  void PluginFactoryBase::registerPMaker(void* iPMaker, const std::string& iName) {
151  assert(nullptr != iPMaker);
152  PMakers newMakers;
153  newMakers.emplace_back(iPMaker, PluginManager::loadingFile());
154  if (not m_plugins.emplace(iName, std::move(newMakers)).second) {
155  //the item was already added
156  m_plugins[iName].push_back(PluginMakerInfo(iPMaker, PluginManager::loadingFile()));
157  }
158  newPlugin(iName);
159  }
160 
161  std::vector<PluginInfo> PluginFactoryBase::available() const {
162  std::vector<PluginInfo> returnValue;
163  returnValue.reserve(m_plugins.size());
164  fillAvailable(returnValue);
165  return returnValue;
166  }
167 
168  //
169  // const member functions
170  //
171 
172  //
173  // static member functions
174  //
175 } // namespace edmplugin
static const TGPicture * info(bool iBackgroundIsBlack)
const SharedLibrary * tryToLoad(const std::string &iCategory, const std::string &iPlugin)
void registerPMaker(void *iPMaker, const std::string &iName)
const std::filesystem::path & path() const
Definition: SharedLibrary.h:38
assert(be >=bs)
static const std::string & staticallyLinkedLoadingFileName()
if the value returned from loadingFile matches this string then the file is statically linked ...
tuple lib
Definition: mps_check.py:21
void fillAvailable(std::vector< PluginInfo > &iReturn) const
std::filesystem::path loadable_
Definition: PluginInfo.h:30
edm::signalslot::Signal< void(const std::string &, const PluginInfo &)> newPluginAdded_
signal containing plugin category, and plugin info for newly added plugin
void checkProperLoadable(const std::string &iName, const std::string &iLoadedFrom) const
def move
Definition: eostools.py:511
static const std::string & loadingFile()
file name of the shared object being loaded
Definition: PluginManager.h:89
void fillInfo(const PMakers &makers, PluginInfo &iInfo, std::vector< PluginInfo > &iReturn) const
void addFactory(const PluginFactoryBase *)
virtual const std::string & category() const =0
returns the name of the category to which this plugin factory belongs
void * findPMaker(const std::string &iName) const
tbb::concurrent_vector< PluginMakerInfo, edm::zero_allocator< PluginMakerInfo > > PMakers
const std::filesystem::path & loadableFor(const std::string &iCategory, const std::string &iPlugin)
std::string name_
Definition: PluginInfo.h:29
virtual std::vector< PluginInfo > available() const
return info about all plugins which are already available in the program
const SharedLibrary & load(const std::string &iCategory, const std::string &iPlugin)
static PluginManager * get()
void * tryToFindPMaker(const std::string &iName) const
static PluginFactoryManager * get()
void newPlugin(const std::string &iName)