Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015
00016 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00018 #include "FWCore/ParameterSet/interface/ParameterSetDescriptionFillerBase.h"
00019 #include "FWCore/ParameterSet/interface/ParameterSetDescriptionFillerPluginFactory.h"
00020
00021 #include "FWCore/ServiceRegistry/interface/ServicePluginFactory.h"
00022 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
00023 #include "FWCore/ServiceRegistry/interface/ServiceToken.h"
00024 #include "FWCore/ServiceRegistry/interface/ServicesManager.h"
00025
00026 #include "FWCore/Utilities/interface/ConvertException.h"
00027 #include "FWCore/Utilities/interface/Exception.h"
00028 #include "FWCore/Utilities/interface/TypeDemangler.h"
00029
00030
00031 #include <set>
00032 #include <string>
00033 #include <exception>
00034 #include <sstream>
00035
00036
00037
00038
00039
00040 namespace edm {
00041 namespace serviceregistry {
00042
00043 ServicesManager::MakerHolder::MakerHolder(boost::shared_ptr<ServiceMakerBase> iMaker,
00044 ParameterSet& iPSet,
00045 ActivityRegistry& iRegistry) :
00046 maker_(iMaker),
00047 pset_(&iPSet),
00048 registry_(&iRegistry),
00049 wasAdded_(false) {}
00050
00051 bool
00052 ServicesManager::MakerHolder::add(ServicesManager& oManager) const {
00053 if(!wasAdded_) {
00054 wasAdded_ = maker_->make(*pset_, *registry_, oManager);
00055 if(wasAdded_ && maker_->saveConfiguration()) {
00056 pset_->addUntrackedParameter("@save_config", true);
00057 }
00058 }
00059 return wasAdded_;
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069 ServicesManager::ServicesManager(std::vector<ParameterSet>& iConfiguration) :
00070 type2Maker_(new Type2Maker) {
00071
00072 fillListOfMakers(iConfiguration);
00073
00074 createServices();
00075 }
00076
00077 ServicesManager::ServicesManager(ServiceToken iToken,
00078 ServiceLegacy iLegacy,
00079 std::vector<ParameterSet>& iConfiguration,
00080 bool associate) :
00081 associatedManager_(associate ? iToken.manager_ : boost::shared_ptr<ServicesManager>()),
00082 type2Maker_(new Type2Maker) {
00083 fillListOfMakers(iConfiguration);
00084
00085
00086 typedef std::set< TypeIDBase> TypeSet;
00087 TypeSet configTypes;
00088 for(Type2Maker::iterator itType = type2Maker_->begin(), itTypeEnd = type2Maker_->end();
00089 itType != itTypeEnd;
00090 ++itType) {
00091 configTypes.insert(itType->first);
00092 }
00093
00094 TypeSet tokenTypes;
00095 if(0 != iToken.manager_.get()) {
00096 for(Type2Service::iterator itType = iToken.manager_->type2Service_.begin(),
00097 itTypeEnd = iToken.manager_->type2Service_.end();
00098 itType != itTypeEnd;
00099 ++itType) {
00100 tokenTypes.insert(itType->first);
00101 }
00102
00103 typedef std::set<TypeIDBase> IntersectionType;
00104 IntersectionType intersection;
00105 std::set_intersection(configTypes.begin(), configTypes.end(),
00106 tokenTypes.begin(), tokenTypes.end(),
00107 inserter(intersection, intersection.end()));
00108
00109 switch(iLegacy) {
00110 case kOverlapIsError :
00111 if(!intersection.empty()) {
00112 throw Exception(errors::Configuration, "Service")
00113 << "the Service " << (*type2Maker_).find(*(intersection.begin()))->second.pset_->getParameter<std::string>("@service_type")
00114 << " already has an instance of that type of Service";
00115 } else {
00116
00117 type2Service_ = iToken.manager_->type2Service_;
00118 }
00119 break;
00120 case kTokenOverrides :
00121
00122 type2Service_ = iToken.manager_->type2Service_;
00123
00124
00125 for(IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
00126 itType != itTypeEnd;
00127 ++itType) {
00128 Type2Maker::iterator itFound = type2Maker_->find(*itType);
00129
00130 if(itFound->second.maker_->saveConfiguration()) {
00131 itFound->second.pset_->addUntrackedParameter("@save_config", true);
00132 }
00133 type2Maker_->erase(itFound);
00134 }
00135 break;
00136 case kConfigurationOverrides:
00137
00138 type2Service_ = iToken.manager_->type2Service_;
00139
00140
00141 for(IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
00142 itType != itTypeEnd;
00143 ++itType) {
00144 Type2Maker::iterator itFound = type2Maker_->find(*itType);
00145 if(itFound->second.maker_->processWideService()) {
00146
00147
00148 if(itFound->second.maker_->saveConfiguration()) {
00149 itFound->second.pset_->addUntrackedParameter("@save_config", true);
00150 }
00151 std::string type(typeDemangle(itType->name()));
00152 LogInfo("Configuration") << "Warning: You have reconfigured service\n"
00153 << "'" << type << "' in a subprocess.\n"
00154 << "This service has already been configured.\n"
00155 << "This particular service may not be reconfigured in a subprocess.\n"
00156 << "The reconfiguration will be ignored.\n";
00157 type2Maker_->erase(itFound);
00158 } else {
00159
00160 type2Service_.erase(type2Service_.find(*itType));
00161 }
00162 }
00163 break;
00164 }
00165
00166 if (associate) registry_.copySlotsFrom(associatedManager_->registry_);
00167 }
00168 createServices();
00169 }
00170
00171
00172
00173
00174
00175 ServicesManager::~ServicesManager() {
00176
00177
00178
00179
00180
00181
00182
00183
00184 for(std::vector<TypeIDBase>::const_reverse_iterator idIter = actualCreationOrder_.rbegin(),
00185 idEnd = actualCreationOrder_.rend();
00186 idIter != idEnd;
00187 ++idIter) {
00188
00189 Type2Service::iterator itService = type2Service_.find(*idIter);
00190
00191 if(itService != type2Service_.end()) {
00192
00193
00194
00195 itService->second.reset();
00196 }
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 void
00215 ServicesManager::connect(ActivityRegistry& iOther) {
00216 registry_.connect(iOther);
00217 }
00218
00219 void
00220 ServicesManager::connectTo(ActivityRegistry& iOther) {
00221 iOther.connect(registry_);
00222 }
00223
00224 void
00225 ServicesManager::copySlotsFrom(ActivityRegistry& iOther) {
00226 registry_.copySlotsFrom(iOther);
00227 }
00228
00229 void
00230 ServicesManager::copySlotsTo(ActivityRegistry& iOther) {
00231 iOther.copySlotsFrom(registry_);
00232 }
00233
00234 void
00235 ServicesManager::fillListOfMakers(std::vector<ParameterSet>& iConfiguration) {
00236 for(std::vector<ParameterSet>::iterator itParam = iConfiguration.begin(),
00237 itParamEnd = iConfiguration.end();
00238 itParam != itParamEnd;
00239 ++itParam) {
00240 boost::shared_ptr<ServiceMakerBase> base(ServicePluginFactory::get()->create(itParam->getParameter<std::string>("@service_type")));
00241
00242 if(0 == base.get()) {
00243 throw Exception(errors::Configuration, "Service")
00244 << "could not find a service named "
00245 << itParam->getParameter<std::string>("@service_type")
00246 << ". Please check spelling.";
00247 }
00248 Type2Maker::iterator itFound = type2Maker_->find(TypeIDBase(base->serviceType()));
00249 if(itFound != type2Maker_->end()) {
00250 throw Exception(errors::Configuration, "Service")
00251 << " the service " << itParam->getParameter<std::string>("@service_type")
00252 << " provides the same service as "
00253 << itFound->second.pset_->getParameter<std::string>("@service_type")
00254 << "\n Please reconfigure job to only use one of these services.";
00255 }
00256 type2Maker_->insert(Type2Maker::value_type(TypeIDBase(base->serviceType()),
00257 MakerHolder(base,
00258 *itParam,
00259 registry_)));
00260 requestedCreationOrder_.push_back(TypeIDBase(base->serviceType()));
00261 }
00262 }
00263
00264 namespace {
00265 struct NoOp {
00266 void operator()(ServicesManager*) {}
00267 };
00268 }
00269
00270 void
00271 ServicesManager::createServices() {
00272
00273
00274 boost::shared_ptr<ServicesManager> shareThis(this, NoOp());
00275
00276 ServiceToken token(shareThis);
00277
00278
00279
00280 ServiceRegistry::Operate operate(token);
00281
00282
00283
00284
00285 for(std::vector<TypeIDBase>::const_iterator idIter = requestedCreationOrder_.begin(),
00286 idEnd = requestedCreationOrder_.end();
00287 idIter != idEnd;
00288 ++idIter) {
00289 Type2Maker::iterator itMaker = type2Maker_->find(*idIter);
00290
00291
00292
00293 if(itMaker != type2Maker_->end()) {
00294
00295 std::string serviceType = itMaker->second.pset_->getParameter<std::string>("@service_type");
00296 std::auto_ptr<ParameterSetDescriptionFillerBase> filler(
00297 ParameterSetDescriptionFillerPluginFactory::get()->create(serviceType));
00298 ConfigurationDescriptions descriptions(filler->baseType());
00299 filler->fill(descriptions);
00300
00301 try {
00302 try {
00303 descriptions.validate(*(itMaker->second.pset_), serviceType);
00304 }
00305 catch (cms::Exception& e) { throw; }
00306 catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00307 catch (std::exception& e) { convertException::stdToEDM(e); }
00308 catch(std::string& s) { convertException::stringToEDM(s); }
00309 catch(char const* c) { convertException::charPtrToEDM(c); }
00310 catch (...) { convertException::unknownToEDM(); }
00311 }
00312 catch (cms::Exception & iException) {
00313 std::ostringstream ost;
00314 ost << "Validating configuration of service of type " << serviceType;
00315 iException.addContext(ost.str());
00316 throw;
00317 }
00318 try {
00319 try {
00320
00321 itMaker->second.add(*this);
00322 }
00323 catch (cms::Exception& e) { throw; }
00324 catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00325 catch (std::exception& e) { convertException::stdToEDM(e); }
00326 catch(std::string& s) { convertException::stringToEDM(s); }
00327 catch(char const* c) { convertException::charPtrToEDM(c); }
00328 catch (...) { convertException::unknownToEDM(); }
00329 }
00330 catch (cms::Exception & iException) {
00331 std::ostringstream ost;
00332 ost << "Constructing service of type " << serviceType;
00333 iException.addContext(ost.str());
00334 throw;
00335 }
00336 }
00337 }
00338
00339 type2Maker_.reset();
00340 }
00341
00342
00343
00344
00345
00346
00347
00348 }
00349 }