Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:29:08

0001 #ifndef ServiceRegistry_ServicesManager_h
0002 #define ServiceRegistry_ServicesManager_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     ServiceRegistry
0006 // Class  :     ServicesManager
0007 //
0008 /**\class ServicesManager ServicesManager.h FWCore/ServiceRegistry/interface/ServicesManager.h
0009 
0010  Description: <one line class summary>
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Original Author:  Chris Jones
0018 //         Created:  Mon Sep  5 13:33:01 EDT 2005
0019 //
0020 
0021 // user include files
0022 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0023 #include "FWCore/ServiceRegistry/interface/ServiceLegacy.h"
0024 #include "FWCore/ServiceRegistry/interface/ServiceMakerBase.h"
0025 #include "FWCore/ServiceRegistry/interface/ServiceWrapper.h"
0026 #include "FWCore/Utilities/interface/EDMException.h"
0027 #include "FWCore/Utilities/interface/TypeIDBase.h"
0028 #include "FWCore/Utilities/interface/propagate_const.h"
0029 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0030 
0031 // system include files
0032 #include <memory>
0033 
0034 #include <cassert>
0035 #include <vector>
0036 
0037 // forward declarations
0038 namespace edm {
0039   class ParameterSet;
0040   class ServiceToken;
0041 
0042   namespace serviceregistry {
0043 
0044     class ServicesManager {
0045     public:
0046       struct MakerHolder {
0047         MakerHolder(std::shared_ptr<ServiceMakerBase> iMaker, ParameterSet& iPSet, ActivityRegistry&);
0048         bool add(ServicesManager&) const;
0049 
0050         edm::propagate_const<std::shared_ptr<ServiceMakerBase>> maker_;
0051         ParameterSet* pset_;
0052         ActivityRegistry* registry_;  // We do not use propagate_const because the registry itself is mutable
0053         //Services construction is not allowed to occur across threads
0054         CMS_SA_ALLOW mutable bool wasAdded_;
0055       };
0056       typedef std::map<TypeIDBase, std::shared_ptr<ServiceWrapperBase>> Type2Service;
0057       typedef std::map<TypeIDBase, MakerHolder> Type2Maker;
0058 
0059       ServicesManager(std::vector<ParameterSet>& iConfiguration);
0060 
0061       /** Takes the services described by iToken and places them into the manager.
0062              Conflicts over Services provided by both the iToken and iConfiguration
0063              are resolved based on the value of iLegacy
0064          */
0065       ServicesManager(ServiceToken iToken,
0066                       ServiceLegacy iLegacy,
0067                       std::vector<ParameterSet>& iConfiguration,
0068                       bool associate = true);
0069 
0070       ServicesManager(ServicesManager const&) = delete;                   // stop default
0071       ServicesManager const& operator=(ServicesManager const&) = delete;  // stop default
0072       ~ServicesManager();
0073 
0074       // ---------- const member functions ---------------------
0075       template <typename T>
0076       T& get() const {
0077         Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
0078         Type2Maker::const_iterator itFoundMaker;
0079         if (itFound == type2Service_.end()) {
0080           //do on demand building of the service
0081           if (nullptr == type2Maker_.get() ||
0082               type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
0083             Exception::throwThis(errors::NotFound,
0084                                  "Service Request unable to find requested service with compiler type name '",
0085                                  typeid(T).name(),
0086                                  "'.\n");
0087           } else {
0088             const_cast<ServicesManager&>(*this).createServiceFor(itFoundMaker->second);
0089             itFound = type2Service_.find(TypeIDBase(typeid(T)));
0090             //the 'add()' should have put the service into the list
0091             assert(itFound != type2Service_.end());
0092           }
0093         }
0094         //convert it to its actual type
0095         std::shared_ptr<ServiceWrapper<T>> ptr(std::dynamic_pointer_cast<ServiceWrapper<T>>(itFound->second));
0096         assert(nullptr != ptr.get());
0097         return ptr->get();
0098       }
0099 
0100       ///returns true of the particular service is accessible
0101       template <typename T>
0102       bool isAvailable() const {
0103         Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
0104         Type2Maker::const_iterator itFoundMaker;
0105         if (itFound == type2Service_.end()) {
0106           //do on demand building of the service
0107           if (nullptr == type2Maker_.get() ||
0108               type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
0109             return false;
0110           } else {
0111             //Actually create the service in order to 'flush out' any
0112             // configuration errors for the service
0113             const_cast<ServicesManager&>(*this).createServiceFor(itFoundMaker->second);
0114             itFound = type2Service_.find(TypeIDBase(typeid(T)));
0115             //the 'add()' should have put the service into the list
0116             assert(itFound != type2Service_.end());
0117           }
0118         }
0119         return true;
0120       }
0121 
0122       // ---------- static member functions --------------------
0123 
0124       // ---------- member functions ---------------------------
0125       ///returns false if put fails because a service of this type already exists
0126       template <typename T>
0127       bool put(std::shared_ptr<ServiceWrapper<T>> iPtr) {
0128         Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
0129         if (itFound != type2Service_.end()) {
0130           return false;
0131         }
0132         type2Service_[TypeIDBase(typeid(T))] = iPtr;
0133         actualCreationOrder_.push_back(TypeIDBase(typeid(T)));
0134         return true;
0135       }
0136 
0137       ///causes our ActivityRegistry's signals to be forwarded to iOther
0138       void connect(ActivityRegistry& iOther);
0139 
0140       ///causes iOther's signals to be forward to us
0141       void connectTo(ActivityRegistry& iOther);
0142 
0143       ///copy our Service's slots to the argument's signals
0144       void copySlotsTo(ActivityRegistry&);
0145       ///the copy the argument's slots to the our signals
0146       void copySlotsFrom(ActivityRegistry&);
0147 
0148     private:
0149       void fillListOfMakers(std::vector<ParameterSet>&);
0150       void createServices();
0151       void createServiceFor(MakerHolder const&);
0152 
0153       // ---------- member data --------------------------------
0154       //hold onto the Manager passed in from the ServiceToken so that
0155       // the ActivityRegistry of that Manager does not go out of scope
0156       // This must be first to get the Service destructors called in
0157       // the correct order.
0158       edm::propagate_const<std::shared_ptr<ServicesManager>> associatedManager_;
0159 
0160       ActivityRegistry registry_;
0161       Type2Service type2Service_;
0162       edm::propagate_const<std::unique_ptr<Type2Maker>> type2Maker_;
0163       std::vector<TypeIDBase> requestedCreationOrder_;
0164       std::vector<TypeIDBase> actualCreationOrder_;
0165     };
0166   }  // namespace serviceregistry
0167 }  // namespace edm
0168 
0169 #endif