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