1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
#ifndef ServiceRegistry_ServicesManager_h
#define ServiceRegistry_ServicesManager_h
// -*- C++ -*-
//
// Package: ServiceRegistry
// Class : ServicesManager
//
/**\class ServicesManager ServicesManager.h FWCore/ServiceRegistry/interface/ServicesManager.h
Description: <one line class summary>
Usage:
<usage>
*/
//
// Original Author: Chris Jones
// Created: Mon Sep 5 13:33:01 EDT 2005
//
// user include files
#include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
#include "FWCore/ServiceRegistry/interface/ServiceLegacy.h"
#include "FWCore/ServiceRegistry/interface/ServiceMakerBase.h"
#include "FWCore/ServiceRegistry/interface/ServiceWrapper.h"
#include "FWCore/Utilities/interface/EDMException.h"
#include "FWCore/Utilities/interface/TypeDemangler.h"
#include "FWCore/Utilities/interface/TypeIDBase.h"
#include "FWCore/Utilities/interface/propagate_const.h"
#include "FWCore/Utilities/interface/thread_safety_macros.h"
// system include files
#include <memory>
#include <cassert>
#include <vector>
// forward declarations
namespace edm {
class ParameterSet;
class ServiceToken;
namespace serviceregistry {
class ServicesManager {
public:
struct MakerHolder {
MakerHolder(std::shared_ptr<ServiceMakerBase> iMaker, ParameterSet& iPSet, ActivityRegistry&);
bool add(ServicesManager&) const;
edm::propagate_const<std::shared_ptr<ServiceMakerBase>> maker_;
ParameterSet* pset_;
ActivityRegistry* registry_; // We do not use propagate_const because the registry itself is mutable
//Services construction is not allowed to occur across threads
CMS_SA_ALLOW mutable bool wasAdded_;
};
typedef std::map<TypeIDBase, std::shared_ptr<ServiceWrapperBase>> Type2Service;
typedef std::map<TypeIDBase, MakerHolder> Type2Maker;
ServicesManager(std::vector<ParameterSet>& iConfiguration);
/** Takes the services described by iToken and places them into the manager.
Conflicts over Services provided by both the iToken and iConfiguration
are resolved based on the value of iLegacy
*/
ServicesManager(ServiceToken iToken,
ServiceLegacy iLegacy,
std::vector<ParameterSet>& iConfiguration,
bool associate = true);
ServicesManager(ServicesManager const&) = delete; // stop default
ServicesManager const& operator=(ServicesManager const&) = delete; // stop default
~ServicesManager();
// ---------- const member functions ---------------------
template <typename T>
T& get() const {
Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
Type2Maker::const_iterator itFoundMaker;
if (itFound == type2Service_.end()) {
//do on demand building of the service
if (nullptr == type2Maker_.get() ||
type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
auto demangled = typeDemangle(typeid(T).name());
Exception::throwThis(errors::NotFound,
"Service Request unable to find requested service with C++ type '",
demangled.c_str(),
"'.\n");
} else {
const_cast<ServicesManager&>(*this).createServiceFor(itFoundMaker->second);
itFound = type2Service_.find(TypeIDBase(typeid(T)));
//the 'add()' should have put the service into the list
assert(itFound != type2Service_.end());
}
}
//convert it to its actual type
std::shared_ptr<ServiceWrapper<T>> ptr(std::dynamic_pointer_cast<ServiceWrapper<T>>(itFound->second));
assert(nullptr != ptr.get());
return ptr->get();
}
///returns true of the particular service is accessible
template <typename T>
bool isAvailable() const {
Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
Type2Maker::const_iterator itFoundMaker;
if (itFound == type2Service_.end()) {
//do on demand building of the service
if (nullptr == type2Maker_.get() ||
type2Maker_->end() == (itFoundMaker = type2Maker_->find(TypeIDBase(typeid(T))))) {
return false;
} else {
//Actually create the service in order to 'flush out' any
// configuration errors for the service
const_cast<ServicesManager&>(*this).createServiceFor(itFoundMaker->second);
itFound = type2Service_.find(TypeIDBase(typeid(T)));
//the 'add()' should have put the service into the list
assert(itFound != type2Service_.end());
}
}
return true;
}
// ---------- static member functions --------------------
// ---------- member functions ---------------------------
///returns false if put fails because a service of this type already exists
template <typename T>
bool put(std::shared_ptr<ServiceWrapper<T>> iPtr, bool iOverride = false) {
Type2Service::const_iterator itFound = type2Service_.find(TypeIDBase(typeid(T)));
if (itFound != type2Service_.end() and not iOverride) {
return false;
}
type2Service_[TypeIDBase(typeid(T))] = iPtr;
actualCreationOrder_.push_back(TypeIDBase(typeid(T)));
return true;
}
///causes our ActivityRegistry's signals to be forwarded to iOther
void connect(ActivityRegistry& iOther);
///causes iOther's signals to be forward to us
void connectTo(ActivityRegistry& iOther);
///copy our Service's slots to the argument's signals
void copySlotsTo(ActivityRegistry&);
///the copy the argument's slots to the our signals
void copySlotsFrom(ActivityRegistry&);
private:
void fillListOfMakers(std::vector<ParameterSet>&);
void createServices();
void createServiceFor(MakerHolder const&);
// ---------- member data --------------------------------
//hold onto the Manager passed in from the ServiceToken so that
// the ActivityRegistry of that Manager does not go out of scope
// This must be first to get the Service destructors called in
// the correct order.
edm::propagate_const<std::shared_ptr<ServicesManager>> associatedManager_;
ActivityRegistry registry_;
Type2Service type2Service_;
edm::propagate_const<std::unique_ptr<Type2Maker>> type2Maker_;
std::vector<TypeIDBase> requestedCreationOrder_;
std::vector<TypeIDBase> actualCreationOrder_;
};
} // namespace serviceregistry
} // namespace edm
#endif
|