Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:01:59

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