Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-07 04:59:29

0001 // -*- C++ -*-
0002 #ifndef FWCore_Framework_ESSourceProductResolverBase_h
0003 #define FWCore_Framework_ESSourceProductResolverBase_h
0004 //
0005 // Package:     FWCore/Framework
0006 // Class  :     ESSourceProductResolverBase
0007 //
0008 /**\class edm::eventsetup::ESSourceProductResolverBase
0009 
0010  Description: Base class for ESProductResolvers for ESSources that can be specialized based on concurrency needs
0011 
0012  Usage:
0013     The ESSourceProductResolverBase provides the bases for ProductResolvers needed for ESSources.
0014     It allows customization of synchronization needs via the use of template parameters.
0015 
0016     NOTE: if inheriting classes override `void invalidateCache()` they must be sure to call this classes
0017     implementation as part of the call.
0018 
0019 */
0020 //
0021 // Original Author:  Chris Jones
0022 //         Created:  14/05/2020
0023 //
0024 
0025 // system include files
0026 #include <atomic>
0027 
0028 // user include files
0029 #include "FWCore/Framework/interface/ESProductResolver.h"
0030 #include "FWCore/Framework/interface/EventSetupRecordDetails.h"
0031 #include "FWCore/Concurrency/interface/WaitingTaskList.h"
0032 #include "FWCore/ServiceRegistry/interface/ESParentContext.h"
0033 
0034 // forward declarations
0035 
0036 namespace edm::eventsetup {
0037   class ESSourceProductResolverBase : public ESProductResolver {
0038   public:
0039     ESSourceProductResolverBase() : m_prefetching{false} {}
0040 
0041   protected:
0042     void invalidateCache() override {
0043       m_waitingList.reset();
0044       m_prefetching = false;
0045     }
0046     void invalidateTransientCache() override {}
0047 
0048     virtual void prefetch(edm::eventsetup::DataKey const& iKey, EventSetupRecordDetails) = 0;
0049 
0050     //Should call from prefetchAsyncImpl
0051     template <typename ASYNC, typename GUARD>
0052     void prefetchAsyncImplTemplate(ASYNC iAsync,
0053                                    GUARD iGuardFactory,
0054                                    edm::WaitingTaskHolder iTask,
0055                                    edm::eventsetup::EventSetupRecordImpl const& iRecord,
0056                                    edm::eventsetup::DataKey const& iKey,
0057                                    edm::ESParentContext const& iContext) noexcept {
0058       auto group = iTask.group();
0059       if (needToPrefetch(std::move(iTask))) {
0060         iAsync(*group, [this, iGuardFactory, &iRecord, iKey, iContext]() {
0061           try {
0062             guardPrefetch(iGuardFactory, iRecord, iKey, iContext);
0063             m_waitingList.doneWaiting(std::exception_ptr{});
0064           } catch (...) {
0065             m_waitingList.doneWaiting(std::current_exception());
0066           }
0067         });
0068       }
0069     }
0070 
0071   private:
0072     template <typename GUARD>
0073     void guardPrefetch(GUARD iGuardFactory,
0074                        edm::eventsetup::EventSetupRecordImpl const& iES,
0075                        edm::eventsetup::DataKey const& iKey,
0076                        edm::ESParentContext const& iContext) {
0077       [[maybe_unused]] auto guard = iGuardFactory();
0078       doPrefetchAndSignals(iES, iKey, iContext);
0079     }
0080 
0081     bool needToPrefetch(edm::WaitingTaskHolder iTask) noexcept;
0082 
0083     void doPrefetchAndSignals(edm::eventsetup::EventSetupRecordImpl const&,
0084                               edm::eventsetup::DataKey const& iKey,
0085                               edm::ESParentContext const&);
0086 
0087     // ---------- member data --------------------------------
0088 
0089     edm::WaitingTaskList m_waitingList;
0090     std::atomic<bool> m_prefetching;
0091   };
0092 }  // namespace edm::eventsetup
0093 #endif