Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:13:02

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