CMS 3D CMS Logo

List of all members | Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Private Member Functions | Static Private Member Functions | Private Attributes | Friends
edmplugin::PluginManager Class Reference

#include <PluginManager.h>

Classes

class  Config
 

Public Types

typedef std::map< std::string, InfosCategoryToInfos
 
typedef std::vector< PluginInfoInfos
 
typedef std::vector< std::string > SearchPath
 

Public Member Functions

const CategoryToInfoscategoryToInfos () const
 
const SharedLibraryload (const std::string &iCategory, const std::string &iPlugin)
 
const boost::filesystem::path & loadableFor (const std::string &iCategory, const std::string &iPlugin)
 
const SharedLibrarytryToLoad (const std::string &iCategory, const std::string &iPlugin)
 
 ~PluginManager ()
 

Static Public Member Functions

static PluginManagerconfigure (const Config &)
 
static PluginManagerget ()
 
static bool isAvailable ()
 
static const std::string & loadingFile ()
 file name of the shared object being loaded More...
 
static const std::string & staticallyLinkedLoadingFileName ()
 if the value returned from loadingFile matches this string then the file is statically linked More...
 

Public Attributes

edm::signalslot::Signal< void(const std::string &, const std::string &)> askedToLoadCategoryWithPlugin_
 
edm::signalslot::Signal< void(const boost::filesystem::path &)> goingToLoad_
 
edm::signalslot::Signal< void(const SharedLibrary &)> justLoaded_
 

Private Member Functions

const boost::filesystem::path & loadableFor_ (const std::string &iCategory, const std::string &iPlugin, bool &ioThrowIfFailElseSucceedStatus)
 
void newFactory (const PluginFactoryBase *)
 
const PluginManageroperator= (const PluginManager &)=delete
 
std::recursive_mutex & pluginLoadMutex ()
 
 PluginManager (const Config &)
 
 PluginManager (const PluginManager &)=delete
 

Static Private Member Functions

static std::string & loadingLibraryNamed_ ()
 
static PluginManager *& singleton ()
 

Private Attributes

CategoryToInfos categoryToInfos_
 
tbb::concurrent_unordered_map< boost::filesystem::path, std::shared_ptr< SharedLibrary >, PluginManagerPathHasherloadables_
 
std::recursive_mutex pluginLoadMutex_
 
SearchPath searchPath_
 

Friends

class DummyFriend
 

Detailed Description

Definition at line 48 of file PluginManager.h.

Member Typedef Documentation

typedef std::map<std::string, Infos > edmplugin::PluginManager::CategoryToInfos

Definition at line 54 of file PluginManager.h.

Definition at line 53 of file PluginManager.h.

typedef std::vector<std::string> edmplugin::PluginManager::SearchPath

Definition at line 52 of file PluginManager.h.

Constructor & Destructor Documentation

PluginManager::~PluginManager ( )

Definition at line 128 of file PluginManager.cc.

129 {
130 }
PluginManager::PluginManager ( const Config iConfig)
private

Definition at line 60 of file PluginManager.cc.

References edmplugin::PluginFactoryManager::begin(), edmplugin::standard::cachefileName(), categoryToInfos_, dir, MillePedeFileConverter_cfg::e, edmplugin::PluginFactoryManager::end(), Exception, edmplugin::PluginFactoryManager::get(), mps_fire::i, loadingLibraryNamed_(), edmplugin::PluginManager::Config::mustHaveCache(), newFactory(), edmplugin::PluginFactoryManager::newFactory_, callgraph::path, edmplugin::standard::poisonedCachefileName(), edmplugin::readCacheFile(), and searchPath_.

Referenced by configure().

60  :
61  searchPath_( iConfig.searchPath() )
62 {
63  using std::placeholders::_1;
65  // This is the filename of a file which contains plugins which exist in the
66  // base release and which should exists in the local area, otherwise they
67  // were removed and we want to catch their usage.
68  const boost::filesystem::path& kPoisonedCacheFile(standard::poisonedCachefileName());
69  //NOTE: This may not be needed :/
71  pfm->newFactory_.connect(std::bind(std::mem_fn(&PluginManager::newFactory),this,_1));
72 
73  // When building a single big executable the plugins are already registered in the
74  // PluginFactoryManager, we therefore only need to populate the categoryToInfos_ map
75  // with the relevant information.
76  for (PluginFactoryManager::const_iterator i = pfm->begin(), e = pfm->end(); i != e; ++i)
77  {
78  categoryToInfos_[(*i)->category()] = (*i)->available();
79  }
80 
81  //read in the files
82  //Since we are looping in the 'precidence' order then the lists in categoryToInfos_ will also be
83  // in that order
84  bool foundAtLeastOneCacheFile = false;
85  std::set<std::string> alreadySeen;
86  for(SearchPath::const_iterator itPath=searchPath_.begin(), itEnd = searchPath_.end();
87  itPath != itEnd;
88  ++itPath) {
89  //take care of the case where the same path is passed in multiple times
90  if (alreadySeen.find(*itPath) != alreadySeen.end() ) {
91  continue;
92  }
93  alreadySeen.insert(*itPath);
95  if( exists( dir) ) {
96  if(not is_directory(dir) ) {
97  throw cms::Exception("PluginManagerBadPath") <<"The path '"<<dir.string()<<"' for the PluginManager is not a directory";
98  }
99  boost::filesystem::path cacheFile = dir/kCacheFile;
100 
101  if (readCacheFile(cacheFile, dir, categoryToInfos_))
102  {
103  foundAtLeastOneCacheFile=true;
104  }
105 
106  // We do not check for return code since we do not want to consider a
107  // poison cache file as a valid cache file having been found.
108  boost::filesystem::path poisonedCacheFile = dir/kPoisonedCacheFile;
109  readCacheFile(poisonedCacheFile, dir/"poisoned", categoryToInfos_);
110  }
111  }
112  if(not foundAtLeastOneCacheFile and iConfig.mustHaveCache()) {
113  auto ex = cms::Exception("PluginManagerNoCacheFile")<<"No cache files named '"<<standard::cachefileName()<<"' were found in the directories \n";
114  for( auto const& seen : alreadySeen) {
115  ex <<" '"<<seen<<"'\n";
116  }
117  throw ex;
118  }
119  //Since this should not be called until after 'main' has started, we can set the value
120  loadingLibraryNamed_()="<loaded by another plugin system>";
121 }
CategoryToInfos categoryToInfos_
const boost::filesystem::path & cachefileName()
Definition: standard.cc:47
const boost::filesystem::path & poisonedCachefileName()
Definition: standard.cc:52
static bool readCacheFile(const boost::filesystem::path &cacheFile, const boost::filesystem::path &dir, PluginManager::CategoryToInfos &categoryToInfos)
dbl *** dir
Definition: mlp_gen.cc:35
static std::string & loadingLibraryNamed_()
std::vector< const PluginFactoryBase * >::const_iterator const_iterator
void newFactory(const PluginFactoryBase *)
static PluginFactoryManager * get()
edmplugin::PluginManager::PluginManager ( const PluginManager )
privatedelete

Member Function Documentation

const CategoryToInfos& edmplugin::PluginManager::categoryToInfos ( ) const
inline

The container is ordered by category, then plugin name and then by precidence order of the plugin files. Therefore the first match on category and plugin name will be the proper file to load

Definition at line 90 of file PluginManager.h.

References AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by PrintLoadingPlugins::askedToLoad(), FWDetailViewManager::findViewersFor(), FWEveViewManager::FWEveViewManager(), FWItemAccessorFactory::hasAccessor(), edm::service::LoadAllDictionaries::LoadAllDictionaries(), and main().

90  {
91  return categoryToInfos_;
92  }
CategoryToInfos categoryToInfos_
PluginManager & PluginManager::configure ( const Config iConfig)
static

Definition at line 335 of file PluginManager.cc.

References Exception, PluginManager(), alignCSCRings::s, edmplugin::PluginManager::Config::searchPath(), singleton(), and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by FWLiteEnabler::enable(), StorageFactory::getMaker(), main(), edm::ProblemTracker::ProblemTracker(), cond::Utilities::run(), and edm::PluginDescription< T >::writeCfi_().

336 {
337  PluginManager*& s = singleton();
338  if( nullptr != s ){
339  throw cms::Exception("PluginManagerReconfigured");
340  }
341 
342  const Config& realConfig = iConfig;
343  if (realConfig.searchPath().empty() ) {
344  throw cms::Exception("PluginManagerEmptySearchPath");
345  }
346  s = new PluginManager (realConfig);
347  return *s;
348 }
static PluginManager *& singleton()
Definition: Config.py:1
PluginManager(const Config &)
PluginManager * PluginManager::get ( )
static
bool PluginManager::isAvailable ( )
static

Definition at line 374 of file PluginManager.cc.

References singleton().

Referenced by edmplugin::PluginFactoryBase::checkProperLoadable(), StorageFactory::getMaker(), and edm::ProblemTracker::ProblemTracker().

375 {
376  return nullptr != singleton();
377 }
static PluginManager *& singleton()
const SharedLibrary & PluginManager::load ( const std::string &  iCategory,
const std::string &  iPlugin 
)

Definition at line 248 of file PluginManager.cc.

References askedToLoadCategoryWithPlugin_, goingToLoad_, justLoaded_, loadableFor(), loadables_, loadingLibraryNamed_(), AlCaHLTBitMon_ParallelJobs::p, callgraph::path, pluginLoadMutex(), and alignCSCRings::s.

Referenced by edmplugin::PluginFactoryBase::findPMaker(), and edmplugin::PluginCapabilities::load().

250 {
251  askedToLoadCategoryWithPlugin_(iCategory,iPlugin);
252  const boost::filesystem::path& p = loadableFor(iCategory,iPlugin);
253 
254  //have we already loaded this?
255  auto itLoaded = loadables_.find(p);
256  if(itLoaded == loadables_.end()) {
257  //Need to make sure we only have on SharedLibrary loading at a time
258  std::lock_guard<std::recursive_mutex> guard(pluginLoadMutex());
259  //Another thread may have gotten this while we were waiting on the mutex
260  itLoaded = loadables_.find(p);
261  if(itLoaded == loadables_.end()){
262  //try to make one
263  goingToLoad_(p);
264  Sentry s(loadingLibraryNamed_(), p.string());
265  //boost::filesystem::path native(p.string());
266  std::shared_ptr<SharedLibrary> ptr;
267  {
268  //TEMPORARY: to avoid possible deadlocks from ROOT, we must
269  // take the lock ourselves
270  R__LOCKGUARD2(gInterpreterMutex);
271  ptr.reset( new SharedLibrary(p) );
272  }
273  loadables_[p]=ptr;
274  justLoaded_(*ptr);
275  return *ptr;
276  }
277  }
278  return *(itLoaded->second);
279 }
tbb::concurrent_unordered_map< boost::filesystem::path, std::shared_ptr< SharedLibrary >, PluginManagerPathHasher > loadables_
const boost::filesystem::path & loadableFor(const std::string &iCategory, const std::string &iPlugin)
edm::signalslot::Signal< void(const SharedLibrary &)> justLoaded_
edm::signalslot::Signal< void(const std::string &, const std::string &)> askedToLoadCategoryWithPlugin_
std::recursive_mutex & pluginLoadMutex()
edm::signalslot::Signal< void(const boost::filesystem::path &)> goingToLoad_
static std::string & loadingLibraryNamed_()
const boost::filesystem::path & PluginManager::loadableFor ( const std::string &  iCategory,
const std::string &  iPlugin 
)

Definition at line 164 of file PluginManager.cc.

References loadableFor_(), and callgraph::path.

Referenced by edmplugin::PluginFactoryBase::checkProperLoadable(), and load().

166 {
167  bool throwIfFail = true;
168  return loadableFor_(iCategory, iPlugin,throwIfFail);
169 }
const boost::filesystem::path & loadableFor_(const std::string &iCategory, const std::string &iPlugin, bool &ioThrowIfFailElseSucceedStatus)
const boost::filesystem::path & PluginManager::loadableFor_ ( const std::string &  iCategory,
const std::string &  iPlugin,
bool &  ioThrowIfFailElseSucceedStatus 
)
private

Definition at line 172 of file PluginManager.cc.

References categoryToInfos_, Exception, mps_fire::i, edmplugin::PluginInfo::name_, oldPath_, callgraph::path, path_, and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by loadableFor(), and tryToLoad().

175 {
176  const bool throwIfFail = ioThrowIfFailElseSucceedStatus;
177  ioThrowIfFailElseSucceedStatus = true;
178  CategoryToInfos::iterator itFound = categoryToInfos_.find(iCategory);
179  if(itFound == categoryToInfos_.end()) {
180  if(throwIfFail) {
181  throw cms::Exception("PluginNotFound")<<"Unable to find plugin '"<<iPlugin<<
182  "' because the category '"<<iCategory<<"' has no known plugins";
183  } else {
184  ioThrowIfFailElseSucceedStatus = false;
185  static const boost::filesystem::path s_path;
186  return s_path;
187  }
188  }
189 
190  PluginInfo i;
191  i.name_ = iPlugin;
192  typedef std::vector<PluginInfo>::iterator PIItr;
193  std::pair<PIItr,PIItr> range = std::equal_range(itFound->second.begin(),
194  itFound->second.end(),
195  i,
196  PICompare() );
197 
198  if(range.first == range.second) {
199  if(throwIfFail) {
200  throw cms::Exception("PluginNotFound")<<"Unable to find plugin '"<<iPlugin
201  <<"' in category '"<<iCategory<<"'. Please check spelling of name.";
202  } else {
203  ioThrowIfFailElseSucceedStatus = false;
204  static const boost::filesystem::path s_path;
205  return s_path;
206  }
207  }
208 
209  if(range.second - range.first > 1 ) {
210  //see if the come from the same directory
211  if(range.first->loadable_.branch_path() == (range.first+1)->loadable_.branch_path()) {
212  //std::cout<<range.first->name_ <<" " <<(range.first+1)->name_<<std::endl;
213  throw cms::Exception("MultiplePlugins")<<"The plugin '"<<iPlugin<<"' is found in multiple files \n"
214  " '"<<range.first->loadable_.leaf()<<"'\n '"
215  <<(range.first+1)->loadable_.leaf()<<"'\n"
216  "in directory '"<<range.first->loadable_.branch_path().string()<<"'.\n"
217  "The code must be changed so the plugin only appears in one plugin file. "
218  "You will need to remove the macro which registers the plugin so it only appears in"
219  " one of these files.\n"
220  " If none of these files register such a plugin, "
221  "then the problem originates in a library to which all these files link.\n"
222  "The plugin registration must be removed from that library since plugins are not allowed in regular libraries.";
223  }
224  }
225 
226  return range.first->loadable_;
227 }
CategoryToInfos categoryToInfos_
static const std::string& edmplugin::PluginManager::loadingFile ( )
inlinestatic

file name of the shared object being loaded

Definition at line 100 of file PluginManager.h.

References AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by edmplugin::PluginFactoryBase::newPlugin(), and edmplugin::PluginFactoryBase::registerPMaker().

100  {
101  return loadingLibraryNamed_();}
static std::string & loadingLibraryNamed_()
std::string & PluginManager::loadingLibraryNamed_ ( )
staticprivate

Definition at line 359 of file PluginManager.cc.

References CMS_THREAD_SAFE, staticallyLinkedLoadingFileName(), and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by load(), PluginManager(), and tryToLoad().

360 {
361  //NOTE: pluginLoadMutex() indirectly guards this since this value
362  // is only accessible via the Sentry call which us guarded by the mutex
364  return s_name;
365 }
static const std::string & staticallyLinkedLoadingFileName()
if the value returned from loadingFile matches this string then the file is statically linked ...
#define CMS_THREAD_SAFE
void PluginManager::newFactory ( const PluginFactoryBase )
private

Definition at line 148 of file PluginManager.cc.

References edmplugin::PluginInfo::name_, and callgraph::path.

Referenced by PluginManager().

149 {
150 }
const PluginManager& edmplugin::PluginManager::operator= ( const PluginManager )
privatedelete
std::recursive_mutex& edmplugin::PluginManager::pluginLoadMutex ( )
inlineprivate

Definition at line 126 of file PluginManager.h.

References callgraph::path, and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by load(), and tryToLoad().

126 {return pluginLoadMutex_;}
std::recursive_mutex pluginLoadMutex_
PluginManager *& PluginManager::singleton ( )
staticprivate

Definition at line 367 of file PluginManager.cc.

References CMS_THREAD_SAFE.

Referenced by configure(), get(), and isAvailable().

368 {
369  CMS_THREAD_SAFE static PluginManager* s_singleton=nullptr;
370  return s_singleton;
371 }
#define CMS_THREAD_SAFE
const std::string & PluginManager::staticallyLinkedLoadingFileName ( )
static

if the value returned from loadingFile matches this string then the file is statically linked

Definition at line 352 of file PluginManager.cc.

References AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by edmplugin::PluginFactoryBase::checkProperLoadable(), and loadingLibraryNamed_().

353 {
354  static const std::string s_name("static");
355  return s_name;
356 }
const SharedLibrary * PluginManager::tryToLoad ( const std::string &  iCategory,
const std::string &  iPlugin 
)

Definition at line 282 of file PluginManager.cc.

References askedToLoadCategoryWithPlugin_, goingToLoad_, justLoaded_, loadableFor_(), loadables_, loadingLibraryNamed_(), AlCaHLTBitMon_ParallelJobs::p, callgraph::path, pluginLoadMutex(), and alignCSCRings::s.

Referenced by edmplugin::PluginFactoryBase::tryToFindPMaker(), and edmplugin::PluginCapabilities::tryToLoad().

284 {
285  askedToLoadCategoryWithPlugin_(iCategory,iPlugin);
286  bool ioThrowIfFailElseSucceedStatus = false;
287  const boost::filesystem::path& p = loadableFor_(iCategory,iPlugin, ioThrowIfFailElseSucceedStatus);
288 
289  if( not ioThrowIfFailElseSucceedStatus ) {
290  return nullptr;
291  }
292 
293 
294  //have we already loaded this?
295  auto itLoaded = loadables_.find(p);
296  if(itLoaded == loadables_.end()) {
297  //Need to make sure we only have on SharedLibrary loading at a time
298  std::lock_guard<std::recursive_mutex> guard(pluginLoadMutex());
299  //Another thread may have gotten this while we were waiting on the mutex
300  itLoaded = loadables_.find(p);
301  if(itLoaded == loadables_.end()){
302  //try to make one
303  goingToLoad_(p);
304  Sentry s(loadingLibraryNamed_(), p.string());
305  //boost::filesystem::path native(p.string());
306  std::shared_ptr<SharedLibrary> ptr;
307  {
308  //TEMPORARY: to avoid possible deadlocks from ROOT, we must
309  // take the lock ourselves
310  R__LOCKGUARD(gInterpreterMutex);
311  ptr.reset( new SharedLibrary(p) );
312  }
313  loadables_[p]=ptr;
314  justLoaded_(*ptr);
315  return ptr.get();
316  }
317  }
318  return (itLoaded->second).get();
319 }
tbb::concurrent_unordered_map< boost::filesystem::path, std::shared_ptr< SharedLibrary >, PluginManagerPathHasher > loadables_
const boost::filesystem::path & loadableFor_(const std::string &iCategory, const std::string &iPlugin, bool &ioThrowIfFailElseSucceedStatus)
edm::signalslot::Signal< void(const SharedLibrary &)> justLoaded_
edm::signalslot::Signal< void(const std::string &, const std::string &)> askedToLoadCategoryWithPlugin_
std::recursive_mutex & pluginLoadMutex()
edm::signalslot::Signal< void(const boost::filesystem::path &)> goingToLoad_
static std::string & loadingLibraryNamed_()

Friends And Related Function Documentation

friend class DummyFriend
friend

Definition at line 50 of file PluginManager.h.

Member Data Documentation

edm::signalslot::Signal<void(const std::string&,const std::string&)> edmplugin::PluginManager::askedToLoadCategoryWithPlugin_

Definition at line 115 of file PluginManager.h.

Referenced by load(), PrintLoadingPlugins::PrintLoadingPlugins(), and tryToLoad().

CategoryToInfos edmplugin::PluginManager::categoryToInfos_
private

Definition at line 135 of file PluginManager.h.

Referenced by loadableFor_(), and PluginManager().

edm::signalslot::Signal<void(const boost::filesystem::path&)> edmplugin::PluginManager::goingToLoad_

Definition at line 113 of file PluginManager.h.

Referenced by load(), PrintLoadingPlugins::PrintLoadingPlugins(), and tryToLoad().

edm::signalslot::Signal<void(const SharedLibrary&)> edmplugin::PluginManager::justLoaded_

Definition at line 114 of file PluginManager.h.

Referenced by load(), and tryToLoad().

tbb::concurrent_unordered_map<boost::filesystem::path, std::shared_ptr<SharedLibrary>, PluginManagerPathHasher > edmplugin::PluginManager::loadables_
private

Definition at line 133 of file PluginManager.h.

Referenced by load(), and tryToLoad().

std::recursive_mutex edmplugin::PluginManager::pluginLoadMutex_
private

Definition at line 136 of file PluginManager.h.

SearchPath edmplugin::PluginManager::searchPath_
private

Definition at line 132 of file PluginManager.h.

Referenced by PluginManager().