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 std::filesystem::path & loadableFor (const std::string &iCategory, const std::string &iPlugin)
 
const PluginManageroperator= (const PluginManager &)=delete
 
 PluginManager (const PluginManager &)=delete
 
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 std::filesystem::path &)> goingToLoad_
 
edm::signalslot::Signal< void(const SharedLibrary &)> justLoaded_
 

Private Member Functions

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

Static Private Member Functions

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

Private Attributes

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

Friends

class DummyFriend
 

Detailed Description

Definition at line 45 of file PluginManager.h.

Member Typedef Documentation

◆ CategoryToInfos

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

Definition at line 51 of file PluginManager.h.

◆ Infos

Definition at line 50 of file PluginManager.h.

◆ SearchPath

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

Definition at line 49 of file PluginManager.h.

Constructor & Destructor Documentation

◆ PluginManager() [1/2]

edmplugin::PluginManager::PluginManager ( const PluginManager )
delete

Referenced by configure().

◆ ~PluginManager()

PluginManager::~PluginManager ( )

Definition at line 123 of file PluginManager.cc.

123 {}

◆ PluginManager() [2/2]

PluginManager::PluginManager ( const Config iConfig)
private

Definition at line 58 of file PluginManager.cc.

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

References edmplugin::PluginFactoryManager::begin(), edmplugin::standard::cachefileName(), categoryToInfos_, DeadROC_duringRun::dir, MillePedeFileConverter_cfg::e, edmplugin::PluginFactoryManager::end(), Exception, edmplugin::PluginFactoryManager::get(), mps_fire::i, loadingLibraryNamed_(), edmplugin::PluginManager::Config::mustHaveCache(), newFactory(), edmplugin::PluginFactoryManager::newFactory_, castor_dqm_sourceclient_file_cfg::path, edmplugin::standard::poisonedCachefileName(), edmplugin::readCacheFile(), searchPath_, and postprocess-scan-build::seen.

Member Function Documentation

◆ categoryToInfos()

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.

82 { return categoryToInfos_; }

References categoryToInfos_.

Referenced by PrintLoadingPlugins::askedToLoad(), FWDetailViewManager::findViewersFor(), FWEveViewManager::FWEveViewManager(), FWItemAccessorFactory::hasAccessor(), main(), and edm::PluginDescription< T >::printNestedContent_().

◆ configure()

PluginManager & PluginManager::configure ( const Config iConfig)
static

Definition at line 315 of file PluginManager.cc.

315  {
316  PluginManager*& s = singleton();
317  if (nullptr != s) {
318  throw cms::Exception("PluginManagerReconfigured");
319  }
320 
321  const Config& realConfig = iConfig;
322  if (realConfig.searchPath().empty()) {
323  throw cms::Exception("PluginManagerEmptySearchPath");
324  }
325  s = new PluginManager(realConfig);
326  return *s;
327  }

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

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

◆ get()

PluginManager * PluginManager::get ( )
static

◆ isAvailable()

bool PluginManager::isAvailable ( )
static

◆ load()

const SharedLibrary & PluginManager::load ( const std::string &  iCategory,
const std::string &  iPlugin 
)

Definition at line 226 of file PluginManager.cc.

226  {
227  askedToLoadCategoryWithPlugin_(iCategory, iPlugin);
228  const std::filesystem::path& p = loadableFor(iCategory, iPlugin);
229 
230  //have we already loaded this?
231  auto itLoaded = loadables_.find(p);
232  if (itLoaded == loadables_.end()) {
233  //Need to make sure we only have on SharedLibrary loading at a time
234  std::lock_guard<std::recursive_mutex> guard(pluginLoadMutex());
235  //Another thread may have gotten this while we were waiting on the mutex
236  itLoaded = loadables_.find(p);
237  if (itLoaded == loadables_.end()) {
238  //try to make one
239  goingToLoad_(p);
240  Sentry s(loadingLibraryNamed_(), p.string());
241  //std::filesystem::path native(p.string());
242  std::shared_ptr<SharedLibrary> ptr;
243  {
244  //TEMPORARY: to avoid possible deadlocks from ROOT, we must
245  // take the lock ourselves
246  R__LOCKGUARD2(gInterpreterMutex);
247  try {
248  ptr = std::make_shared<SharedLibrary>(p);
249  } catch (cms::Exception& e) {
250  e.addContext("While attempting to load plugin " + iPlugin);
251  throw;
252  }
253  }
254  loadables_[p] = ptr;
255  justLoaded_(*ptr);
256  return *ptr;
257  }
258  }
259  return *(itLoaded->second);
260  }

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

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

◆ loadableFor()

const std::filesystem::path & PluginManager::loadableFor ( const std::string &  iCategory,
const std::string &  iPlugin 
)

Definition at line 150 of file PluginManager.cc.

150  {
151  bool throwIfFail = true;
152  return loadableFor_(iCategory, iPlugin, throwIfFail);
153  }

References loadableFor_().

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

◆ loadableFor_()

const std::filesystem::path & PluginManager::loadableFor_ ( const std::string &  iCategory,
const std::string &  iPlugin,
bool &  ioThrowIfFailElseSucceedStatus 
)
private

Definition at line 155 of file PluginManager.cc.

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

References categoryToInfos_, Exception, mps_fire::i, castor_dqm_sourceclient_file_cfg::path, and FastTimerService_cff::range.

Referenced by loadableFor(), and tryToLoad().

◆ loadingFile()

static const std::string& edmplugin::PluginManager::loadingFile ( )
inlinestatic

file name of the shared object being loaded

Definition at line 89 of file PluginManager.h.

89 { return loadingLibraryNamed_(); }

References loadingLibraryNamed_().

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

◆ loadingLibraryNamed_()

std::string & PluginManager::loadingLibraryNamed_ ( )
staticprivate

Definition at line 334 of file PluginManager.cc.

334  {
335  //NOTE: pluginLoadMutex() indirectly guards this since this value
336  // is only accessible via the Sentry call which us guarded by the mutex
338  return s_name;
339  }

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

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

◆ newFactory()

void PluginManager::newFactory ( const PluginFactoryBase )
private

Definition at line 140 of file PluginManager.cc.

140 {}

Referenced by PluginManager().

◆ operator=()

const PluginManager& edmplugin::PluginManager::operator= ( const PluginManager )
delete

◆ pluginLoadMutex()

std::recursive_mutex& edmplugin::PluginManager::pluginLoadMutex ( )
inlineprivate

Definition at line 111 of file PluginManager.h.

111 { return pluginLoadMutex_; }

References pluginLoadMutex_.

Referenced by load(), and tryToLoad().

◆ singleton()

PluginManager *& PluginManager::singleton ( )
staticprivate

Definition at line 341 of file PluginManager.cc.

341  {
342  CMS_THREAD_SAFE static PluginManager* s_singleton = nullptr;
343  return s_singleton;
344  }

References CMS_THREAD_SAFE.

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

◆ staticallyLinkedLoadingFileName()

const std::string & PluginManager::staticallyLinkedLoadingFileName ( )
static

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

Definition at line 329 of file PluginManager.cc.

329  {
330  static const std::string s_name("static");
331  return s_name;
332  }

References AlCaHLTBitMon_QueryRunRegistry::string.

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

◆ tryToLoad()

const SharedLibrary * PluginManager::tryToLoad ( const std::string &  iCategory,
const std::string &  iPlugin 
)

Definition at line 262 of file PluginManager.cc.

262  {
263  askedToLoadCategoryWithPlugin_(iCategory, iPlugin);
264  bool ioThrowIfFailElseSucceedStatus = false;
265  const std::filesystem::path& p = loadableFor_(iCategory, iPlugin, ioThrowIfFailElseSucceedStatus);
266 
267  if (not ioThrowIfFailElseSucceedStatus) {
268  return nullptr;
269  }
270 
271  //have we already loaded this?
272  auto itLoaded = loadables_.find(p);
273  if (itLoaded == loadables_.end()) {
274  //Need to make sure we only have on SharedLibrary loading at a time
275  std::lock_guard<std::recursive_mutex> guard(pluginLoadMutex());
276  //Another thread may have gotten this while we were waiting on the mutex
277  itLoaded = loadables_.find(p);
278  if (itLoaded == loadables_.end()) {
279  //try to make one
280  goingToLoad_(p);
281  Sentry s(loadingLibraryNamed_(), p.string());
282  //std::filesystem::path native(p.string());
283  std::shared_ptr<SharedLibrary> ptr;
284  {
285  //TEMPORARY: to avoid possible deadlocks from ROOT, we must
286  // take the lock ourselves
287  R__LOCKGUARD(gInterpreterMutex);
288  try {
289  ptr = std::make_shared<SharedLibrary>(p);
290  } catch (cms::Exception& e) {
291  e.addContext("While attempting to load plugin " + iPlugin);
292  throw;
293  }
294  }
295  loadables_[p] = ptr;
296  justLoaded_(*ptr);
297  return ptr.get();
298  }
299  }
300  return (itLoaded->second).get();
301  }

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

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

Friends And Related Function Documentation

◆ DummyFriend

friend class DummyFriend
friend

Definition at line 46 of file PluginManager.h.

Member Data Documentation

◆ askedToLoadCategoryWithPlugin_

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

Definition at line 102 of file PluginManager.h.

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

◆ categoryToInfos_

CategoryToInfos edmplugin::PluginManager::categoryToInfos_
private

Definition at line 121 of file PluginManager.h.

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

◆ goingToLoad_

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

Definition at line 100 of file PluginManager.h.

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

◆ justLoaded_

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

Definition at line 101 of file PluginManager.h.

Referenced by load(), and tryToLoad().

◆ loadables_

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

Definition at line 119 of file PluginManager.h.

Referenced by load(), and tryToLoad().

◆ pluginLoadMutex_

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

Definition at line 122 of file PluginManager.h.

Referenced by pluginLoadMutex().

◆ searchPath_

SearchPath edmplugin::PluginManager::searchPath_
private

Definition at line 117 of file PluginManager.h.

Referenced by PluginManager().

FastTimerService_cff.range
range
Definition: FastTimerService_cff.py:34
edmplugin::PluginManager::searchPath_
SearchPath searchPath_
Definition: PluginManager.h:117
mps_fire.i
i
Definition: mps_fire.py:428
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
edmplugin::standard::cachefileName
const std::filesystem::path & cachefileName()
Definition: standard.cc:47
edmplugin::PluginManager::loadables_
tbb::concurrent_unordered_map< std::filesystem::path, std::shared_ptr< SharedLibrary >, PluginManagerPathHasher > loadables_
Definition: PluginManager.h:119
edmplugin::PluginManager::pluginLoadMutex
std::recursive_mutex & pluginLoadMutex()
Definition: PluginManager.h:111
alignCSCRings.s
s
Definition: alignCSCRings.py:92
edmplugin::PluginManager::goingToLoad_
edm::signalslot::Signal< void(const std::filesystem::path &)> goingToLoad_
Definition: PluginManager.h:100
edmplugin::PluginManager::loadableFor
const std::filesystem::path & loadableFor(const std::string &iCategory, const std::string &iPlugin)
Definition: PluginManager.cc:150
PluginFactoryManager
CMS_THREAD_SAFE
#define CMS_THREAD_SAFE
Definition: thread_safety_macros.h:4
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
edmplugin::PluginManager::singleton
static PluginManager *& singleton()
Definition: PluginManager.cc:341
edmplugin::PluginManager::pluginLoadMutex_
std::recursive_mutex pluginLoadMutex_
Definition: PluginManager.h:122
edmplugin::readCacheFile
static bool readCacheFile(const std::filesystem::path &cacheFile, const std::filesystem::path &dir, PluginManager::CategoryToInfos &categoryToInfos)
Definition: PluginManager.cc:41
edmplugin::PluginManager::PluginManager
PluginManager(const PluginManager &)=delete
postprocess-scan-build.seen
seen
Definition: postprocess-scan-build.py:9
PluginManager
edmplugin::PluginManager::loadingLibraryNamed_
static std::string & loadingLibraryNamed_()
Definition: PluginManager.cc:334
edmplugin::standard::poisonedCachefileName
const std::filesystem::path & poisonedCachefileName()
Definition: standard.cc:52
edmplugin::PluginManager::newFactory
void newFactory(const PluginFactoryBase *)
Definition: PluginManager.cc:140
edmplugin::PluginManager::askedToLoadCategoryWithPlugin_
edm::signalslot::Signal< void(const std::string &, const std::string &)> askedToLoadCategoryWithPlugin_
Definition: PluginManager.h:102
Exception
Definition: hltDiff.cc:246
edmplugin::PluginManager::loadableFor_
const std::filesystem::path & loadableFor_(const std::string &iCategory, const std::string &iPlugin, bool &ioThrowIfFailElseSucceedStatus)
Definition: PluginManager.cc:155
edmplugin::PluginManager::categoryToInfos_
CategoryToInfos categoryToInfos_
Definition: PluginManager.h:121
edmplugin::PluginFactoryManager::const_iterator
std::vector< const PluginFactoryBase * >::const_iterator const_iterator
Definition: PluginFactoryManager.h:38
cms::Exception
Definition: Exception.h:70
castor_dqm_sourceclient_file_cfg.path
path
Definition: castor_dqm_sourceclient_file_cfg.py:37
PluginInfo
edmplugin::PluginManager::staticallyLinkedLoadingFileName
static const std::string & staticallyLinkedLoadingFileName()
if the value returned from loadingFile matches this string then the file is statically linked
Definition: PluginManager.cc:329
Config
Definition: Config.py:1
edmplugin::PluginFactoryManager::get
static PluginFactoryManager * get()
Definition: PluginFactoryManager.cc:70
DeadROC_duringRun.dir
dir
Definition: DeadROC_duringRun.py:23
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37
edmplugin::PluginManager::justLoaded_
edm::signalslot::Signal< void(const SharedLibrary &)> justLoaded_
Definition: PluginManager.h:101