CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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,
Infos
CategoryToInfos
 
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 &)
 
std::recursive_mutex & pluginLoadMutex ()
 
 PluginManager (const Config &)
 
 PluginManager (const PluginManager &)
 

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 >
, PluginManagerPathHasher
loadables_
 
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 109 of file PluginManager.cc.

110 {
111 }
PluginManager::PluginManager ( const Config iConfig)
private

Definition at line 45 of file PluginManager.cc.

References edmplugin::PluginFactoryManager::begin(), edmplugin::standard::cachefileName(), categoryToInfos_, dir, alignCSCRings::e, edmplugin::PluginFactoryManager::end(), edm::hlt::Exception, mergeVDriftHistosByStation::file, edmplugin::PluginFactoryManager::get(), i, loadingLibraryNamed_(), newFactory(), edmplugin::PluginFactoryManager::newFactory_, cmsHarvester::path, edmplugin::CacheParser::read(), and searchPath_.

Referenced by configure().

45  :
46  searchPath_( iConfig.searchPath() )
47 {
48  using std::placeholders::_1;
50  //NOTE: This may not be needed :/
52  pfm->newFactory_.connect(std::bind(std::mem_fn(&PluginManager::newFactory),this,_1));
53 
54  // When building a single big executable the plugins are already registered in the
55  // PluginFactoryManager, we therefore only need to populate the categoryToInfos_ map
56  // with the relevant information.
57  for (PluginFactoryManager::const_iterator i = pfm->begin(), e = pfm->end(); i != e; ++i)
58  {
59  categoryToInfos_[(*i)->category()] = (*i)->available();
60  }
61 
62  //read in the files
63  //Since we are looping in the 'precidence' order then the lists in categoryToInfos_ will also be
64  // in that order
65  bool foundAtLeastOneCacheFile = false;
66  std::set<std::string> alreadySeen;
67  for(SearchPath::const_iterator itPath=searchPath_.begin(), itEnd = searchPath_.end();
68  itPath != itEnd;
69  ++itPath) {
70  //take care of the case where the same path is passed in multiple times
71  if (alreadySeen.find(*itPath) != alreadySeen.end() ) {
72  continue;
73  }
74  alreadySeen.insert(*itPath);
76  if( exists( dir) ) {
77  if(not is_directory(dir) ) {
78  throw cms::Exception("PluginManagerBadPath") <<"The path '"<<dir.string()<<"' for the PluginManager is not a directory";
79  }
80  boost::filesystem::path cacheFile = dir/kCacheFile;
81 
82  if(exists(cacheFile) ) {
83  std::ifstream file(cacheFile.string().c_str());
84  if(not file) {
85  throw cms::Exception("PluginMangerCacheProblem")<<"Unable to open the cache file '"<<cacheFile.string()
86  <<"'. Please check permissions on file";
87  }
88  foundAtLeastOneCacheFile=true;
90  }
91  }
92  }
93  if(not foundAtLeastOneCacheFile) {
94  auto ex = cms::Exception("PluginManagerNoCacheFile")<<"No cache files named '"<<standard::cachefileName()<<"' were found in the directories \n";
95  for( auto const& seen : alreadySeen) {
96  ex <<" '"<<seen<<"'\n";
97  }
98  throw ex;
99  }
100  //Since this should not be called until after 'main' has started, we can set the value
101  loadingLibraryNamed_()="<loaded by another plugin system>";
102 }
CategoryToInfos categoryToInfos_
int i
Definition: DBlmapReader.cc:9
const boost::filesystem::path & cachefileName()
Definition: standard.cc:47
tuple path
else: Piece not in the list, fine.
dbl *** dir
Definition: mlp_gen.cc:35
static std::string & loadingLibraryNamed_()
static void read(std::istream &, const boost::filesystem::path &iDirectory, CategoryToInfos &oOut)
Definition: CacheParser.cc:125
std::vector< const PluginFactoryBase * >::const_iterator const_iterator
void newFactory(const PluginFactoryBase *)
static PluginFactoryManager * get()
edmplugin::PluginManager::PluginManager ( const PluginManager )
private

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 82 of file PluginManager.h.

References categoryToInfos_.

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

82  {
83  return categoryToInfos_;
84  }
CategoryToInfos categoryToInfos_
PluginManager & PluginManager::configure ( const Config iConfig)
static

Definition at line 316 of file PluginManager.cc.

References edm::hlt::Exception, PluginManager(), alignCSCRings::s, edmplugin::PluginManager::Config::searchPath(), and singleton().

Referenced by AutoLibraryLoader::enable(), StorageFactory::getMaker(), HcalO2OManager::HcalO2OManager(), main(), edm::ProblemTracker::ProblemTracker(), cond::Utilities::run(), and cond::topinit().

317 {
318  PluginManager*& s = singleton();
319  if( 0 != s ){
320  throw cms::Exception("PluginManagerReconfigured");
321  }
322 
323  Config realConfig = iConfig;
324  if (realConfig.searchPath().empty() ) {
325  throw cms::Exception("PluginManagerEmptySearchPath");
326  }
327  s = new PluginManager (realConfig);
328  return *s;
329 }
static PluginManager *& singleton()
PluginManager(const Config &)
PluginManager * PluginManager::get ( void  )
static
bool PluginManager::isAvailable ( )
static

Definition at line 355 of file PluginManager.cc.

References singleton().

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

356 {
357  return 0 != singleton();
358 }
static PluginManager *& singleton()
const SharedLibrary & PluginManager::load ( const std::string &  iCategory,
const std::string &  iPlugin 
)

Definition at line 229 of file PluginManager.cc.

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

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

231 {
232  askedToLoadCategoryWithPlugin_(iCategory,iPlugin);
233  const boost::filesystem::path& p = loadableFor(iCategory,iPlugin);
234 
235  //have we already loaded this?
236  auto itLoaded = loadables_.find(p);
237  if(itLoaded == loadables_.end()) {
238  //Need to make sure we only have on SharedLibrary loading at a time
239  std::lock_guard<std::recursive_mutex> guard(pluginLoadMutex());
240  //Another thread may have gotten this while we were waiting on the mutex
241  itLoaded = loadables_.find(p);
242  if(itLoaded == loadables_.end()){
243  //try to make one
244  goingToLoad_(p);
245  Sentry s(loadingLibraryNamed_(), p.string());
246  //boost::filesystem::path native(p.string());
247  std::shared_ptr<SharedLibrary> ptr;
248  {
249  //TEMPORARY: to avoid possible deadlocks from ROOT, we must
250  // take the lock ourselves
251  R__LOCKGUARD2(gCINTMutex);
252  ptr.reset( new SharedLibrary(p) );
253  }
254  loadables_[p]=ptr;
255  justLoaded_(*ptr);
256  return *ptr;
257  }
258  }
259  return *(itLoaded->second);
260 }
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)
tuple path
else: Piece not in the list, fine.
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 145 of file PluginManager.cc.

References loadableFor_().

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

147 {
148  bool throwIfFail = true;
149  return loadableFor_(iCategory, iPlugin,throwIfFail);
150 }
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 153 of file PluginManager.cc.

References categoryToInfos_, edm::hlt::Exception, i, edmplugin::PluginInfo::name_, and cmsHarvester::path.

Referenced by loadableFor(), and tryToLoad().

156 {
157  const bool throwIfFail = ioThrowIfFailElseSucceedStatus;
158  ioThrowIfFailElseSucceedStatus = true;
159  CategoryToInfos::iterator itFound = categoryToInfos_.find(iCategory);
160  if(itFound == categoryToInfos_.end()) {
161  if(throwIfFail) {
162  throw cms::Exception("PluginNotFound")<<"Unable to find plugin '"<<iPlugin<<
163  "' because the category '"<<iCategory<<"' has no known plugins";
164  } else {
165  ioThrowIfFailElseSucceedStatus = false;
166  static const boost::filesystem::path s_path;
167  return s_path;
168  }
169  }
170 
171  PluginInfo i;
172  i.name_ = iPlugin;
173  typedef std::vector<PluginInfo>::iterator PIItr;
174  std::pair<PIItr,PIItr> range = std::equal_range(itFound->second.begin(),
175  itFound->second.end(),
176  i,
177  PICompare() );
178 
179  if(range.first == range.second) {
180  if(throwIfFail) {
181  throw cms::Exception("PluginNotFound")<<"Unable to find plugin '"<<iPlugin
182  <<"' in category '"<<iCategory<<"'. Please check spelling of name.";
183  } else {
184  ioThrowIfFailElseSucceedStatus = false;
185  static const boost::filesystem::path s_path;
186  return s_path;
187  }
188  }
189 
190  if(range.second - range.first > 1 ) {
191  //see if the come from the same directory
192  if(range.first->loadable_.branch_path() == (range.first+1)->loadable_.branch_path()) {
193  //std::cout<<range.first->name_ <<" " <<(range.first+1)->name_<<std::endl;
194  throw cms::Exception("MultiplePlugins")<<"The plugin '"<<iPlugin<<"' is found in multiple files \n"
195  " '"<<range.first->loadable_.leaf()<<"'\n '"
196  <<(range.first+1)->loadable_.leaf()<<"'\n"
197  "in directory '"<<range.first->loadable_.branch_path().string()<<"'.\n"
198  "The code must be changed so the plugin only appears in one plugin file. "
199  "You will need to remove the macro which registers the plugin so it only appears in"
200  " one of these files.\n"
201  " If none of these files register such a plugin, "
202  "then the problem originates in a library to which all these files link.\n"
203  "The plugin registration must be removed from that library since plugins are not allowed in regular libraries.";
204  }
205  }
206 
207  return range.first->loadable_;
208 }
CategoryToInfos categoryToInfos_
int i
Definition: DBlmapReader.cc:9
tuple path
else: Piece not in the list, fine.
static const std::string& edmplugin::PluginManager::loadingFile ( )
inlinestatic

file name of the shared object being loaded

Definition at line 92 of file PluginManager.h.

References loadingLibraryNamed_().

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

92  {
93  return loadingLibraryNamed_();}
static std::string & loadingLibraryNamed_()
std::string & PluginManager::loadingLibraryNamed_ ( )
staticprivate

Definition at line 340 of file PluginManager.cc.

References staticallyLinkedLoadingFileName(), and AlCaHLTBitMon_QueryRunRegistry::string.

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

341 {
342  //NOTE: pluginLoadMutex() indirectly guards this since this value
343  // is only accessible via the Sentry call which us guarded by the mutex
344  [[cms::thread_safe]] static std::string s_name(staticallyLinkedLoadingFileName());
345  return s_name;
346 }
static const std::string & staticallyLinkedLoadingFileName()
if the value returned from loadingFile matches this string then the file is statically linked ...
void PluginManager::newFactory ( const PluginFactoryBase )
private

Definition at line 129 of file PluginManager.cc.

Referenced by PluginManager().

130 {
131 }
const PluginManager& edmplugin::PluginManager::operator= ( const PluginManager )
private
std::recursive_mutex& edmplugin::PluginManager::pluginLoadMutex ( )
inlineprivate

Definition at line 118 of file PluginManager.h.

References pluginLoadMutex_.

Referenced by load(), and tryToLoad().

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

Definition at line 348 of file PluginManager.cc.

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

349 {
350  [[cms::thread_safe]] static PluginManager* s_singleton=0;
351  return s_singleton;
352 }
const std::string & PluginManager::staticallyLinkedLoadingFileName ( )
static

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

Definition at line 333 of file PluginManager.cc.

References AlCaHLTBitMon_QueryRunRegistry::string.

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

334 {
335  static const std::string s_name("static");
336  return s_name;
337 }
const SharedLibrary * PluginManager::tryToLoad ( const std::string &  iCategory,
const std::string &  iPlugin 
)

Definition at line 263 of file PluginManager.cc.

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

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

265 {
266  askedToLoadCategoryWithPlugin_(iCategory,iPlugin);
267  bool ioThrowIfFailElseSucceedStatus = false;
268  const boost::filesystem::path& p = loadableFor_(iCategory,iPlugin, ioThrowIfFailElseSucceedStatus);
269 
270  if( not ioThrowIfFailElseSucceedStatus ) {
271  return 0;
272  }
273 
274 
275  //have we already loaded this?
276  auto itLoaded = loadables_.find(p);
277  if(itLoaded == loadables_.end()) {
278  //Need to make sure we only have on SharedLibrary loading at a time
279  std::lock_guard<std::recursive_mutex> guard(pluginLoadMutex());
280  //Another thread may have gotten this while we were waiting on the mutex
281  itLoaded = loadables_.find(p);
282  if(itLoaded == loadables_.end()){
283  //try to make one
284  goingToLoad_(p);
285  Sentry s(loadingLibraryNamed_(), p.string());
286  //boost::filesystem::path native(p.string());
287  std::shared_ptr<SharedLibrary> ptr;
288  {
289  //TEMPORARY: to avoid possible deadlocks from ROOT, we must
290  // take the lock ourselves
291  R__LOCKGUARD(gCINTMutex);
292  ptr.reset( new SharedLibrary(p) );
293  }
294  loadables_[p]=ptr;
295  justLoaded_(*ptr);
296  return ptr.get();
297  }
298  }
299  return (itLoaded->second).get();
300 }
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)
tuple path
else: Piece not in the list, fine.
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 107 of file PluginManager.h.

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

CategoryToInfos edmplugin::PluginManager::categoryToInfos_
private

Definition at line 127 of file PluginManager.h.

Referenced by categoryToInfos(), loadableFor_(), and PluginManager().

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

Definition at line 105 of file PluginManager.h.

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

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

Definition at line 106 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 125 of file PluginManager.h.

Referenced by load(), and tryToLoad().

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

Definition at line 128 of file PluginManager.h.

Referenced by pluginLoadMutex().

SearchPath edmplugin::PluginManager::searchPath_
private

Definition at line 124 of file PluginManager.h.

Referenced by PluginManager().