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 
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 
44 //
45 // assignment operators
46 //
47 // const PluginFactoryBase& PluginFactoryBase::operator=(const PluginFactoryBase& rhs)
48 // {
49 // //An exception safe implementation is
50 // PluginFactoryBase temp(rhs);
51 // swap(rhs);
52 //
53 // return *this;
54 // }
55 
56 //
57 // member functions
58 //
59 void
61 {
63 }
64 
65 void
67 {
70  info.name_=iName;
71  newPluginAdded_(category(),info);
72 }
73 
74 
75 void*
77 {
78  //do we already have it?
79  Plugins::const_iterator itFound = m_plugins.find(iName);
80  if(itFound == m_plugins.end()) {
81  std::string lib = PluginManager::get()->load(this->category(),iName).path().string();
82  itFound = m_plugins.find(iName);
83  if(itFound == m_plugins.end()) {
84  throw cms::Exception("PluginCacheError")<<"The plugin '"<<iName<<"' should have been in loadable\n '"
85  <<lib<<"'\n but was not there. This means the plugin cache is incorrect. Please run 'EdmPluginRefresh "<<lib<<"'";
86  }
87  } else {
88  //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
89  auto const& value= itFound->second.front();
90  while(value.m_ptr.load(std::memory_order_acquire)==nullptr) {}
91  checkProperLoadable(iName,value.m_name);
92  }
93  return itFound->second.front().m_ptr.load(std::memory_order_acquire);
94 }
95 
96 
97 void*
99 {
100  //do we already have it?
101  Plugins::const_iterator itFound = m_plugins.find(iName);
102  if(itFound == m_plugins.end()) {
103  const SharedLibrary* slib = PluginManager::get()->tryToLoad(this->category(),iName);
104  if(nullptr!=slib) {
105  std::string lib = slib->path().string();
106  itFound = m_plugins.find(iName);
107  if(itFound == m_plugins.end()) {
108  throw cms::Exception("PluginCacheError")<<"The plugin '"<<iName<<"' should have been in loadable\n '"
109  <<lib<<"'\n but was not there. This means the plugin cache is incorrect. Please run 'EdmPluginRefresh "<<lib<<"'";
110  }
111  }
112  } else {
113  //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
114  auto const& value= itFound->second.front();
115  while(value.m_ptr.load(std::memory_order_acquire)==nullptr) {}
116  checkProperLoadable(iName,value.m_name);
117  }
118  return itFound != m_plugins.end()? itFound->second.front().m_ptr.load(std::memory_order_acquire) : nullptr;
119 }
120 
121 void
123  PluginInfo& iInfo,
124  std::vector<PluginInfo>& iReturn ) const {
125  for(PMakers::const_iterator it = makers.begin();
126  it != makers.end();
127  ++it) {
128  while (nullptr ==it->m_ptr.load(std::memory_order_acquire)) ;
129  iInfo.loadable_ = it->m_name;
130  iReturn.push_back(iInfo);
131  }
132 }
133 
134 void
135 PluginFactoryBase::fillAvailable(std::vector<PluginInfo>& iReturn) const {
137  for( Plugins::const_iterator it = m_plugins.begin();
138  it != m_plugins.end();
139  ++it) {
140  info.name_ = it->first;
141  fillInfo(it->second,
142  info, iReturn);
143  }
144 }
145 
146 void
147 PluginFactoryBase::checkProperLoadable(const std::string& iName, const std::string& iLoadedFrom) const
148 {
149  //should check to see if this is from the proper loadable if it
150  // was not statically linked
151  if (iLoadedFrom != PluginManager::staticallyLinkedLoadingFileName() &&
153  if( iLoadedFrom != PluginManager::get()->loadableFor(category(),iName).string() ) {
154  throw cms::Exception("WrongPluginLoaded")<<"The plugin '"<<iName<<"' should have been loaded from\n '"
155  <<PluginManager::get()->loadableFor(category(),iName).string()
156  <<"'\n but instead it was already loaded from\n '"
157  <<iLoadedFrom<<"'\n because some other plugin was loaded from the latter loadables.\n"
158  "To work around the problem the plugin '"<<iName<<"' should only be defined in one of these loadables.";
159  }
160  }
161 }
162 
163 
164 void
165 PluginFactoryBase::registerPMaker(void* iPMaker, const std::string& iName) {
166  assert(nullptr!= iPMaker);
167  m_plugins[iName].push_back(PluginMakerInfo(iPMaker,PluginManager::loadingFile()));
168  newPlugin(iName);
169 }
170 
171 std::vector<PluginInfo>
173  std::vector<PluginInfo> returnValue;
174  returnValue.reserve(m_plugins.size());
175  fillAvailable(returnValue);
176  return returnValue;
177 }
178 
179 //
180 // const member functions
181 //
182 
183 //
184 // static member functions
185 //
186 }
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:92
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:38
static PluginManager * get()
void * tryToFindPMaker(const std::string &iName) const
static PluginFactoryManager * get()
void newPlugin(const std::string &iName)