Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-30 22:24:06

0001 // -*- C++ -*-
0002 #ifndef FWCore_Framework_EventSetupRecordImpl_h
0003 #define FWCore_Framework_EventSetupRecordImpl_h
0004 //
0005 // Package:     Framework
0006 // Class  :     EventSetupRecordImpl
0007 //
0008 /**\class edm::eventsetup::EventSetupRecordImpl
0009 
0010  Description: Base class for all Records in an EventSetup.  Holds data with the same lifetime.
0011 
0012  Usage:
0013 This class contains the Resolvers that make up a given Record.  It
0014 is designed to be reused time after time, rather than it being
0015 destroyed and a new one created every time a new Record is
0016 required.  Resolvers can only be added by the EventSetupRecordProvider class which
0017 uses the 'add' function to do this.
0018 
0019 When the set of  Resolvers for a Records changes, i.e. a
0020 ESProductResolverProvider is added of removed from the system, then the
0021 Resolvers in a Record need to be changed as appropriate.
0022 In this design it was decided the easiest way to achieve this was
0023 to erase all Resolvers in a Record.
0024 
0025 It is important for the management of the Records that each Record
0026 know the ValidityInterval that represents the time over which its data is valid.
0027 The ValidityInterval is set by its EventSetupRecordProvider using the
0028 'set' function.  This quantity can be recovered
0029 through the 'validityInterval' method.
0030 
0031 */
0032 //
0033 // Author:      Chris Jones
0034 // Created:     Fri Mar 25 14:38:35 EST 2005
0035 //
0036 
0037 // user include files
0038 #include "FWCore/Framework/interface/FunctorESHandleExceptionFactory.h"
0039 #include "FWCore/Framework/interface/DataKey.h"
0040 #include "FWCore/Framework/interface/ValidityInterval.h"
0041 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0042 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0043 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0044 #include "FWCore/Utilities/interface/propagate_const.h"
0045 #include "FWCore/Utilities/interface/ESIndices.h"
0046 
0047 // system include files
0048 #include <memory>
0049 #include <vector>
0050 #include <atomic>
0051 #include <cassert>
0052 
0053 // forward declarations
0054 namespace cms {
0055   class Exception;
0056 }  // namespace cms
0057 
0058 namespace edm {
0059 
0060   class ActivityRegistry;
0061   class ESHandleExceptionFactory;
0062   class EventSetupImpl;
0063   class ServiceToken;
0064   class ESParentContext;
0065 
0066   namespace eventsetup {
0067     struct ComponentDescription;
0068     class ESProductResolver;
0069 
0070     class EventSetupRecordImpl {
0071       friend class EventSetupRecord;
0072 
0073     public:
0074       EventSetupRecordImpl(const EventSetupRecordKey& iKey, ActivityRegistry const*, unsigned int iovIndex = 0);
0075       EventSetupRecordImpl(EventSetupRecordImpl const&) = delete;
0076       EventSetupRecordImpl const& operator=(EventSetupRecordImpl const&) = delete;
0077       EventSetupRecordImpl(EventSetupRecordImpl&&);
0078       EventSetupRecordImpl& operator=(EventSetupRecordImpl&&);
0079 
0080       ValidityInterval validityInterval() const;
0081 
0082       ///prefetch the data to setup for subsequent calls to getImplementation
0083       void prefetchAsync(WaitingTaskHolder iTask,
0084                          ESResolverIndex iResolverIndex,
0085                          EventSetupImpl const*,
0086                          ServiceToken const&,
0087                          ESParentContext) const noexcept;
0088 
0089       /**returns true only if someone has already requested data for this key
0090           and the data was retrieved
0091           */
0092       bool wasGotten(DataKey const& aKey) const;
0093 
0094       /**returns the ComponentDescription for the module which creates the data or 0
0095           if no module has been registered for the data. This does not cause the data to
0096           actually be constructed.
0097           */
0098       ComponentDescription const* providerDescription(DataKey const& aKey) const;
0099 
0100       EventSetupRecordKey const& key() const { return key_; }
0101 
0102       /**If you are caching data from the Record, you should also keep
0103           this number.  If this number changes then you know that
0104           the data you have cached is invalid. This is NOT true if
0105           if the validityInterval() hasn't changed since it is possible that
0106           the job has gone to a new Record and then come back to the
0107           previous SyncValue and your algorithm didn't see the intervening
0108           Record.
0109           The value of '0' will never be returned so you can use that to
0110           denote that you have not yet checked the value.
0111           */
0112       unsigned long long cacheIdentifier() const { return cacheIdentifier_; }
0113 
0114       unsigned int iovIndex() const { return iovIndex_; }
0115 
0116       ///keys for all registered data keys
0117       std::vector<DataKey> const& registeredDataKeys() const;
0118       ///there is a 1-to-1 correspondence between elements returned and the elements returned from fillRegisteredDataKey.
0119       std::vector<ComponentDescription const*> componentsForRegisteredDataKeys() const;
0120 
0121       std::vector<unsigned int> produceMethodIDsForRegisteredDataKeys() const;
0122 
0123       // The following member functions should only be used by EventSetupRecordProvider
0124       bool add(DataKey const& iKey, ESProductResolver* iResolver);
0125       void clearResolvers();
0126 
0127       ///Set the cache identifier and validity interval when starting a new IOV
0128       ///In addition, also notify the ESProductResolver's a new IOV is starting.
0129       ///(As a performance optimization, we only notify the ESProductResolver's if hasFinder
0130       ///is true. At the current time, the CondDBESSource ESProductResolver's are the only
0131       ///ones who need to know about this and they always have finders).
0132       void initializeForNewIOV(unsigned long long iCacheIdentifier, ValidityInterval const&, bool hasFinder);
0133 
0134       /**Set the validity interval in a thread safe way. This is used when the
0135          IOV is already in use and the end of the IOV needs to be updated but
0136          the start time stays the same. In this case a new IOV does not need
0137          to be started.
0138           */
0139       void setSafely(ValidityInterval const&) const;
0140 
0141       void getESProducers(std::vector<ComponentDescription const*>& esproducers) const;
0142 
0143       ESProductResolver const* find(DataKey const& aKey) const;
0144 
0145       ActivityRegistry const* activityRegistry() const noexcept { return activityRegistry_; }
0146 
0147       void addTraceInfoToCmsException(cms::Exception& iException,
0148                                       char const* iName,
0149                                       ComponentDescription const*,
0150                                       DataKey const&) const;
0151 
0152       void invalidateResolvers();
0153       void resetIfTransientInResolvers();
0154 
0155     private:
0156       void const* getFromResolverAfterPrefetch(ESResolverIndex iResolverIndex,
0157                                                bool iTransientAccessOnly,
0158                                                ComponentDescription const*& iDesc,
0159                                                DataKey const*& oGottenKey) const;
0160 
0161       template <typename DataT>
0162       void getImplementation(DataT const*& iData,
0163                              ESResolverIndex iResolverIndex,
0164                              bool iTransientAccessOnly,
0165                              ComponentDescription const*& oDesc,
0166                              std::shared_ptr<ESHandleExceptionFactory>& whyFailedFactory) const {
0167         DataKey const* dataKey = nullptr;
0168         assert(iResolverIndex.value() > -1 and
0169                iResolverIndex.value() < static_cast<ESResolverIndex::Value_t>(keysForResolvers_.size()));
0170         void const* pValue = this->getFromResolverAfterPrefetch(iResolverIndex, iTransientAccessOnly, oDesc, dataKey);
0171         iData = reinterpret_cast<DataT const*>(pValue);
0172       }
0173 
0174       // ---------- member data --------------------------------
0175 
0176       // We allow the validity to be modified while it is being used in
0177       // the case where a new sync value is being initialized and the
0178       // first part of the new validity range is the same,
0179       // but the last part of the validity range changes. In this case,
0180       // we do not want to start a new IOV, all the cached data should
0181       // remain valid. The atomic bool validityModificationUnderway_
0182       // protects access to validity_ while this change is made.
0183       CMS_THREAD_SAFE mutable ValidityInterval validity_;
0184 
0185       EventSetupRecordKey key_;
0186       std::vector<DataKey> keysForResolvers_;
0187       std::vector<edm::propagate_const<ESProductResolver*>> resolvers_;
0188       ActivityRegistry const* activityRegistry_;
0189       unsigned long long cacheIdentifier_;
0190       unsigned int iovIndex_;
0191       std::atomic<bool> isAvailable_;
0192       mutable std::atomic<bool> validityModificationUnderway_;
0193     };
0194   }  // namespace eventsetup
0195 }  // namespace edm
0196 #endif