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
35 
36 namespace edm {
37  namespace eventsetup {
38  class EventSetupRecordImpl;
39 
40  // The default decorator that does nothing
41  template <typename TRecord>
43  void pre(const TRecord&) {}
44  void post(const TRecord&) {}
45  };
46 
47  template <typename T, //producer's type
48  typename TReturn, //return type of the producer's method
49  typename TRecord, //the record passed in as an argument
50  typename TDecorator //allows customization using pre/post calls
51  = CallbackSimpleDecorator<TRecord>>
52  class Callback {
53  public:
54  using method_type = TReturn (T ::*)(const TRecord&);
55 
56  Callback(T* iProd, method_type iMethod, unsigned int iID, const TDecorator& iDec = TDecorator())
57  : proxyData_{},
58  producer_(iProd),
59  method_(iMethod),
60  id_(iID),
62  decorator_(iDec) {}
63 
65 
66  Callback(const Callback&) = delete;
67  const Callback& operator=(const Callback&) = delete;
68 
70  EventSetupRecordImpl const* iRecord,
71  EventSetupImpl const* iEventSetupImpl,
72  ServiceToken const& token) {
73  bool expected = false;
74  auto doPrefetch = wasCalledForThisRecord_.compare_exchange_strong(expected, true);
75  taskList_.add(iTask);
76  if (doPrefetch) {
77  if UNLIKELY (producer_->hasMayConsumes()) {
78  //after prefetching need to do the mayGet
79  auto mayGetTask = edm::make_waiting_task(
80  tbb::task::allocate_root(), [this, iRecord, iEventSetupImpl, token](std::exception_ptr const* iExcept) {
81  if (iExcept) {
82  runProducerAsync(iExcept, iRecord, iEventSetupImpl, token);
83  return;
84  }
85  if (handleMayGet(iRecord, iEventSetupImpl)) {
86  auto runTask = edm::make_waiting_task(
87  tbb::task::allocate_root(),
88  [this, iRecord, iEventSetupImpl, token](std::exception_ptr const* iExcept) {
89  runProducerAsync(iExcept, iRecord, iEventSetupImpl, token);
90  });
91  prefetchNeededDataAsync(runTask, iEventSetupImpl, &((*postMayGetProxies_).front()), token);
92  } else {
93  runProducerAsync(iExcept, iRecord, iEventSetupImpl, token);
94  }
95  });
96 
97  //Get everything we can before knowing about the mayGets
98  prefetchNeededDataAsync(mayGetTask, iEventSetupImpl, getTokenIndices(), token);
99  } else {
101  tbb::task::allocate_root(), [this, iRecord, iEventSetupImpl, token](std::exception_ptr const* iExcept) {
102  runProducerAsync(iExcept, iRecord, iEventSetupImpl, token);
103  });
104  prefetchNeededDataAsync(task, iEventSetupImpl, getTokenIndices(), token);
105  }
106  }
107  }
108 
109  template <class DataT>
110  void holdOntoPointer(DataT* iData) {
112  }
113 
114  void storeReturnedValues(TReturn iReturn) {
116  setData<typename type::head_type, typename type::tail_type>(iReturn);
117  }
118 
119  template <class RemainingContainerT, class DataT, class ProductsT>
120  void setData(ProductsT& iProducts) {
121  DataT* temp = reinterpret_cast<DataT*>(proxyData_[produce::find_index<TReturn, DataT>::value]);
122  if (nullptr != temp) {
123  moveFromTo(iProducts, *temp);
124  }
125  if constexpr (not std::is_same_v<produce::Null, RemainingContainerT>) {
126  setData<typename RemainingContainerT::head_type, typename RemainingContainerT::tail_type>(iProducts);
127  }
128  }
130  wasCalledForThisRecord_ = false;
131  taskList_.reset();
132  }
133 
134  unsigned int transitionID() const { return id_; }
135  ESProxyIndex const* getTokenIndices() const { return producer_->getTokenIndices(id_); }
136 
137  private:
139  EventSetupImpl const* iImpl,
140  ESProxyIndex const* proxies,
141  edm::ServiceToken const& token) const {
143  auto recs = producer_->getTokenRecordIndices(id_);
144  auto n = producer_->numberOfTokenIndices(id_);
145  for (size_t i = 0; i != n; ++i) {
146  auto rec = iImpl->findImpl(recs[i]);
147  if (rec) {
148  rec->prefetchAsync(task, proxies[i], iImpl, token);
149  }
150  }
151  }
152 
153  bool handleMayGet(EventSetupRecordImpl const* iRecord, EventSetupImpl const* iEventSetupImpl) {
154  //Handle mayGets
155  TRecord rec;
156  rec.setImpl(iRecord, transitionID(), getTokenIndices(), iEventSetupImpl, true);
157  postMayGetProxies_ = producer_->updateFromMayConsumes(id_, rec);
158  return static_cast<bool>(postMayGetProxies_);
159  }
160 
161  void runProducerAsync(std::exception_ptr const* iExcept,
162  EventSetupRecordImpl const* iRecord,
163  EventSetupImpl const* iEventSetupImpl,
164  ServiceToken const& token) {
165  if (iExcept) {
166  //The cache held by the CallbackProxy was already set to invalid at the beginning of the IOV
167  taskList_.doneWaiting(*iExcept);
168  return;
169  }
170  producer_->queue().push([this, iRecord, iEventSetupImpl, token]() {
171  std::exception_ptr exceptPtr;
172  try {
173  convertException::wrap([this, iRecord, iEventSetupImpl, token] {
174  auto proxies = getTokenIndices();
175  if (postMayGetProxies_) {
176  proxies = &((*postMayGetProxies_).front());
177  }
178  TRecord rec;
179  rec.setImpl(iRecord, transitionID(), proxies, iEventSetupImpl, true);
181  decorator_.pre(rec);
183  decorator_.post(rec);
184  });
185  } catch (cms::Exception& iException) {
186  auto const& description = producer_->description();
187  std::ostringstream ost;
188  ost << "Running EventSetup component " << description.type_ << "/'" << description.label_;
189  iException.addContext(ost.str());
190  exceptPtr = std::current_exception();
191  }
192  taskList_.doneWaiting(exceptPtr);
193  });
194  }
195 
197  std::optional<std::vector<ESProxyIndex>> postMayGetProxies_;
201  // This transition id identifies which setWhatProduced call this Callback is associated with
202  const unsigned int id_;
203  std::atomic<bool> wasCalledForThisRecord_;
204  TDecorator decorator_;
205  };
206  } // namespace eventsetup
207 } // namespace edm
208 
209 #endif
edm::eventsetup::Callback::prefetchAsync
void prefetchAsync(WaitingTask *iTask, EventSetupRecordImpl const *iRecord, EventSetupImpl const *iEventSetupImpl, ServiceToken const &token)
Definition: Callback.h:69
edm::eventsetup::Callback::operator=
const Callback & operator=(const Callback &)=delete
edm::eventsetup::CallbackSimpleDecorator::pre
void pre(const TRecord &)
Definition: Callback.h:43
edm::EventSetupImpl::findImpl
eventsetup::EventSetupRecordImpl const * findImpl(const eventsetup::EventSetupRecordKey &) const
Definition: EventSetupImpl.cc:59
edm::eventsetup::produce::product_traits::type
T type
Definition: produce_helpers.h:58
edm::eventsetup::Callback::storeReturnedValues
void storeReturnedValues(TReturn iReturn)
Definition: Callback.h:114
mps_fire.i
i
Definition: mps_fire.py:428
edm::eventsetup::Callback::producer_
edm::propagate_const< T * > producer_
Definition: Callback.h:198
ServiceRegistry.h
dqmiodumpmetadata.n
n
Definition: dqmiodumpmetadata.py:28
cms::Exception::addContext
void addContext(std::string const &context)
Definition: Exception.cc:165
edm::eventsetup::Callback::newRecordComing
void newRecordComing()
Definition: Callback.h:129
propagate_const.h
edm::EventSetupImpl
Definition: EventSetupImpl.h:48
edm::eventsetup::Callback::holdOntoPointer
void holdOntoPointer(DataT *iData)
Definition: Callback.h:110
WaitingTaskHolder.h
edm::eventsetup::Callback::id_
const unsigned int id_
Definition: Callback.h:202
edm
HLT enums.
Definition: AlignableModifier.h:19
h
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
Definition: L1TUtmAlgorithmRcd.h:4
edmLumisInFiles.description
description
Definition: edmLumisInFiles.py:11
edm::WaitingTaskList::add
void add(WaitingTask *)
Adds task to the waiting list.
Definition: WaitingTaskList.cc:90
edm::eventsetup::Callback::handleMayGet
bool handleMayGet(EventSetupRecordImpl const *iRecord, EventSetupImpl const *iEventSetupImpl)
Definition: Callback.h:153
EventSetupImpl.h
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:54
ServiceToken.h
edm::eventsetup::CallbackSimpleDecorator::post
void post(const TRecord &)
Definition: Callback.h:44
edm::eventsetup::CallbackSimpleDecorator
Definition: Callback.h:42
groupFilesInBlocks.temp
list temp
Definition: groupFilesInBlocks.py:142
ESIndices.h
edm::eventsetup::Callback::transitionID
unsigned int transitionID() const
Definition: Callback.h:134
edm::eventsetup::Callback
Definition: Callback.h:52
edm::ESProxyIndex
Definition: ESIndices.h:30
edm::eventsetup::EventSetupRecordImpl::prefetchAsync
void prefetchAsync(WaitingTask *iTask, ESProxyIndex iProxyIndex, EventSetupImpl const *, ServiceToken const &) const
prefetch the data to setup for subsequent calls to getImplementation
Definition: EventSetupRecordImpl.cc:260
edm::WaitingTaskList::reset
void reset()
Resets access to the resource so that added tasks will wait.
Definition: WaitingTaskList.cc:52
edm::WaitingTaskList
Definition: WaitingTaskList.h:101
edm::eventsetup::Callback::decorator_
TDecorator decorator_
Definition: Callback.h:204
edm::ServiceToken
Definition: ServiceToken.h:40
UNLIKELY
#define UNLIKELY(x)
Definition: Likely.h:21
edm::propagate_const< T * >
edm::eventsetup::Callback::proxyData_
std::array< void *, produce::size< TReturn >::value > proxyData_
Definition: Callback.h:196
edm::convertException::wrap
auto wrap(F iFunc) -> decltype(iFunc())
Definition: ConvertException.h:19
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:170
ConvertException.h
edm::make_waiting_task
FunctorWaitingTask< F > * make_waiting_task(ALLOC &&iAlloc, F f)
Definition: WaitingTask.h:87
edm::eventsetup::Callback::Callback
Callback(T *iProd, method_type iMethod, unsigned int iID, const TDecorator &iDec=TDecorator())
Definition: Callback.h:56
edm::eventsetup::Callback::getTokenIndices
ESProxyIndex const * getTokenIndices() const
Definition: Callback.h:135
edm::eventsetup::EventSetupRecordImpl
Definition: EventSetupRecordImpl.h:76
edm::eventsetup::Callback::prefetchNeededDataAsync
void prefetchNeededDataAsync(WaitingTask *task, EventSetupImpl const *iImpl, ESProxyIndex const *proxies, edm::ServiceToken const &token) const
Definition: Callback.h:138
edm::eventsetup::Callback::taskList_
edm::WaitingTaskList taskList_
Definition: Callback.h:199
edm::eventsetup::Callback::wasCalledForThisRecord_
std::atomic< bool > wasCalledForThisRecord_
Definition: Callback.h:203
edm::WaitingTaskHolder
Definition: WaitingTaskHolder.h:30
edm::eventsetup::Callback::runProducerAsync
void runProducerAsync(std::exception_ptr const *iExcept, EventSetupRecordImpl const *iRecord, EventSetupImpl const *iEventSetupImpl, ServiceToken const &token)
Definition: Callback.h:161
type
type
Definition: SiPixelVCal_PayloadInspector.cc:37
edm::eventsetup::Callback::postMayGetProxies_
std::optional< std::vector< ESProxyIndex > > postMayGetProxies_
Definition: Callback.h:197
edm::eventsetup::Callback::setData
void setData(ProductsT &iProducts)
Definition: Callback.h:120
edm::eventsetup::produce::find_index
Definition: produce_helpers.h:117
produce_helpers.h
edm::WaitingTask
Definition: WaitingTask.h:36
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:200
WaitingTaskList.h
edm::eventsetup::Callback::clone
Callback * clone()
Definition: Callback.h:64
cms::Exception
Definition: Exception.h:70
edm::ServiceRegistry::Operate
Definition: ServiceRegistry.h:40
edm::eventsetup::moveFromTo
void moveFromTo(FromT &iFrom, ToT &iTo)
Definition: produce_helpers.h:33
unpackBuffers-CaloStage2.token
token
Definition: unpackBuffers-CaloStage2.py:318