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;
00152 typeDemangle(itType->name(), type);
00153 LogInfo("Configuration") << "Warning: You have reconfigured service\n"
00154 << "'" << type << "' in a subprocess.\n"
00155 << "This service has already been configured.\n"
00156 << "This particular service may not be reconfigured in a subprocess.\n"
00157 << "The reconfiguration will be ignored.\n";
00158 type2Maker_->erase(itFound);
00159 } else {
00160
00161 type2Service_.erase(type2Service_.find(*itType));
00162 }
00163 }
00164 break;
00165 }
00166
00167 if (associate) registry_.copySlotsFrom(associatedManager_->registry_);
00168 }
00169 createServices();
00170 }
00171
00172
00173
00174
00175
00176 ServicesManager::~ServicesManager() {
00177
00178
00179
00180
00181
00182
00183
00184
00185 for(std::vector<TypeIDBase>::const_reverse_iterator idIter = actualCreationOrder_.rbegin(),
00186 idEnd = actualCreationOrder_.rend();
00187 idIter != idEnd;
00188 ++idIter) {
00189
00190 Type2Service::iterator itService = type2Service_.find(*idIter);
00191
00192 if(itService != type2Service_.end()) {
00193
00194
00195
00196 itService->second.reset();
00197 }
00198 }
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 void
00216 ServicesManager::connect(ActivityRegistry& iOther) {
00217 registry_.connect(iOther);
00218 }
00219
00220 void
00221 ServicesManager::connectTo(ActivityRegistry& iOther) {
00222 iOther.connect(registry_);
00223 }
00224
00225 void
00226 ServicesManager::copySlotsFrom(ActivityRegistry& iOther) {
00227 registry_.copySlotsFrom(iOther);
00228 }
00229
00230 void
00231 ServicesManager::copySlotsTo(ActivityRegistry& iOther) {
00232 iOther.copySlotsFrom(registry_);
00233 }
00234
00235 void
00236 ServicesManager::fillListOfMakers(std::vector<ParameterSet>& iConfiguration) {
00237 for(std::vector<ParameterSet>::iterator itParam = iConfiguration.begin(),
00238 itParamEnd = iConfiguration.end();
00239 itParam != itParamEnd;
00240 ++itParam) {
00241 boost::shared_ptr<ServiceMakerBase> base(ServicePluginFactory::get()->create(itParam->getParameter<std::string>("@service_type")));
00242
00243 if(0 == base.get()) {
00244 throw Exception(errors::Configuration, "Service")
00245 << "could not find a service named "
00246 << itParam->getParameter<std::string>("@service_type")
00247 << ". Please check spelling.";
00248 }
00249 Type2Maker::iterator itFound = type2Maker_->find(TypeIDBase(base->serviceType()));
00250 if(itFound != type2Maker_->end()) {
00251 throw Exception(errors::Configuration, "Service")
00252 << " the service " << itParam->getParameter<std::string>("@service_type")
00253 << " provides the same service as "
00254 << itFound->second.pset_->getParameter<std::string>("@service_type")
00255 << "\n Please reconfigure job to only use one of these services.";
00256 }
00257 type2Maker_->insert(Type2Maker::value_type(TypeIDBase(base->serviceType()),
00258 MakerHolder(base,
00259 *itParam,
00260 registry_)));
00261 requestedCreationOrder_.push_back(TypeIDBase(base->serviceType()));
00262 }
00263 }
00264
00265 namespace {
00266 struct NoOp {
00267 void operator()(ServicesManager*) {}
00268 };
00269 }
00270
00271 void
00272 ServicesManager::createServices() {
00273
00274
00275 boost::shared_ptr<ServicesManager> shareThis(this, NoOp());
00276
00277 ServiceToken token(shareThis);
00278
00279
00280
00281 ServiceRegistry::Operate operate(token);
00282
00283
00284
00285
00286 for(std::vector<TypeIDBase>::const_iterator idIter = requestedCreationOrder_.begin(),
00287 idEnd = requestedCreationOrder_.end();
00288 idIter != idEnd;
00289 ++idIter) {
00290 Type2Maker::iterator itMaker = type2Maker_->find(*idIter);
00291
00292
00293
00294 if(itMaker != type2Maker_->end()) {
00295
00296 std::string serviceType = itMaker->second.pset_->getParameter<std::string>("@service_type");
00297 std::auto_ptr<ParameterSetDescriptionFillerBase> filler(
00298 ParameterSetDescriptionFillerPluginFactory::get()->create(serviceType));
00299 ConfigurationDescriptions descriptions(filler->baseType());
00300 filler->fill(descriptions);
00301
00302 try {
00303 try {
00304 descriptions.validate(*(itMaker->second.pset_), serviceType);
00305 }
00306 catch (cms::Exception& e) { throw; }
00307 catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00308 catch (std::exception& e) { convertException::stdToEDM(e); }
00309 catch(std::string& s) { convertException::stringToEDM(s); }
00310 catch(char const* c) { convertException::charPtrToEDM(c); }
00311 catch (...) { convertException::unknownToEDM(); }
00312 }
00313 catch (cms::Exception & iException) {
00314 std::ostringstream ost;
00315 ost << "Validating configuration of service of type " << serviceType;
00316 iException.addContext(ost.str());
00317 throw;
00318 }
00319 try {
00320 try {
00321
00322 itMaker->second.add(*this);
00323 }
00324 catch (cms::Exception& e) { throw; }
00325 catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00326 catch (std::exception& e) { convertException::stdToEDM(e); }
00327 catch(std::string& s) { convertException::stringToEDM(s); }
00328 catch(char const* c) { convertException::charPtrToEDM(c); }
00329 catch (...) { convertException::unknownToEDM(); }
00330 }
00331 catch (cms::Exception & iException) {
00332 std::ostringstream ost;
00333 ost << "Constructing service of type " << serviceType;
00334 iException.addContext(ost.str());
00335 throw;
00336 }
00337 }
00338 }
00339
00340 type2Maker_.reset();
00341 }
00342
00343
00344
00345
00346
00347
00348
00349 }
00350 }