Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-14 11:45:05

0001 #ifndef FWCore_Framework_DataProxyTemplate_h
0002 #define FWCore_Framework_DataProxyTemplate_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Framework
0006 // Class  :     DataProxyTemplate
0007 //
0008 /**\class DataProxyTemplate DataProxyTemplate.h FWCore/Framework/interface/DataProxyTemplate.h
0009 
0010  Description: A DataProxy base class which allows one to write type-safe proxies
0011 
0012               Note that DataProxy types that inherit from this are not allowed
0013               to get data from the EventSetup (they cannot consume anything).
0014               This is intended mainly for use with ESSources that are also
0015               not allowed to get data from the EventSetup. Currently (as of
0016               April 2019), this class is used only in PoolDBESSource and
0017               Framework unit tests.
0018 
0019               This is also not used with ESProducers that inherit from
0020               the ESProducer base class and use the setWhatProduced interface.
0021               This class is used instead of CallProxy.
0022 
0023  Usage:
0024     <usage>
0025 */
0026 //
0027 // Author:      Chris Jones
0028 // Created:     Thu Mar 31 12:45:32 EST 2005
0029 //
0030 
0031 // system include files
0032 
0033 // user include files
0034 #include "FWCore/Framework/interface/DataProxy.h"
0035 #include "FWCore/Framework/interface/EventSetupRecord.h"
0036 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0037 #include "FWCore/ServiceRegistry/interface/ESParentContext.h"
0038 #include "FWCore/Concurrency/interface/WaitingTaskList.h"
0039 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0040 #include <cassert>
0041 #include <limits>
0042 #include <atomic>
0043 
0044 // forward declarations
0045 
0046 namespace edm {
0047 
0048   class EventSetupImpl;
0049 
0050   namespace eventsetup {
0051 
0052     template <class RecordT, class DataT>
0053     class DataProxyTemplate : public DataProxy {
0054     public:
0055       typedef DataT value_type;
0056       typedef RecordT record_type;
0057 
0058       DataProxyTemplate() {}
0059 
0060       void prefetchAsyncImpl(WaitingTaskHolder iTask,
0061                              const EventSetupRecordImpl& iRecord,
0062                              const DataKey& iKey,
0063                              EventSetupImpl const* iEventSetupImpl,
0064                              edm::ServiceToken const& iToken,
0065                              edm::ESParentContext const& iParent) override {
0066         assert(iRecord.key() == RecordT::keyForClass());
0067         bool expected = false;
0068         bool doPrefetch = prefetching_.compare_exchange_strong(expected, true);
0069         taskList_.add(iTask);
0070 
0071         if (doPrefetch) {
0072           iTask.group()->run([this, &iRecord, iKey, iEventSetupImpl, iToken, iParent]() {
0073             try {
0074               RecordT rec;
0075               rec.setImpl(&iRecord, std::numeric_limits<unsigned int>::max(), nullptr, iEventSetupImpl, &iParent);
0076               ServiceRegistry::Operate operate(iToken);
0077               this->make(rec, iKey);
0078             } catch (...) {
0079               this->taskList_.doneWaiting(std::current_exception());
0080               return;
0081             }
0082             this->taskList_.doneWaiting(std::exception_ptr{});
0083           });
0084         }
0085       }
0086 
0087     protected:
0088       void invalidateCache() override {
0089         taskList_.reset();
0090         prefetching_ = false;
0091       }
0092 
0093       virtual const DataT* make(const RecordT&, const DataKey&) = 0;
0094 
0095     private:
0096       WaitingTaskList taskList_;
0097       std::atomic<bool> prefetching_{false};
0098     };
0099 
0100   }  // namespace eventsetup
0101 }  // namespace edm
0102 #endif