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