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