CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ServicesManager.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: ServiceRegistry
4 // Class : ServicesManager
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Mon Sep 5 13:33:19 EDT 2005
11 //
12 
13 // user include files
15 
20 
25 
29 
30 // system include files
31 #include <set>
32 #include <string>
33 #include <exception>
34 #include <sstream>
35 
36 //
37 // constants, enums and typedefs
38 //
39 
40 namespace edm {
41  namespace serviceregistry {
42 
43  ServicesManager::MakerHolder::MakerHolder(boost::shared_ptr<ServiceMakerBase> iMaker,
44  ParameterSet& iPSet,
45  ActivityRegistry& iRegistry) :
46  maker_(iMaker),
47  pset_(&iPSet),
48  registry_(&iRegistry),
49  wasAdded_(false) {}
50 
51  bool
53  if(!wasAdded_) {
54  wasAdded_ = maker_->make(*pset_, *registry_, oManager);
55  if(wasAdded_ && maker_->saveConfiguration()) {
56  pset_->addUntrackedParameter("@save_config", true);
57  }
58  }
59  return wasAdded_;
60  }
61 
62  //
63  // static data member definitions
64  //
65 
66  //
67  // constructors and destructor
68  //
69  ServicesManager::ServicesManager(std::vector<ParameterSet>& iConfiguration) :
70  type2Maker_(new Type2Maker) {
71  //First create the list of makers
72  fillListOfMakers(iConfiguration);
73 
75  }
76 
78  ServiceLegacy iLegacy,
79  std::vector<ParameterSet>& iConfiguration,
80  bool associate) :
81  associatedManager_(associate ? iToken.manager_ : boost::shared_ptr<ServicesManager>()),
82  type2Maker_(new Type2Maker) {
83  fillListOfMakers(iConfiguration);
84 
85  //find overlaps between services in iToken and iConfiguration
86  typedef std::set< TypeIDBase> TypeSet;
87  TypeSet configTypes;
88  for(Type2Maker::iterator itType = type2Maker_->begin(), itTypeEnd = type2Maker_->end();
89  itType != itTypeEnd;
90  ++itType) {
91  configTypes.insert(itType->first);
92  }
93 
94  TypeSet tokenTypes;
95  if(0 != iToken.manager_.get()) {
96  for(Type2Service::iterator itType = iToken.manager_->type2Service_.begin(),
97  itTypeEnd = iToken.manager_->type2Service_.end();
98  itType != itTypeEnd;
99  ++itType) {
100  tokenTypes.insert(itType->first);
101  }
102 
103  typedef std::set<TypeIDBase> IntersectionType;
104  IntersectionType intersection;
105  std::set_intersection(configTypes.begin(), configTypes.end(),
106  tokenTypes.begin(), tokenTypes.end(),
107  inserter(intersection, intersection.end()));
108 
109  switch(iLegacy) {
110  case kOverlapIsError :
111  if(!intersection.empty()) {
112  throw Exception(errors::Configuration, "Service")
113  << "the Service " << (*type2Maker_).find(*(intersection.begin()))->second.pset_->getParameter<std::string>("@service_type")
114  << " already has an instance of that type of Service";
115  } else {
116  //get all the services from Token
117  type2Service_ = iToken.manager_->type2Service_;
118  }
119  break;
120  case kTokenOverrides :
121  //get all the services from Token
122  type2Service_ = iToken.manager_->type2Service_;
123 
124  //remove from type2Maker the overlapping services so we never try to make them
125  for(IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
126  itType != itTypeEnd;
127  ++itType) {
128  Type2Maker::iterator itFound = type2Maker_->find(*itType);
129  //HLT needs it such that even if a service isn't created we store its PSet if needed
130  if(itFound->second.maker_->saveConfiguration()) {
131  itFound->second.pset_->addUntrackedParameter("@save_config", true);
132  }
133  type2Maker_->erase(itFound);
134  }
135  break;
137  //get all the services from the Configuration, except process wide services
138  type2Service_ = iToken.manager_->type2Service_;
139 
140  //now remove the ones we do not want
141  for(IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
142  itType != itTypeEnd;
143  ++itType) {
144  Type2Maker::iterator itFound = type2Maker_->find(*itType);
145  if(itFound->second.maker_->processWideService()) {
146  // This is a process wide service, so the token overrides the configuration.
147  //HLT needs it such that even if a service isn't created we store its PSet if needed
148  if(itFound->second.maker_->saveConfiguration()) {
149  itFound->second.pset_->addUntrackedParameter("@save_config", true);
150  }
151  std::string type;
152  typeDemangle(itType->name(), type);
153  LogInfo("Configuration") << "Warning: You have reconfigured service\n"
154  << "'" << type << "' in a subprocess.\n"
155  << "This service has already been configured.\n"
156  << "This particular service may not be reconfigured in a subprocess.\n"
157  << "The reconfiguration will be ignored.\n";
158  type2Maker_->erase(itFound);
159  } else {
160  // This is not a process wide service, so the configuration overrides the token.
161  type2Service_.erase(type2Service_.find(*itType));
162  }
163  }
164  break;
165  }
166  //make sure our signals are propagated to our 'inherited' Services
167  if (associate) registry_.copySlotsFrom(associatedManager_->registry_);
168  }
169  createServices();
170  }
171 
172  // ServicesManager::ServicesManager(ServicesManager const& rhs) {
173  // // do actual copying here;
174  // }
175 
177  // Force the Service destructors to execute in the reverse order of construction.
178  // Note that services passed in by a token are not included in this loop and
179  // do not get destroyed until the ServicesManager object that created them is destroyed
180  // which occurs after the body of this destructor is executed (the correct order).
181  // Services directly passed in by a put and not created in the constructor
182  // may or not be detroyed in the desired order because this class does not control
183  // their creation (as I'm writing this comment everything in a standard cmsRun
184  // executable is destroyed in the desired order).
185  for(std::vector<TypeIDBase>::const_reverse_iterator idIter = actualCreationOrder_.rbegin(),
186  idEnd = actualCreationOrder_.rend();
187  idIter != idEnd;
188  ++idIter) {
189 
190  Type2Service::iterator itService = type2Service_.find(*idIter);
191 
192  if(itService != type2Service_.end()) {
193 
194  // This will cause the Service's destruction if
195  // there are no other shared pointers around
196  itService->second.reset();
197  }
198  }
199  }
200 
201  //
202  // assignment operators
203  //
204  // ServicesManager const& ServicesManager::operator=(ServicesManager const& rhs) {
205  // //An exception safe implementation is
206  // ServicesManager temp(rhs);
207  // swap(rhs);
208  //
209  // return *this;
210  // }
211 
212  //
213  // member functions
214  //
215  void
217  registry_.connect(iOther);
218  }
219 
220  void
222  iOther.connect(registry_);
223  }
224 
225  void
227  registry_.copySlotsFrom(iOther);
228  }
229 
230  void
232  iOther.copySlotsFrom(registry_);
233  }
234 
235  void
236  ServicesManager::fillListOfMakers(std::vector<ParameterSet>& iConfiguration) {
237  for(std::vector<ParameterSet>::iterator itParam = iConfiguration.begin(),
238  itParamEnd = iConfiguration.end();
239  itParam != itParamEnd;
240  ++itParam) {
241  boost::shared_ptr<ServiceMakerBase> base(ServicePluginFactory::get()->create(itParam->getParameter<std::string>("@service_type")));
242 
243  if(0 == base.get()) {
244  throw Exception(errors::Configuration, "Service")
245  << "could not find a service named "
246  << itParam->getParameter<std::string>("@service_type")
247  << ". Please check spelling.";
248  }
249  Type2Maker::iterator itFound = type2Maker_->find(TypeIDBase(base->serviceType()));
250  if(itFound != type2Maker_->end()) {
251  throw Exception(errors::Configuration, "Service")
252  << " the service " << itParam->getParameter<std::string>("@service_type")
253  << " provides the same service as "
254  << itFound->second.pset_->getParameter<std::string>("@service_type")
255  << "\n Please reconfigure job to only use one of these services.";
256  }
257  type2Maker_->insert(Type2Maker::value_type(TypeIDBase(base->serviceType()),
258  MakerHolder(base,
259  *itParam,
260  registry_)));
261  requestedCreationOrder_.push_back(TypeIDBase(base->serviceType()));
262  }
263  }
264 
265  namespace {
266  struct NoOp {
267  void operator()(ServicesManager*) {}
268  };
269  }
270 
271  void
273 
274  //create a shared_ptr of 'this' that will not delete us
275  boost::shared_ptr<ServicesManager> shareThis(this, NoOp());
276 
277  ServiceToken token(shareThis);
278 
279  //Now make our services to ones obtained via ServiceRegistry
280  // when this goes out of scope, it will revert back to the previous Service set
282 
283  //Now, make each Service. If a service depends on a service that has yet to be
284  // created, that other service will automatically be made
285 
286  for(std::vector<TypeIDBase>::const_iterator idIter = requestedCreationOrder_.begin(),
287  idEnd = requestedCreationOrder_.end();
288  idIter != idEnd;
289  ++idIter) {
290  Type2Maker::iterator itMaker = type2Maker_->find(*idIter);
291 
292  // Check to make sure this maker is still there. They are deleted
293  // sometimes and that is OK.
294  if(itMaker != type2Maker_->end()) {
295 
296  std::string serviceType = itMaker->second.pset_->getParameter<std::string>("@service_type");
297  std::auto_ptr<ParameterSetDescriptionFillerBase> filler(
299  ConfigurationDescriptions descriptions(filler->baseType());
300  filler->fill(descriptions);
301 
302  try {
303  try {
304  descriptions.validate(*(itMaker->second.pset_), serviceType);
305  }
306  catch (cms::Exception& e) { throw; }
307  catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
308  catch (std::exception& e) { convertException::stdToEDM(e); }
309  catch(std::string& s) { convertException::stringToEDM(s); }
310  catch(char const* c) { convertException::charPtrToEDM(c); }
311  catch (...) { convertException::unknownToEDM(); }
312  }
313  catch (cms::Exception & iException) {
314  std::ostringstream ost;
315  ost << "Validating configuration of service of type " << serviceType;
316  iException.addContext(ost.str());
317  throw;
318  }
319  try {
320  try {
321  // This creates the service
322  itMaker->second.add(*this);
323  }
324  catch (cms::Exception& e) { throw; }
325  catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
326  catch (std::exception& e) { convertException::stdToEDM(e); }
327  catch(std::string& s) { convertException::stringToEDM(s); }
328  catch(char const* c) { convertException::charPtrToEDM(c); }
329  catch (...) { convertException::unknownToEDM(); }
330  }
331  catch (cms::Exception & iException) {
332  std::ostringstream ost;
333  ost << "Constructing service of type " << serviceType;
334  iException.addContext(ost.str());
335  throw;
336  }
337  }
338  }
339  //No longer need the makers
340  type2Maker_.reset();
341  }
342  //
343  // const member functions
344  //
345 
346  //
347  // static member functions
348  //
349  }
350 }
tuple base
Main Program
Definition: newFWLiteAna.py:92
type
Definition: HCALResponse.h:22
void fillListOfMakers(std::vector< ParameterSet > &)
void copySlotsTo(ActivityRegistry &)
copy our Service&#39;s slots to the argument&#39;s signals
std::map< TypeIDBase, MakerHolder > Type2Maker
void copySlotsFrom(ActivityRegistry &iOther)
std::auto_ptr< Type2Maker > type2Maker_
std::vector< TypeIDBase > actualCreationOrder_
void typeDemangle(char const *mangledName, std::string &demangledName)
void connectTo(ActivityRegistry &iOther)
causes iOther&#39;s signals to be forward to us
void stdToEDM(std::exception const &e)
boost::shared_ptr< edm::serviceregistry::ServicesManager > manager_
Definition: ServiceToken.h:71
Container::value_type value_type
MakerHolder(boost::shared_ptr< ServiceMakerBase > iMaker, ParameterSet &iPSet, ActivityRegistry &)
boost::shared_ptr< ServicesManager > associatedManager_
void charPtrToEDM(char const *c)
void stringToEDM(std::string &s)
void copySlotsFrom(ActivityRegistry &)
the copy the argument&#39;s slots to the our signals
std::vector< TypeIDBase > requestedCreationOrder_
void addContext(std::string const &context)
Definition: Exception.cc:227
ServicesManager(std::vector< ParameterSet > &iConfiguration)
void validate(ParameterSet &pset, std::string const &moduleLabel) const
void connect(ActivityRegistry &iOther)
causes our ActivityRegistry&#39;s signals to be forwarded to iOther
SurfaceDeformation * create(int type, const std::vector< double > &params)
T get(const Candidate &c)
Definition: component.h:56
void connect(ActivityRegistry &iOther)
forwards our signals to slots connected to iOther