CMS 3D CMS Logo

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 
15 // user include files
20 
21 namespace edmplugin {
22  //
23  // constants, enums and typedefs
24  //
25 
26  //
27  // static data member definitions
28  //
29 
30  //
31  // constructors and destructor
32  //
33 
34  // PluginFactoryBase::PluginFactoryBase(const PluginFactoryBase& rhs)
35  // {
36  // // do actual copying here;
37  // }
38 
40 
41  //
42  // assignment operators
43  //
44  // const PluginFactoryBase& PluginFactoryBase::operator=(const PluginFactoryBase& rhs)
45  // {
46  // //An exception safe implementation is
47  // PluginFactoryBase temp(rhs);
48  // swap(rhs);
49  //
50  // return *this;
51  // }
52 
53  //
54  // member functions
55  //
57 
61  info.name_ = iName;
62  newPluginAdded_(category(), info);
63  }
64 
65  void* PluginFactoryBase::findPMaker(const std::string& iName) const {
66  //do we already have it?
67  Plugins::const_iterator itFound = m_plugins.find(iName);
68  if (itFound == m_plugins.end()) {
69  std::string lib = PluginManager::get()->load(this->category(), iName).path().string();
70  itFound = m_plugins.find(iName);
71  if (itFound == m_plugins.end()) {
72  throw cms::Exception("PluginCacheError")
73  << "The plugin '" << iName << "' should have been in loadable\n '" << lib
74  << "'\n but was not there. This means the plugin cache is incorrect. Please run 'EdmPluginRefresh " << lib
75  << "'";
76  }
77  } else {
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  checkProperLoadable(iName, value.m_name);
83  }
84  return itFound->second.front().m_ptr.load(std::memory_order_acquire);
85  }
86 
87  void* PluginFactoryBase::tryToFindPMaker(const std::string& iName) const {
88  //do we already have it?
89  Plugins::const_iterator itFound = m_plugins.find(iName);
90  if (itFound == m_plugins.end()) {
91  const SharedLibrary* slib = PluginManager::get()->tryToLoad(this->category(), iName);
92  if (nullptr != slib) {
93  std::string lib = slib->path().string();
94  itFound = m_plugins.find(iName);
95  if (itFound == m_plugins.end()) {
96  throw cms::Exception("PluginCacheError")
97  << "The plugin '" << iName << "' should have been in loadable\n '" << lib
98  << "'\n but was not there. This means the plugin cache is incorrect. Please run 'EdmPluginRefresh "
99  << lib << "'";
100  }
101  }
102  } else {
103  //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
104  auto const& value = itFound->second.front();
105  while (value.m_ptr.load(std::memory_order_acquire) == nullptr) {
106  }
107  checkProperLoadable(iName, value.m_name);
108  }
109  return itFound != m_plugins.end() ? itFound->second.front().m_ptr.load(std::memory_order_acquire) : nullptr;
110  }
111 
112  void PluginFactoryBase::fillInfo(const PMakers& makers, PluginInfo& iInfo, std::vector<PluginInfo>& iReturn) const {
113  for (PMakers::const_iterator it = makers.begin(); it != makers.end(); ++it) {
114  while (nullptr == it->m_ptr.load(std::memory_order_acquire))
115  ;
116  iInfo.loadable_ = it->m_name;
117  iReturn.push_back(iInfo);
118  }
119  }
120 
121  void PluginFactoryBase::fillAvailable(std::vector<PluginInfo>& iReturn) const {
123  for (Plugins::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it) {
124  info.name_ = it->first;
125  fillInfo(it->second, info, iReturn);
126  }
127  }
128 
129  void PluginFactoryBase::checkProperLoadable(const std::string& iName, const std::string& iLoadedFrom) const {
130  //should check to see if this is from the proper loadable if it
131  // was not statically linked
133  if (iLoadedFrom != PluginManager::get()->loadableFor(category(), iName).string()) {
134  throw cms::Exception("WrongPluginLoaded")
135  << "The plugin '" << iName << "' should have been loaded from\n '"
136  << PluginManager::get()->loadableFor(category(), iName).string()
137  << "'\n but instead it was already loaded from\n '" << iLoadedFrom
138  << "'\n because some other plugin was loaded from the latter loadables.\n"
139  "To work around the problem the plugin '"
140  << iName << "' should only be defined in one of these loadables.";
141  }
142  }
143  }
144 
145  void PluginFactoryBase::registerPMaker(void* iPMaker, const std::string& iName) {
146  assert(nullptr != iPMaker);
147  m_plugins[iName].push_back(PluginMakerInfo(iPMaker, PluginManager::loadingFile()));
148  newPlugin(iName);
149  }
150 
151  std::vector<PluginInfo> PluginFactoryBase::available() const {
152  std::vector<PluginInfo> returnValue;
153  returnValue.reserve(m_plugins.size());
154  fillAvailable(returnValue);
155  return returnValue;
156  }
157 
158  //
159  // const member functions
160  //
161 
162  //
163  // static member functions
164  //
165 } // namespace edmplugin
static const TGPicture * info(bool iBackgroundIsBlack)
const boost::filesystem::path & loadableFor(const std::string &iCategory, const std::string &iPlugin)
const SharedLibrary * tryToLoad(const std::string &iCategory, const std::string &iPlugin)
void registerPMaker(void *iPMaker, const std::string &iName)
static const std::string & staticallyLinkedLoadingFileName()
if the value returned from loadingFile matches this string then the file is statically linked ...
virtual const std::string & category() const =0
returns the name of the category to which this plugin factory belongs
void fillAvailable(std::vector< PluginInfo > &iReturn) const
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
static const std::string & loadingFile()
file name of the shared object being loaded
Definition: PluginManager.h:90
Definition: value.py:1
tbb::concurrent_vector< PluginMakerInfo > PMakers
void fillInfo(const PMakers &makers, PluginInfo &iInfo, std::vector< PluginInfo > &iReturn) const
void addFactory(const PluginFactoryBase *)
void * findPMaker(const std::string &iName) const
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
boost::filesystem::path loadable_
Definition: PluginInfo.h:30
const SharedLibrary & load(const std::string &iCategory, const std::string &iPlugin)
const boost::filesystem::path & path() const
Definition: SharedLibrary.h:36
static PluginManager * get()
void * tryToFindPMaker(const std::string &iName) const
static PluginFactoryManager * get()
void newPlugin(const std::string &iName)