00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <set>
00016
00017
00018 #include "FWCore/ServiceRegistry/interface/ServicesManager.h"
00019 #include "FWCore/ServiceRegistry/interface/ServicePluginFactory.h"
00020 #include "FWCore/ServiceRegistry/interface/ServiceToken.h"
00021 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
00022
00023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00024
00025 using namespace edm::serviceregistry;
00026
00027
00028
00029
00030 ServicesManager::MakerHolder::MakerHolder(boost::shared_ptr<ServiceMakerBase> iMaker,
00031 const edm::ParameterSet& iPSet,
00032 edm::ActivityRegistry& iRegistry) :
00033 maker_(iMaker),
00034 pset_(&iPSet),
00035 registry_(&iRegistry),
00036 wasAdded_(false)
00037 {}
00038
00039 bool
00040 ServicesManager::MakerHolder::add(ServicesManager& oManager) const
00041 {
00042 if(!wasAdded_) {
00043 return wasAdded_ = maker_->make(*pset_, *registry_, oManager);
00044 }
00045 return wasAdded_;
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055 ServicesManager::ServicesManager(const std::vector<edm::ParameterSet>& iConfiguration) :
00056 type2Maker_(new Type2Maker)
00057 {
00058
00059 fillListOfMakers(iConfiguration);
00060
00061 createServices();
00062 }
00063 ServicesManager::ServicesManager(ServiceToken iToken,
00064 ServiceLegacy iLegacy,
00065 const std::vector<edm::ParameterSet>& iConfiguration):
00066 associatedManager_(iToken.manager_),
00067 type2Maker_(new Type2Maker)
00068 {
00069 fillListOfMakers(iConfiguration);
00070
00071
00072 typedef std::set< TypeIDBase> TypeSet;
00073 TypeSet configTypes;
00074 for(Type2Maker::iterator itType = type2Maker_->begin(), itTypeEnd = type2Maker_->end();
00075 itType != itTypeEnd;
00076 ++itType) {
00077 configTypes.insert(itType->first);
00078 }
00079
00080 TypeSet tokenTypes;
00081 if(0 != associatedManager_.get()) {
00082 for(Type2Service::iterator itType = associatedManager_->type2Service_.begin(),
00083 itTypeEnd = associatedManager_->type2Service_.end();
00084 itType != itTypeEnd;
00085 ++itType) {
00086 tokenTypes.insert(itType->first);
00087 }
00088
00089 typedef std::set<TypeIDBase> IntersectionType;
00090 IntersectionType intersection;
00091 std::set_intersection(configTypes.begin(), configTypes.end(),
00092 tokenTypes.begin(), tokenTypes.end(),
00093 inserter(intersection, intersection.end()));
00094
00095 switch(iLegacy) {
00096 case kOverlapIsError :
00097 if(!intersection.empty()) {
00098 throw edm::Exception(errors::Configuration, "Service")
00099 <<"the Service "<<(*type2Maker_).find(*(intersection.begin()))->second.pset_->getParameter<std::string>("@service_type")
00100 <<" already has an instance of that type of Service";
00101 } else {
00102
00103 type2Service_ = associatedManager_->type2Service_;
00104 }
00105 break;
00106 case kTokenOverrides :
00107
00108 type2Service_ = associatedManager_->type2Service_;
00109
00110
00111 for(IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
00112 itType != itTypeEnd;
00113 ++itType) {
00114 type2Maker_->erase(type2Maker_->find(*itType));
00115 }
00116 break;
00117 case kConfigurationOverrides:
00118
00119 type2Service_ = associatedManager_->type2Service_;
00120
00121
00122 for(IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
00123 itType != itTypeEnd;
00124 ++itType) {
00125 type2Service_.erase(type2Service_.find(*itType));
00126 }
00127 break;
00128 }
00129
00130 registry_.copySlotsFrom(associatedManager_->registry_);
00131 }
00132 createServices();
00133 }
00134
00135
00136
00137
00138
00139
00140 ServicesManager::~ServicesManager()
00141 {
00142
00143
00144
00145
00146
00147
00148
00149
00150 for (std::vector<TypeIDBase>::const_reverse_iterator idIter = actualCreationOrder_.rbegin(),
00151 idEnd = actualCreationOrder_.rend();
00152 idIter != idEnd;
00153 ++idIter) {
00154
00155 Type2Service::iterator itService = type2Service_.find(*idIter);
00156
00157 if (itService != type2Service_.end()) {
00158
00159
00160
00161 itService->second.reset();
00162 }
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 void
00182 ServicesManager::connect(ActivityRegistry& iOther)
00183 {
00184 registry_.connect(iOther);
00185 }
00186
00187 void
00188 ServicesManager::connectTo(ActivityRegistry& iOther)
00189 {
00190 iOther.connect(registry_);
00191 }
00192
00193 void
00194 ServicesManager::copySlotsFrom(ActivityRegistry& iOther)
00195 {
00196 registry_.copySlotsFrom(iOther);
00197 }
00198
00199 void
00200 ServicesManager::copySlotsTo(ActivityRegistry& iOther)
00201 {
00202 iOther.copySlotsFrom(registry_);
00203 }
00204
00205
00206 void
00207 ServicesManager::fillListOfMakers(const std::vector<edm::ParameterSet>& iConfiguration)
00208 {
00209 for(std::vector<edm::ParameterSet>::const_iterator itParam = iConfiguration.begin(),
00210 itParamEnd = iConfiguration.end();
00211 itParam != itParamEnd;
00212 ++itParam) {
00213 boost::shared_ptr<ServiceMakerBase> base(
00214 ServicePluginFactory::get()->create(itParam->getParameter<std::string>("@service_type")));
00215
00216 if(0 == base.get()) {
00217 throw edm::Exception(edm::errors::Configuration, "Service")
00218 <<"could not find a service named "
00219 << itParam->getParameter<std::string>("@service_type")
00220 <<". Please check spelling.";
00221 }
00222 Type2Maker::iterator itFound = type2Maker_->find(TypeIDBase(base->serviceType()));
00223 if(itFound != type2Maker_->end()) {
00224 throw edm::Exception(edm::errors::Configuration,"Service")
00225 <<" the service "<< itParam->getParameter<std::string>("@service_type")
00226 <<" provides the same service as "
00227 << itFound->second.pset_->getParameter<std::string>("@service_type")
00228 <<"\n Please reconfigure job to only use one of these services.";
00229 }
00230 type2Maker_->insert(Type2Maker::value_type(TypeIDBase(base->serviceType()),
00231 MakerHolder(base,
00232 *itParam,
00233 registry_)));
00234 requestedCreationOrder_.push_back(TypeIDBase(base->serviceType()));
00235 }
00236
00237 }
00238
00239 namespace {
00240 struct NoOp {
00241 void operator()(ServicesManager*) {}
00242 };
00243 }
00244
00245 void
00246 ServicesManager::createServices()
00247 {
00248
00249
00250
00251 boost::shared_ptr<ServicesManager> shareThis(this, NoOp());
00252
00253 ServiceToken token(shareThis);
00254
00255
00256
00257 ServiceRegistry::Operate operate(token);
00258
00259
00260
00261
00262 for (std::vector<TypeIDBase>::const_iterator idIter = requestedCreationOrder_.begin(),
00263 idEnd = requestedCreationOrder_.end();
00264 idIter != idEnd;
00265 ++idIter) {
00266 Type2Maker::iterator itMaker = type2Maker_->find(*idIter);
00267
00268
00269
00270 if (itMaker != type2Maker_->end()) {
00271 try {
00272
00273 itMaker->second.add(*this);
00274 }
00275 catch(cms::Exception& iException) {
00276 edm::Exception toThrow(edm::errors::Configuration,"Error occured while creating ");
00277 toThrow<<itMaker->second.pset_->getParameter<std::string>("@service_type")<<"\n";
00278 toThrow.append(iException);
00279 throw toThrow;
00280 }
00281 }
00282 }
00283
00284
00285 type2Maker_.reset();
00286
00287 }
00288
00289
00290
00291
00292
00293
00294