Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-24 09:53:02

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