Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-02-14 03:16:30

0001 // -*- C++ -*-
0002 #ifndef FWCore_Framework_ESProductResolver_h
0003 #define FWCore_Framework_ESProductResolver_h
0004 //
0005 // Package:     Framework
0006 // Class  :     ESProductResolver
0007 //
0008 /**\class edm::eventsetup::ESProductResolver
0009 
0010  Description: Base class for product resolvers held by a EventSetupRecord
0011 
0012  Usage:
0013     This class defines the interface used to handle retrieving data from an
0014  EventSetup Record.
0015 
0016 */
0017 //
0018 // Author:      Chris Jones
0019 // Created:     Thu Mar 31 12:43:01 EST 2005
0020 //
0021 
0022 // system include files
0023 #include <atomic>
0024 
0025 // user include files
0026 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0027 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0028 
0029 // forward declarations
0030 namespace edm {
0031   class EventSetupImpl;
0032   class ServiceToken;
0033   class ESParentContext;
0034 
0035   namespace eventsetup {
0036     struct ComponentDescription;
0037     class DataKey;
0038     class EventSetupRecordImpl;
0039 
0040     class ESProductResolver {
0041     public:
0042       ESProductResolver();
0043       ESProductResolver(ESProductResolver const&) = delete;
0044       ESProductResolver const& operator=(ESProductResolver const&) = delete;
0045       virtual ~ESProductResolver();
0046 
0047       // ---------- const member functions ---------------------
0048       bool cacheIsValid() const;
0049 
0050       void prefetchAsync(WaitingTaskHolder,
0051                          EventSetupRecordImpl const&,
0052                          DataKey const&,
0053                          EventSetupImpl const*,
0054                          ServiceToken const&,
0055                          ESParentContext const&) const noexcept;
0056 
0057       void const* getAfterPrefetch(const EventSetupRecordImpl& iRecord, const DataKey& iKey, bool iTransiently) const;
0058 
0059       ///returns the description of the ESProductResolverProvider which owns this Resolver
0060       ComponentDescription const* providerDescription() const { return description_; }
0061 
0062       // ---------- member functions ---------------------------
0063       void invalidate() {
0064         clearCacheIsValid();
0065         invalidateCache();
0066       }
0067 
0068       void resetIfTransient();
0069 
0070       void setProviderDescription(ComponentDescription const* iDesc) { description_ = iDesc; }
0071 
0072       virtual void initializeForNewIOV() {}
0073 
0074       // Counts setWhatProduced calls if creating module class derives from ESProducer.
0075       // Currently, all others cases always return 0 (CondDBESSource, unit tests...).
0076       virtual unsigned int produceMethodID() const;
0077 
0078     protected:
0079       /**This is the function which does the real work of getting the data if it is not
0080           already cached.  The returning 'void const*' must point to an instance of the class
0081           type corresponding to the type designated in iKey. So if iKey refers to a base class interface
0082           the pointer must be a pointer to that base class interface and not a pointer to an inheriting class
0083           instance.
0084           */
0085       virtual void prefetchAsyncImpl(WaitingTaskHolder,
0086                                      EventSetupRecordImpl const&,
0087                                      DataKey const& iKey,
0088                                      EventSetupImpl const*,
0089                                      ServiceToken const&,
0090                                      ESParentContext const&) noexcept = 0;
0091 
0092       /** indicates that the Resolver should invalidate any cached information
0093           as that information has 'expired' (i.e. we have moved to a new IOV)
0094           */
0095       virtual void invalidateCache() = 0;
0096 
0097       /** indicates that the Resolver should invalidate any cached information
0098           as that information was accessed transiently and therefore is not
0099           intended to be kept over the entire IOV.  Default is to call
0100           invalidateCache().
0101           */
0102       virtual void invalidateTransientCache();
0103 
0104       /** used to retrieve the data from the implementation. The data is then cached locally.
0105        */
0106       virtual void const* getAfterPrefetchImpl() const = 0;
0107 
0108       void clearCacheIsValid();
0109 
0110     private:
0111       // ---------- member data --------------------------------
0112       ComponentDescription const* description_;
0113       mutable std::atomic<void const*> cache_;
0114 
0115       // While implementing the set of code changes that enabled support
0116       // for concurrent IOVs, I have gone to some effort to maintain
0117       // the same behavior for this variable and the things that depend on
0118       // it. My thinking is that we are going to revisit this and make
0119       // changes in the not so distant future so that the transient feature
0120       // works again. Alternatively, we may go through and delete it and
0121       // everything related to it.
0122 
0123       // First comment is that there is only one context in which the value
0124       // in nonTransientAccessRequested_ is used. This is in the resetIfTransient
0125       // function. This function is only called immediately after invalidate
0126       // was called. Therefore the value is always false and condition in
0127       // resetIfTransient always evaluates true. So in the current code this
0128       // data member does nothing and has absolutely no purpose. We should
0129       // delete it and the associated code if we do not modify the code to
0130       // actually make use of the value stored sometime soon.
0131 
0132       // Currently, this usage occurs is when force cache clear
0133       // is called from EventProcessor at beginRun (which only happens
0134       // when a certain configuration parameter is set) and propagates down.
0135       // It is also used when the looper is trying to start a new loop and
0136       // calls resetRecordPlusDependentRecords. It is not currently used in
0137       // any other context.
0138       //
0139       // One other thing to note is that the virtual invalidateTransientCache
0140       // function is defined in this class to just call invalidateCache.
0141       // Outside of unit tests, the only thing that overrides this definition
0142       // is in CondCore/ESSources/interface/ESProductResolver.h. So in all other cases
0143       // the behavior is that invalidateCache is called twice sometimes
0144       // instead of just once. Possibly it is important that invalidateTransientCache
0145       // is called in the CondCore code. I don't know.
0146       mutable std::atomic<bool> nonTransientAccessRequested_;
0147     };
0148   }  // namespace eventsetup
0149 }  // namespace edm
0150 #endif