CMS 3D CMS Logo

Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes

edm::serviceregistry::ServicesManager Class Reference

#include <ServicesManager.h>

List of all members.

Classes

struct  MakerHolder

Public Types

typedef std::map< TypeIDBase,
MakerHolder
Type2Maker
typedef std::map< TypeIDBase,
boost::shared_ptr
< ServiceWrapperBase > > 
Type2Service

Public Member Functions

void connect (ActivityRegistry &iOther)
 causes our ActivityRegistry's signals to be forwarded to iOther
void connectTo (ActivityRegistry &iOther)
 causes iOther's signals to be forward to us
void copySlotsFrom (ActivityRegistry &)
 the copy the argument's slots to the our signals
void copySlotsTo (ActivityRegistry &)
 copy our Service's slots to the argument's signals
template<typename T >
Tget () const
template<typename T >
bool isAvailable () const
 returns true of the particular service is accessible
template<typename T >
bool put (boost::shared_ptr< ServiceWrapper< T > > iPtr)
 returns false if put fails because a service of this type already exists
 ServicesManager (ServiceToken iToken, ServiceLegacy iLegacy, std::vector< ParameterSet > &iConfiguration, bool associate=true)
 ServicesManager (std::vector< ParameterSet > &iConfiguration)
 ~ServicesManager ()

Private Member Functions

void createServices ()
void fillListOfMakers (std::vector< ParameterSet > &)
ServicesManager const & operator= (ServicesManager const &)
 ServicesManager (ServicesManager const &)

Private Attributes

std::vector< TypeIDBaseactualCreationOrder_
boost::shared_ptr
< ServicesManager
associatedManager_
ActivityRegistry registry_
std::vector< TypeIDBaserequestedCreationOrder_
std::auto_ptr< Type2Makertype2Maker_
Type2Service type2Service_

Detailed Description

Definition at line 42 of file ServicesManager.h.


Member Typedef Documentation

Definition at line 56 of file ServicesManager.h.

Definition at line 55 of file ServicesManager.h.


Constructor & Destructor Documentation

ServicesManager::ServicesManager ( std::vector< ParameterSet > &  iConfiguration)

Definition at line 69 of file ServicesManager.cc.

References createServices(), and fillListOfMakers().

                                                                              :
      type2Maker_(new Type2Maker) {
         //First create the list of makers
         fillListOfMakers(iConfiguration);

         createServices();
      }
ServicesManager::ServicesManager ( ServiceToken  iToken,
ServiceLegacy  iLegacy,
std::vector< ParameterSet > &  iConfiguration,
bool  associate = true 
)

Takes the services described by iToken and places them into the manager. Conflicts over Services provided by both the iToken and iConfiguration are resolved based on the value of iLegacy

Definition at line 77 of file ServicesManager.cc.

References associatedManager_, edm::errors::Configuration, edm::ActivityRegistry::copySlotsFrom(), createServices(), Exception, fillListOfMakers(), reco::helper::VirtualJetProducerHelper::intersection(), edm::serviceregistry::kConfigurationOverrides, edm::serviceregistry::kOverlapIsError, edm::serviceregistry::kTokenOverrides, edm::ServiceToken::manager_, registry_, type2Maker_, type2Service_, and edm::typeDemangle().

                                                       :
            associatedManager_(associate ? iToken.manager_ : boost::shared_ptr<ServicesManager>()),
            type2Maker_(new Type2Maker) {
         fillListOfMakers(iConfiguration);

         //find overlaps between services in iToken and iConfiguration
         typedef std::set< TypeIDBase> TypeSet;
         TypeSet configTypes;
         for(Type2Maker::iterator itType = type2Maker_->begin(), itTypeEnd = type2Maker_->end();
             itType != itTypeEnd;
             ++itType) {
            configTypes.insert(itType->first);
         }

         TypeSet tokenTypes;
         if(0 != iToken.manager_.get()) {
            for(Type2Service::iterator itType = iToken.manager_->type2Service_.begin(),
                itTypeEnd = iToken.manager_->type2Service_.end();
                itType != itTypeEnd;
                ++itType) {
               tokenTypes.insert(itType->first);
            }

            typedef std::set<TypeIDBase> IntersectionType;
            IntersectionType intersection;
            std::set_intersection(configTypes.begin(), configTypes.end(),
                                  tokenTypes.begin(), tokenTypes.end(),
                                  inserter(intersection, intersection.end()));

            switch(iLegacy) {
               case kOverlapIsError :
                  if(!intersection.empty()) {
                     throw Exception(errors::Configuration, "Service")
                     << "the Service " << (*type2Maker_).find(*(intersection.begin()))->second.pset_->getParameter<std::string>("@service_type")
                     << " already has an instance of that type of Service";
                  } else {
                     //get all the services from Token
                     type2Service_ = iToken.manager_->type2Service_;
                  }
                  break;
               case kTokenOverrides :
                  //get all the services from Token
                  type2Service_ = iToken.manager_->type2Service_;

                  //remove from type2Maker the overlapping services so we never try to make them
                  for(IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
                      itType != itTypeEnd;
                      ++itType) {
                     Type2Maker::iterator itFound = type2Maker_->find(*itType);
                     //HLT needs it such that even if a service isn't created we store its PSet if needed
                     if(itFound->second.maker_->saveConfiguration()) {
                        itFound->second.pset_->addUntrackedParameter("@save_config", true);
                     }
                     type2Maker_->erase(itFound);
                  }
                  break;
               case kConfigurationOverrides:
                  //get all the services from the Configuration, except process wide services
                  type2Service_ = iToken.manager_->type2Service_;

                  //now remove the ones we do not want
                  for(IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
                      itType != itTypeEnd;
                      ++itType) {
                     Type2Maker::iterator itFound = type2Maker_->find(*itType);
                     if(itFound->second.maker_->processWideService()) {
                       // This is a process wide service, so the token overrides the configuration.
                       //HLT needs it such that even if a service isn't created we store its PSet if needed
                       if(itFound->second.maker_->saveConfiguration()) {
                         itFound->second.pset_->addUntrackedParameter("@save_config", true);
                       }
                       std::string type;
                       typeDemangle(itType->name(), type);
                       LogInfo("Configuration") << "Warning: You have reconfigured service\n"
                                 <<  "'" << type << "' in a subprocess.\n"
                                 << "This service has already been configured.\n"
                                 << "This particular service may not be reconfigured in a subprocess.\n"
                                 << "The reconfiguration will be ignored.\n";
                       type2Maker_->erase(itFound);
                     } else {
                       // This is not a process wide service, so the configuration overrides the token.
                       type2Service_.erase(type2Service_.find(*itType));
                     }
                  }
                  break;
            }
            //make sure our signals are propagated to our 'inherited' Services
            if (associate) registry_.copySlotsFrom(associatedManager_->registry_);
         }
         createServices();
      }
ServicesManager::~ServicesManager ( )

Definition at line 176 of file ServicesManager.cc.

References actualCreationOrder_, and type2Service_.

                                        {
         // Force the Service destructors to execute in the reverse order of construction.
         // Note that services passed in by a token are not included in this loop and
         // do not get destroyed until the ServicesManager object that created them is destroyed
         // which occurs after the body of this destructor is executed (the correct order).
         // Services directly passed in by a put and not created in the constructor
         // may or not be detroyed in the desired order because this class does not control
         // their creation (as I'm writing this comment everything in a standard cmsRun
         // executable is destroyed in the desired order).
         for(std::vector<TypeIDBase>::const_reverse_iterator idIter = actualCreationOrder_.rbegin(),
                                                             idEnd = actualCreationOrder_.rend();
              idIter != idEnd;
              ++idIter) {

            Type2Service::iterator itService = type2Service_.find(*idIter);

            if(itService != type2Service_.end()) {

               // This will cause the Service's destruction if
               // there are no other shared pointers around
               itService->second.reset();
            }
         }
      }
edm::serviceregistry::ServicesManager::ServicesManager ( ServicesManager const &  ) [private]

Member Function Documentation

void ServicesManager::connect ( ActivityRegistry iOther)

causes our ActivityRegistry's signals to be forwarded to iOther

Definition at line 216 of file ServicesManager.cc.

References edm::ActivityRegistry::connect(), and registry_.

                                                       {
         registry_.connect(iOther);
      }
void ServicesManager::connectTo ( ActivityRegistry iOther)

causes iOther's signals to be forward to us

Definition at line 221 of file ServicesManager.cc.

References edm::ActivityRegistry::connect(), and registry_.

                                                         {
         iOther.connect(registry_);
      }
void ServicesManager::copySlotsFrom ( ActivityRegistry iOther)

the copy the argument's slots to the our signals

Definition at line 226 of file ServicesManager.cc.

References edm::ActivityRegistry::copySlotsFrom(), and registry_.

                                                             {
        registry_.copySlotsFrom(iOther);
      }
void ServicesManager::copySlotsTo ( ActivityRegistry iOther)

copy our Service's slots to the argument's signals

Definition at line 231 of file ServicesManager.cc.

References edm::ActivityRegistry::copySlotsFrom(), and registry_.

                                                           {
        iOther.copySlotsFrom(registry_);
      }
void ServicesManager::createServices ( ) [private]

Definition at line 272 of file ServicesManager.cc.

References cms::Exception::addContext(), edm::convertException::badAllocToEDM(), trackerHits::c, edm::convertException::charPtrToEDM(), SurfaceDeformationFactory::create(), alignCSCRings::e, exception, reco::get(), requestedCreationOrder_, alignCSCRings::s, edm::convertException::stdToEDM(), edm::convertException::stringToEDM(), type2Maker_, edm::convertException::unknownToEDM(), and edm::ConfigurationDescriptions::validate().

Referenced by ServicesManager().

                                      {

         //create a shared_ptr of 'this' that will not delete us
         boost::shared_ptr<ServicesManager> shareThis(this, NoOp());

         ServiceToken token(shareThis);

         //Now make our services to ones obtained via ServiceRegistry
         // when this goes out of scope, it will revert back to the previous Service set
         ServiceRegistry::Operate operate(token);

         //Now, make each Service.  If a service depends on a service that has yet to be
         // created, that other service will automatically be made

         for(std::vector<TypeIDBase>::const_iterator idIter = requestedCreationOrder_.begin(),
                                                     idEnd = requestedCreationOrder_.end();
              idIter != idEnd;
              ++idIter) {
           Type2Maker::iterator itMaker = type2Maker_->find(*idIter);

           // Check to make sure this maker is still there.  They are deleted
           // sometimes and that is OK.
           if(itMaker != type2Maker_->end()) {

             std::string serviceType = itMaker->second.pset_->getParameter<std::string>("@service_type");
             std::auto_ptr<ParameterSetDescriptionFillerBase> filler(
               ParameterSetDescriptionFillerPluginFactory::get()->create(serviceType));
             ConfigurationDescriptions descriptions(filler->baseType());
             filler->fill(descriptions);

             try {
               try {
                 descriptions.validate(*(itMaker->second.pset_), serviceType);
               }
               catch (cms::Exception& e) { throw; }
               catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
               catch (std::exception& e) { convertException::stdToEDM(e); }
               catch(std::string& s) { convertException::stringToEDM(s); }
               catch(char const* c) { convertException::charPtrToEDM(c); }
               catch (...) { convertException::unknownToEDM(); }
             }
             catch (cms::Exception & iException) {
               std::ostringstream ost;
               ost << "Validating configuration of service of type " << serviceType;
               iException.addContext(ost.str());
               throw;
             }
             try {
               try {
                 // This creates the service
                 itMaker->second.add(*this);
               }
               catch (cms::Exception& e) { throw; }
               catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
               catch (std::exception& e) { convertException::stdToEDM(e); }
               catch(std::string& s) { convertException::stringToEDM(s); }
               catch(char const* c) { convertException::charPtrToEDM(c); }
               catch (...) { convertException::unknownToEDM(); }
             }
             catch (cms::Exception & iException) {
               std::ostringstream ost;
               ost << "Constructing service of type " << serviceType;
               iException.addContext(ost.str());
               throw;
             }
           }
         }
         //No longer need the makers
         type2Maker_.reset();
      }
void ServicesManager::fillListOfMakers ( std::vector< ParameterSet > &  iConfiguration) [private]

Definition at line 236 of file ServicesManager.cc.

References newFWLiteAna::base, edm::errors::Configuration, SurfaceDeformationFactory::create(), Exception, reco::get(), registry_, requestedCreationOrder_, and type2Maker_.

Referenced by ServicesManager().

                                                                               {
         for(std::vector<ParameterSet>::iterator itParam = iConfiguration.begin(),
              itParamEnd = iConfiguration.end();
              itParam != itParamEnd;
              ++itParam) {
            boost::shared_ptr<ServiceMakerBase> base(ServicePluginFactory::get()->create(itParam->getParameter<std::string>("@service_type")));

            if(0 == base.get()) {
               throw Exception(errors::Configuration, "Service")
               << "could not find a service named "
               << itParam->getParameter<std::string>("@service_type")
               << ". Please check spelling.";
            }
            Type2Maker::iterator itFound = type2Maker_->find(TypeIDBase(base->serviceType()));
            if(itFound != type2Maker_->end()) {
               throw Exception(errors::Configuration, "Service")
               << " the service " << itParam->getParameter<std::string>("@service_type")
               << " provides the same service as "
               << itFound->second.pset_->getParameter<std::string>("@service_type")
               << "\n Please reconfigure job to only use one of these services.";
            }
            type2Maker_->insert(Type2Maker::value_type(TypeIDBase(base->serviceType()),
                                                        MakerHolder(base,
                                                                    *itParam,
                                                                    registry_)));
            requestedCreationOrder_.push_back(TypeIDBase(base->serviceType()));
         }
      }
template<typename T >
T& edm::serviceregistry::ServicesManager::get ( void  ) const [inline]

Definition at line 73 of file ServicesManager.h.

References mergeVDriftHistosByStation::name, edm::errors::NotFound, edm::Exception::throwThis(), type2Maker_, and type2Service_.

                        {
            Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
            Type2Maker::const_iterator itFoundMaker ;
            if(itFound == type2Service_.end()) {
               //do on demand building of the service
               if(0 == type2Maker_.get() ||
                   type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
                      Exception::throwThis(errors::NotFound,
                        "Service Request unable to find requested service with compiler type name '",
                        typeid(T).name(),
                        "'.\n");
               } else {
                  itFoundMaker->second.add(const_cast<ServicesManager&>(*this));
                  itFound = type2Service_.find(TypeIDBase(typeid(T)));
                  //the 'add()' should have put the service into the list
                  assert(itFound != type2Service_.end());
               }
            }
            //convert it to its actual type
            boost::shared_ptr<ServiceWrapper<T> > ptr(boost::dynamic_pointer_cast<ServiceWrapper<T> >(itFound->second));
            assert(0 != ptr.get());
            return ptr->get();
         }
template<typename T >
bool edm::serviceregistry::ServicesManager::isAvailable ( ) const [inline]

returns true of the particular service is accessible

Definition at line 99 of file ServicesManager.h.

References type2Maker_, and type2Service_.

                                  {
            Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
            Type2Maker::const_iterator itFoundMaker ;
            if(itFound == type2Service_.end()) {
               //do on demand building of the service
               if(0 == type2Maker_.get() ||
                   type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
                  return false;
               } else {
                  //Actually create the service in order to 'flush out' any
                  // configuration errors for the service
                  itFoundMaker->second.add(const_cast<ServicesManager&>(*this));
                  itFound = type2Service_.find(TypeIDBase(typeid(T)));
                  //the 'add()' should have put the service into the list
                  assert(itFound != type2Service_.end());
               }
            }
            return true;
         }
ServicesManager const& edm::serviceregistry::ServicesManager::operator= ( ServicesManager const &  ) [private]
template<typename T >
bool edm::serviceregistry::ServicesManager::put ( boost::shared_ptr< ServiceWrapper< T > >  iPtr) [inline]

returns false if put fails because a service of this type already exists

Definition at line 124 of file ServicesManager.h.

References actualCreationOrder_, and type2Service_.

Referenced by edm::serviceregistry::ServiceMaker< T, TMaker >::make().

                                                            {
            Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
            if(itFound != type2Service_.end()) {
               return false;
            }
            type2Service_[ TypeIDBase(typeid(T)) ] = iPtr;
            actualCreationOrder_.push_back(TypeIDBase(typeid(T)));
            return true;
         }

Member Data Documentation

Definition at line 164 of file ServicesManager.h.

Referenced by put(), and ~ServicesManager().

Definition at line 158 of file ServicesManager.h.

Referenced by ServicesManager().

Definition at line 163 of file ServicesManager.h.

Referenced by createServices(), and fillListOfMakers().

Definition at line 161 of file ServicesManager.h.

Referenced by get(), isAvailable(), put(), ServicesManager(), and ~ServicesManager().