Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:59

0001 // -*- C++ -*-
0002 //
0003 // Package:     PluginManager
0004 // Class  :     PluginFactoryBase
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Chris Jones
0010 //         Created:  Wed Apr  4 13:09:50 EDT 2007
0011 //
0012 
0013 // system include files
0014 #include <cassert>
0015 
0016 // user include files
0017 #include "FWCore/PluginManager/interface/PluginFactoryBase.h"
0018 #include "FWCore/PluginManager/interface/PluginManager.h"
0019 #include "FWCore/Utilities/interface/Exception.h"
0020 #include "FWCore/PluginManager/interface/PluginFactoryManager.h"
0021 
0022 namespace edmplugin {
0023   //
0024   // constants, enums and typedefs
0025   //
0026 
0027   //
0028   // static data member definitions
0029   //
0030 
0031   //
0032   // constructors and destructor
0033   //
0034 
0035   // PluginFactoryBase::PluginFactoryBase(const PluginFactoryBase& rhs)
0036   // {
0037   //    // do actual copying here;
0038   // }
0039 
0040   PluginFactoryBase::~PluginFactoryBase() {}
0041 
0042   //
0043   // assignment operators
0044   //
0045   // const PluginFactoryBase& PluginFactoryBase::operator=(const PluginFactoryBase& rhs)
0046   // {
0047   //   //An exception safe implementation is
0048   //   PluginFactoryBase temp(rhs);
0049   //   swap(rhs);
0050   //
0051   //   return *this;
0052   // }
0053 
0054   //
0055   // member functions
0056   //
0057   void PluginFactoryBase::finishedConstruction() { PluginFactoryManager::get()->addFactory(this); }
0058 
0059   void PluginFactoryBase::newPlugin(const std::string& iName) {
0060     PluginInfo info;
0061     info.loadable_ = std::filesystem::path(PluginManager::loadingFile());
0062     info.name_ = iName;
0063     newPluginAdded_(category(), info);
0064   }
0065 
0066   void* PluginFactoryBase::findPMaker(const std::string& iName) const {
0067     //do we already have it?
0068     Plugins::const_iterator itFound = m_plugins.find(iName);
0069     if (itFound == m_plugins.end()) {
0070       std::string lib = PluginManager::get()->load(this->category(), iName).path().string();
0071       itFound = m_plugins.find(iName);
0072       if (itFound == m_plugins.end()) {
0073         throw cms::Exception("PluginCacheError")
0074             << "The plugin '" << iName << "' should have been in loadable\n '" << lib
0075             << "'\n but was not there.  This means the plugin cache is incorrect.  Please run 'EdmPluginRefresh " << lib
0076             << "'";
0077       }
0078       //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
0079       auto const& value = itFound->second.front();
0080       while (value.m_ptr.load(std::memory_order_acquire) == nullptr) {
0081       }
0082     } else {
0083       //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
0084       auto const& value = itFound->second.front();
0085       while (value.m_ptr.load(std::memory_order_acquire) == nullptr) {
0086       }
0087       checkProperLoadable(iName, value.m_name);
0088     }
0089     return itFound->second.front().m_ptr.load(std::memory_order_acquire);
0090   }
0091 
0092   void* PluginFactoryBase::tryToFindPMaker(const std::string& iName) const {
0093     //do we already have it?
0094     Plugins::const_iterator itFound = m_plugins.find(iName);
0095     if (itFound == m_plugins.end()) {
0096       const SharedLibrary* slib = PluginManager::get()->tryToLoad(this->category(), iName);
0097       if (nullptr != slib) {
0098         std::string lib = slib->path().string();
0099         itFound = m_plugins.find(iName);
0100         if (itFound == m_plugins.end()) {
0101           throw cms::Exception("PluginCacheError")
0102               << "The plugin '" << iName << "' should have been in loadable\n '" << lib
0103               << "'\n but was not there.  This means the plugin cache is incorrect.  Please run 'EdmPluginRefresh "
0104               << lib << "'";
0105         }
0106       }
0107     } else {
0108       //The item in the container can still be under construction so wait until the m_ptr has been set since that is done last
0109       auto const& value = itFound->second.front();
0110       while (value.m_ptr.load(std::memory_order_acquire) == nullptr) {
0111       }
0112       checkProperLoadable(iName, value.m_name);
0113     }
0114     return itFound != m_plugins.end() ? itFound->second.front().m_ptr.load(std::memory_order_acquire) : nullptr;
0115   }
0116 
0117   void PluginFactoryBase::fillInfo(const PMakers& makers, PluginInfo& iInfo, std::vector<PluginInfo>& iReturn) const {
0118     for (PMakers::const_iterator it = makers.begin(); it != makers.end(); ++it) {
0119       while (nullptr == it->m_ptr.load(std::memory_order_acquire))
0120         ;
0121       iInfo.loadable_ = it->m_name;
0122       iReturn.push_back(iInfo);
0123     }
0124   }
0125 
0126   void PluginFactoryBase::fillAvailable(std::vector<PluginInfo>& iReturn) const {
0127     PluginInfo info;
0128     for (Plugins::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it) {
0129       info.name_ = it->first;
0130       fillInfo(it->second, info, iReturn);
0131     }
0132   }
0133 
0134   void PluginFactoryBase::checkProperLoadable(const std::string& iName, const std::string& iLoadedFrom) const {
0135     //should check to see if this is from the proper loadable if it
0136     // was not statically linked
0137     if (iLoadedFrom != PluginManager::staticallyLinkedLoadingFileName() && PluginManager::isAvailable()) {
0138       if (iLoadedFrom != PluginManager::get()->loadableFor(category(), iName).string()) {
0139         throw cms::Exception("WrongPluginLoaded")
0140             << "The plugin '" << iName << "' should have been loaded from\n '"
0141             << PluginManager::get()->loadableFor(category(), iName).string()
0142             << "'\n but instead it was already loaded from\n '" << iLoadedFrom
0143             << "'\n because some other plugin was loaded from the latter loadables.\n"
0144                "To work around the problem the plugin '"
0145             << iName << "' should only be defined in one of these loadables.";
0146       }
0147     }
0148   }
0149 
0150   void PluginFactoryBase::registerPMaker(void* iPMaker, const std::string& iName) {
0151     assert(nullptr != iPMaker);
0152     PMakers newMakers;
0153     newMakers.emplace_back(iPMaker, PluginManager::loadingFile());
0154     if (not m_plugins.emplace(iName, std::move(newMakers)).second) {
0155       //the item was already added
0156       m_plugins[iName].push_back(PluginMakerInfo(iPMaker, PluginManager::loadingFile()));
0157     }
0158     newPlugin(iName);
0159   }
0160 
0161   std::vector<PluginInfo> PluginFactoryBase::available() const {
0162     std::vector<PluginInfo> returnValue;
0163     returnValue.reserve(m_plugins.size());
0164     fillAvailable(returnValue);
0165     return returnValue;
0166   }
0167 
0168   //
0169   // const member functions
0170   //
0171 
0172   //
0173   // static member functions
0174   //
0175 }  // namespace edmplugin