Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-24 02:18:55

0001 #ifndef FWCore_PluginManager_PluginFactoryBase_h
0002 #define FWCore_PluginManager_PluginFactoryBase_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     PluginManager
0006 // Class  :     PluginFactoryBase
0007 //
0008 /**\class PluginFactoryBase PluginFactoryBase.h FWCore/PluginManager/interface/PluginFactoryBase.h
0009 
0010  Description: Base class for all plugin factories
0011 
0012  Usage:
0013     This interface provides access to the most generic information about a plugin factory:
0014     1) what is the name of the presently available plugins
0015     2) the file name of the loadable which contained the plugin
0016 */
0017 //
0018 // Original Author:  Chris Jones
0019 //         Created:  Wed Apr  4 12:24:44 EDT 2007
0020 //
0021 
0022 // system include files
0023 #include <string>
0024 #include <vector>
0025 #include <map>
0026 #include <atomic>
0027 #include "oneapi/tbb/concurrent_unordered_map.h"
0028 #include "oneapi/tbb/concurrent_vector.h"
0029 #include "FWCore/Utilities/interface/zero_allocator.h"
0030 #include "FWCore/Utilities/interface/Signal.h"
0031 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0032 // user include files
0033 #include "FWCore/PluginManager/interface/PluginInfo.h"
0034 
0035 // forward declarations
0036 namespace edmplugin {
0037   class PluginFactoryBase {
0038   public:
0039     PluginFactoryBase() {}
0040     PluginFactoryBase(const PluginFactoryBase&) = delete;                   // stop default
0041     const PluginFactoryBase& operator=(const PluginFactoryBase&) = delete;  // stop default
0042     virtual ~PluginFactoryBase();
0043 
0044     struct PluginMakerInfo {
0045       PluginMakerInfo(void* iPtr, const std::string& iName) : m_name(iName), m_ptr() {
0046         m_ptr.store(iPtr, std::memory_order_release);
0047       }
0048 
0049       PluginMakerInfo(const PluginMakerInfo& iOther) : m_name(iOther.m_name), m_ptr() {
0050         m_ptr.store(iOther.m_ptr.load(std::memory_order_acquire), std::memory_order_release);
0051       }
0052 
0053       PluginMakerInfo& operator=(const PluginMakerInfo& iOther) {
0054         m_name = iOther.m_name;
0055         m_ptr.store(iOther.m_ptr.load(std::memory_order_acquire), std::memory_order_release);
0056         return *this;
0057       }
0058       std::string m_name;
0059       //NOTE: this has to be last since once it is non zero it signals
0060       // that the construction has finished
0061       std::atomic<void*> m_ptr;
0062     };
0063 
0064     typedef oneapi::tbb::concurrent_vector<PluginMakerInfo, edm::zero_allocator<PluginMakerInfo>> PMakers;
0065     typedef oneapi::tbb::concurrent_unordered_map<std::string, PMakers> Plugins;
0066 
0067     // ---------- const member functions ---------------------
0068 
0069     ///return info about all plugins which are already available in the program
0070     virtual std::vector<PluginInfo> available() const;
0071 
0072     ///returns the name of the category to which this plugin factory belongs
0073     virtual const std::string& category() const = 0;
0074 
0075     //The signal is only modified during a shared library load which is protected by a mutex by the operating system
0076     ///signal containing plugin category, and  plugin info for newly added plugin
0077     CMS_THREAD_SAFE mutable edm::signalslot::Signal<void(const std::string&, const PluginInfo&)> newPluginAdded_;
0078 
0079     // ---------- static member functions --------------------
0080 
0081     // ---------- member functions ---------------------------
0082 
0083   protected:
0084     /**call this as the last line in the constructor of inheriting classes
0085       this is done so that the virtual table will be properly initialized when the
0086       routine is called
0087       */
0088     void finishedConstruction();
0089 
0090     void newPlugin(const std::string& iName);
0091 
0092     //since each inheriting class has its own Container type to hold their PMakers
0093     // this function allows them to share the same code when doing the lookup
0094     // this routine will throw an exception if iName is unknown therefore the return value is always valid
0095     void* findPMaker(const std::string& iName) const;
0096 
0097     //similar to findPMaker but will return 'end()' if iName is known
0098     void* tryToFindPMaker(const std::string& iName) const;
0099 
0100     void fillInfo(const PMakers& makers, PluginInfo& iInfo, std::vector<PluginInfo>& iReturn) const;
0101 
0102     void fillAvailable(std::vector<PluginInfo>& iReturn) const;
0103 
0104     void registerPMaker(void* iPMaker, const std::string& iName);
0105 
0106   private:
0107     void checkProperLoadable(const std::string& iName, const std::string& iLoadedFrom) const;
0108     // ---------- member data --------------------------------
0109     Plugins m_plugins;
0110   };
0111 
0112 }  // namespace edmplugin
0113 #endif