CMS 3D CMS Logo

Callback.h
Go to the documentation of this file.
1 #ifndef FWCore_Framework_Callback_h
2 #define FWCore_Framework_Callback_h
3 // -*- C++ -*-
4 //
5 // Package: Framework
6 // Class : Callback
7 //
16 //
17 // Author: Chris Jones
18 // Created: Sun Apr 17 14:30:24 EDT 2005
19 //
20 
21 // system include files
22 #include <vector>
23 #include <type_traits>
24 #include <atomic>
25 // user include files
37 
38 namespace edm {
39  namespace eventsetup {
40  class EventSetupRecordImpl;
41 
42  // The default decorator that does nothing
43  template <typename TRecord>
45  void pre(const TRecord&) {}
46  void post(const TRecord&) {}
47  };
48 
49  template <typename T, //producer's type
50  typename TReturn, //return type of the producer's method
51  typename TRecord, //the record passed in as an argument
52  typename TDecorator //allows customization using pre/post calls
53  = CallbackSimpleDecorator<TRecord>>
54  class Callback {
55  public:
56  using method_type = TReturn (T ::*)(const TRecord&);
57 
58  Callback(T* iProd, method_type iMethod, unsigned int iID, const TDecorator& iDec = TDecorator())
59  : proxyData_{},
60  producer_(iProd),
61  callingContext_(&iProd->description()),
62  method_(iMethod),
63  id_(iID),
65  decorator_(iDec) {}
66 
68 
69  Callback(const Callback&) = delete;
70  const Callback& operator=(const Callback&) = delete;
71 
73  EventSetupRecordImpl const* iRecord,
74  EventSetupImpl const* iEventSetupImpl,
75  ServiceToken const& token,
76  ESParentContext const& iParent) {
77  bool expected = false;
78  auto doPrefetch = wasCalledForThisRecord_.compare_exchange_strong(expected, true);
79  taskList_.add(iTask);
80  auto group = iTask.group();
81  if (doPrefetch) {
84  if UNLIKELY (producer_->hasMayConsumes()) {
85  //after prefetching need to do the mayGet
86  ServiceWeakToken weakToken = token;
87  auto mayGetTask = edm::make_waiting_task(
88  [this, iRecord, iEventSetupImpl, weakToken, group](std::exception_ptr const* iExcept) {
89  if (iExcept) {
90  runProducerAsync(group, iExcept, iRecord, iEventSetupImpl, weakToken.lock());
91  return;
92  }
93  if (handleMayGet(iRecord, iEventSetupImpl)) {
94  auto runTask = edm::make_waiting_task(
95  [this, group, iRecord, iEventSetupImpl, weakToken](std::exception_ptr const* iExcept) {
96  runProducerAsync(group, iExcept, iRecord, iEventSetupImpl, weakToken.lock());
97  });
99  iEventSetupImpl,
100  &((*postMayGetProxies_).front()),
101  weakToken.lock());
102  } else {
103  runProducerAsync(group, iExcept, iRecord, iEventSetupImpl, weakToken.lock());
104  }
105  });
106 
107  //Get everything we can before knowing about the mayGets
108  prefetchNeededDataAsync(WaitingTaskHolder(*group, mayGetTask), iEventSetupImpl, getTokenIndices(), token);
109  } else {
110  ServiceWeakToken weakToken = token;
112  [this, group, iRecord, iEventSetupImpl, weakToken](std::exception_ptr const* iExcept) {
113  runProducerAsync(group, iExcept, iRecord, iEventSetupImpl, weakToken.lock());
114  });
116  }
117  }
118  }
119 
120  template <class DataT>
121  void holdOntoPointer(DataT* iData) {
123  }
124 
125  void storeReturnedValues(TReturn iReturn) {
127  setData<typename type::head_type, typename type::tail_type>(iReturn);
128  }
129 
130  template <class RemainingContainerT, class DataT, class ProductsT>
131  void setData(ProductsT& iProducts) {
132  DataT* temp = reinterpret_cast<DataT*>(proxyData_[produce::find_index<TReturn, DataT>::value]);
133  if (nullptr != temp) {
134  moveFromTo(iProducts, *temp);
135  }
136  if constexpr (not std::is_same_v<produce::Null, RemainingContainerT>) {
137  setData<typename RemainingContainerT::head_type, typename RemainingContainerT::tail_type>(iProducts);
138  }
139  }
141  wasCalledForThisRecord_ = false;
142  taskList_.reset();
143  }
144 
145  unsigned int transitionID() const { return id_; }
146  ESProxyIndex const* getTokenIndices() const { return producer_->getTokenIndices(id_); }
147 
148  private:
150  EventSetupImpl const* iImpl,
151  ESProxyIndex const* proxies,
152  edm::ServiceToken const& token) const {
153  auto recs = producer_->getTokenRecordIndices(id_);
154  auto n = producer_->numberOfTokenIndices(id_);
155  for (size_t i = 0; i != n; ++i) {
156  auto rec = iImpl->findImpl(recs[i]);
157  if (rec) {
158  rec->prefetchAsync(task, proxies[i], iImpl, token, edm::ESParentContext{&callingContext_});
159  }
160  }
161  }
162 
163  bool handleMayGet(EventSetupRecordImpl const* iRecord, EventSetupImpl const* iEventSetupImpl) {
164  //Handle mayGets
165  TRecord rec;
167  rec.setImpl(iRecord, transitionID(), getTokenIndices(), iEventSetupImpl, &pc, true);
168  postMayGetProxies_ = producer_->updateFromMayConsumes(id_, rec);
169  return static_cast<bool>(postMayGetProxies_);
170  }
171 
172  void runProducerAsync(tbb::task_group* iGroup,
173  std::exception_ptr const* iExcept,
174  EventSetupRecordImpl const* iRecord,
175  EventSetupImpl const* iEventSetupImpl,
176  ServiceToken const& token) {
177  if (iExcept) {
178  //The cache held by the CallbackProxy was already set to invalid at the beginning of the IOV
179  taskList_.doneWaiting(*iExcept);
180  return;
181  }
183  ServiceWeakToken weakToken = token;
184  producer_->queue().push(*iGroup, [this, iRecord, iEventSetupImpl, weakToken]() {
186  std::exception_ptr exceptPtr;
187  try {
188  convertException::wrap([this, iRecord, iEventSetupImpl, weakToken] {
189  auto proxies = getTokenIndices();
190  if (postMayGetProxies_) {
191  proxies = &((*postMayGetProxies_).front());
192  }
193  TRecord rec;
195  rec.setImpl(iRecord, transitionID(), proxies, iEventSetupImpl, &pc, true);
196  ServiceRegistry::Operate operate(weakToken.lock());
198  struct EndGuard {
199  EndGuard(EventSetupRecordImpl const* iRecord, ESModuleCallingContext const& iContext)
200  : record_{iRecord}, context_{iContext} {}
201  ~EndGuard() { record_->activityRegistry()->postESModuleSignal_.emit(record_->key(), context_); }
202  EventSetupRecordImpl const* record_;
203  ESModuleCallingContext const& context_;
204  };
205  EndGuard guard(iRecord, callingContext_);
206  decorator_.pre(rec);
208  decorator_.post(rec);
209  });
210  } catch (cms::Exception& iException) {
211  auto const& description = producer_->description();
212  std::ostringstream ost;
213  ost << "Running EventSetup component " << description.type_ << "/'" << description.label_;
214  iException.addContext(ost.str());
215  exceptPtr = std::current_exception();
216  }
217  taskList_.doneWaiting(exceptPtr);
218  });
219  }
220 
222  std::optional<std::vector<ESProxyIndex>> postMayGetProxies_;
227  // This transition id identifies which setWhatProduced call this Callback is associated with
228  const unsigned int id_;
229  std::atomic<bool> wasCalledForThisRecord_;
230  TDecorator decorator_;
231  };
232  } // namespace eventsetup
233 } // namespace edm
234 
235 #endif
edm::eventsetup::Callback::callingContext_
ESModuleCallingContext callingContext_
Definition: Callback.h:224
edm::eventsetup::Callback::operator=
const Callback & operator=(const Callback &)=delete
edm::eventsetup::CallbackSimpleDecorator::pre
void pre(const TRecord &)
Definition: Callback.h:45
edm::EventSetupImpl::findImpl
eventsetup::EventSetupRecordImpl const * findImpl(const eventsetup::EventSetupRecordKey &) const
Definition: EventSetupImpl.cc:60
edm::eventsetup::produce::product_traits::type
T type
Definition: produce_helpers.h:58
edm::ESModuleCallingContext
Definition: ESModuleCallingContext.h:27
edm::eventsetup::Callback::storeReturnedValues
void storeReturnedValues(TReturn iReturn)
Definition: Callback.h:125
mps_fire.i
i
Definition: mps_fire.py:428
edm::eventsetup::Callback::producer_
edm::propagate_const< T * > producer_
Definition: Callback.h:223
edm::eventsetup::Callback::prefetchNeededDataAsync
void prefetchNeededDataAsync(WaitingTaskHolder task, EventSetupImpl const *iImpl, ESProxyIndex const *proxies, edm::ServiceToken const &token) const
Definition: Callback.h:149
ServiceRegistry.h
edm::ActivityRegistry::preESModulePrefetchingSignal_
PreESModulePrefetching preESModulePrefetchingSignal_
Definition: ActivityRegistry.h:509
dqmiodumpmetadata.n
n
Definition: dqmiodumpmetadata.py:28
cms::Exception::addContext
void addContext(std::string const &context)
Definition: Exception.cc:165
edm::ServiceWeakToken
Definition: ServiceToken.h:86
edm::eventsetup::Callback::newRecordComing
void newRecordComing()
Definition: Callback.h:140
edm::signalslot::Signal::emit
void emit(Args &&... args) const
Definition: Signal.h:48
propagate_const.h
edm::EventSetupImpl
Definition: EventSetupImpl.h:49
edm::eventsetup::Callback::holdOntoPointer
void holdOntoPointer(DataT *iData)
Definition: Callback.h:121
WaitingTaskHolder.h
edm::eventsetup::Callback::id_
const unsigned int id_
Definition: Callback.h:228
edm
HLT enums.
Definition: AlignableModifier.h:19
edmLumisInFiles.description
description
Definition: edmLumisInFiles.py:11
edm::eventsetup::Callback::handleMayGet
bool handleMayGet(EventSetupRecordImpl const *iRecord, EventSetupImpl const *iEventSetupImpl)
Definition: Callback.h:163
EventSetupImpl.h
edm::ActivityRegistry::preESModuleSignal_
PreESModule preESModuleSignal_
Definition: ActivityRegistry.h:526
edm::propagate_const::get
constexpr element_type const * get() const
Definition: propagate_const.h:64
edm::eventsetup::Callback::method_type
TReturn(T ::*)(const TRecord &) method_type
Definition: Callback.h:56
ServiceToken.h
edm::eventsetup::CallbackSimpleDecorator::post
void post(const TRecord &)
Definition: Callback.h:46
edm::eventsetup::CallbackSimpleDecorator
Definition: Callback.h:44
groupFilesInBlocks.temp
list temp
Definition: groupFilesInBlocks.py:142
edm::eventsetup::EventSetupRecordImpl::prefetchAsync
void prefetchAsync(WaitingTaskHolder iTask, ESProxyIndex iProxyIndex, EventSetupImpl const *, ServiceToken const &, ESParentContext) const
prefetch the data to setup for subsequent calls to getImplementation
Definition: EventSetupRecordImpl.cc:265
ESIndices.h
edm::eventsetup::Callback::transitionID
unsigned int transitionID() const
Definition: Callback.h:145
edm::eventsetup::Callback
Definition: Callback.h:54
edm::ESProxyIndex
Definition: ESIndices.h:30
edm::WaitingTaskList::reset
void reset()
Resets access to the resource so that added tasks will wait.
Definition: WaitingTaskList.cc:53
edm::WaitingTaskList
Definition: WaitingTaskList.h:84
edm::eventsetup::Callback::decorator_
TDecorator decorator_
Definition: Callback.h:230
edm::ServiceToken
Definition: ServiceToken.h:42
UNLIKELY
#define UNLIKELY(x)
Definition: Likely.h:21
edm::eventsetup::Callback::prefetchAsync
void prefetchAsync(WaitingTaskHolder iTask, EventSetupRecordImpl const *iRecord, EventSetupImpl const *iEventSetupImpl, ServiceToken const &token, ESParentContext const &iParent)
Definition: Callback.h:72
edm::propagate_const< T * >
edm::eventsetup::Callback::proxyData_
std::array< void *, produce::size< TReturn >::value > proxyData_
Definition: Callback.h:221
edm::convertException::wrap
auto wrap(F iFunc) -> decltype(iFunc())
Definition: ConvertException.h:19
edm::ESModuleCallingContext::State::kPrefetching
TrackValidation_cff.task
task
Definition: TrackValidation_cff.py:252
edm::WaitingTaskList::doneWaiting
void doneWaiting(std::exception_ptr iPtr)
Signals that the resource is now available and tasks should be spawned.
Definition: WaitingTaskList.cc:212
ConvertException.h
edm::eventsetup::Callback::Callback
Callback(T *iProd, method_type iMethod, unsigned int iID, const TDecorator &iDec=TDecorator())
Definition: Callback.h:58
edm::eventsetup::Callback::getTokenIndices
ESProxyIndex const * getTokenIndices() const
Definition: Callback.h:146
edm::eventsetup::EventSetupRecordImpl::activityRegistry
ActivityRegistry const * activityRegistry() const noexcept
Definition: EventSetupRecordImpl.h:152
edm::eventsetup::EventSetupRecordImpl
Definition: EventSetupRecordImpl.h:77
edm::eventsetup::Callback::taskList_
edm::WaitingTaskList taskList_
Definition: Callback.h:225
edm::eventsetup::Callback::wasCalledForThisRecord_
std::atomic< bool > wasCalledForThisRecord_
Definition: Callback.h:229
edm::make_waiting_task
FunctorWaitingTask< F > * make_waiting_task(F f)
Definition: WaitingTask.h:101
ESParentContext.h
edm::eventsetup::EventSetupRecordImpl::key
EventSetupRecordKey const & key() const
Definition: EventSetupRecordImpl.h:107
edm::WaitingTaskHolder
Definition: WaitingTaskHolder.h:32
type
type
Definition: SiPixelVCal_PayloadInspector.cc:37
edm::eventsetup::Callback::runProducerAsync
void runProducerAsync(tbb::task_group *iGroup, std::exception_ptr const *iExcept, EventSetupRecordImpl const *iRecord, EventSetupImpl const *iEventSetupImpl, ServiceToken const &token)
Definition: Callback.h:172
edm::ActivityRegistry::postESModulePrefetchingSignal_
PostESModulePrefetching postESModulePrefetchingSignal_
Definition: ActivityRegistry.h:518
edm::eventsetup::Callback::postMayGetProxies_
std::optional< std::vector< ESProxyIndex > > postMayGetProxies_
Definition: Callback.h:222
edm::eventsetup::Callback::setData
void setData(ProductsT &iProducts)
Definition: Callback.h:131
edm::ServiceWeakToken::lock
ServiceToken lock() const
Definition: ServiceToken.h:101
edm::ESParentContext
Definition: ESParentContext.h:21
edm::eventsetup::produce::find_index
Definition: produce_helpers.h:117
edm::ESModuleCallingContext::setContext
void setContext(State state, ESParentContext const &parent)
Definition: ESModuleCallingContext.cc:18
produce_helpers.h
edm::WaitingTaskList::add
void add(tbb::task_group *, WaitingTask *)
Adds task to the waiting list.
Definition: WaitingTaskList.cc:125
edm::ESModuleCallingContext::setState
void setState(State state)
Definition: ESModuleCallingContext.h:45
T
long double T
Definition: Basic3DVectorLD.h:48
relativeConstraints.value
value
Definition: relativeConstraints.py:53
edm::eventsetup::Callback::method_
method_type method_
Definition: Callback.h:226
edm::ESModuleCallingContext::State::kRunning
WaitingTaskList.h
edm::eventsetup::Callback::clone
Callback * clone()
Definition: Callback.h:67
cms::Exception
Definition: Exception.h:70
edm::ServiceRegistry::Operate
Definition: ServiceRegistry.h:40
edm::WaitingTaskHolder::group
tbb::task_group * group() const noexcept
Definition: WaitingTaskHolder.h:77
edm::eventsetup::moveFromTo
void moveFromTo(FromT &iFrom, ToT &iTo)
Definition: produce_helpers.h:33
ESModuleCallingContext.h
watchdog.group
group
Definition: watchdog.py:82
unpackBuffers-CaloStage2.token
token
Definition: unpackBuffers-CaloStage2.py:316