Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-17 01:30:25

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, ServiceLegacy iLegacy, std::vector<ParameterSet>& iConfiguration);
0067 
0068       ServicesManager(ServicesManager const&) = delete;                   // stop default
0069       ServicesManager const& operator=(ServicesManager const&) = delete;  // stop default
0070       ~ServicesManager();
0071 
0072       // ---------- const member functions ---------------------
0073       template <typename T>
0074       T& get() const {
0075         Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
0076         Type2Maker::const_iterator itFoundMaker;
0077         if (itFound == type2Service_.end()) {
0078           //do on demand building of the service
0079           if (nullptr == type2Maker_.get() ||
0080               type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
0081             auto demangled = typeDemangle(typeid(T).name());
0082             Exception::throwThis(errors::NotFound,
0083                                  "Service Request unable to find requested service with C++ type '",
0084                                  demangled.c_str(),
0085                                  "'.\n");
0086           } else {
0087             const_cast<ServicesManager&>(*this).createServiceFor(itFoundMaker->second);
0088             itFound = type2Service_.find(TypeIDBase(typeid(T)));
0089             //the 'add()' should have put the service into the list
0090             assert(itFound != type2Service_.end());
0091           }
0092         }
0093         //convert it to its actual type
0094         std::shared_ptr<ServiceWrapper<T>> ptr(std::dynamic_pointer_cast<ServiceWrapper<T>>(itFound->second));
0095         assert(nullptr != ptr.get());
0096         return ptr->get();
0097       }
0098 
0099       ///returns true of the particular service is accessible
0100       template <typename T>
0101       bool isAvailable() const {
0102         Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
0103         Type2Maker::const_iterator itFoundMaker;
0104         if (itFound == type2Service_.end()) {
0105           //do on demand building of the service
0106           if (nullptr == type2Maker_.get() ||
0107               type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
0108             return false;
0109           } else {
0110             //Actually create the service in order to 'flush out' any
0111             // configuration errors for the service
0112             const_cast<ServicesManager&>(*this).createServiceFor(itFoundMaker->second);
0113             itFound = type2Service_.find(TypeIDBase(typeid(T)));
0114             //the 'add()' should have put the service into the list
0115             assert(itFound != type2Service_.end());
0116           }
0117         }
0118         return true;
0119       }
0120 
0121       // ---------- static member functions --------------------
0122 
0123       // ---------- member functions ---------------------------
0124       ///returns false if put fails because a service of this type already exists
0125       template <typename T>
0126       bool put(std::shared_ptr<ServiceWrapper<T>> iPtr, bool iOverride = false) {
0127         Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
0128         if (itFound != type2Service_.end() and not iOverride) {
0129           return false;
0130         }
0131         type2Service_[TypeIDBase(typeid(T))] = iPtr;
0132         actualCreationOrder_.push_back(TypeIDBase(typeid(T)));
0133         return true;
0134       }
0135 
0136       ///causes our ActivityRegistry's signals to be forwarded to iOther
0137       void connect(ActivityRegistry& iOther);
0138 
0139       ///causes iOther's signals to be forward to us
0140       void connectTo(ActivityRegistry& iOther);
0141 
0142       ///copy our Service's slots to the argument's signals
0143       void copySlotsTo(ActivityRegistry&);
0144       ///the copy the argument's slots to the our signals
0145       void copySlotsFrom(ActivityRegistry&);
0146 
0147     private:
0148       void fillListOfMakers(std::vector<ParameterSet>&);
0149       void createServices();
0150       void createServiceFor(MakerHolder const&);
0151 
0152       // ---------- member data --------------------------------
0153       //hold onto the Manager passed in from the ServiceToken so that
0154       // the ActivityRegistry of that Manager does not go out of scope
0155       // This must be first to get the Service destructors called in
0156       // the correct order.
0157       edm::propagate_const<std::shared_ptr<ServicesManager>> associatedManager_;
0158 
0159       ActivityRegistry registry_;
0160       Type2Service type2Service_;
0161       edm::propagate_const<std::unique_ptr<Type2Maker>> type2Maker_;
0162       std::vector<TypeIDBase> requestedCreationOrder_;
0163       std::vector<TypeIDBase> actualCreationOrder_;
0164     };
0165   }  // namespace serviceregistry
0166 }  // namespace edm
0167 
0168 #endif