Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // Package:     Framework
0004 // Class  :     ESProductResolver
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Author:      Chris Jones
0010 // Created:     Thu Mar 31 12:49:19 EST 2005
0011 //
0012 
0013 #include "FWCore/Framework/interface/ESProductResolver.h"
0014 #include "FWCore/Framework/interface/ComponentDescription.h"
0015 #include "FWCore/Framework/interface/MakeDataException.h"
0016 #include "FWCore/Framework/interface/EventSetupRecordImpl.h"
0017 #include "FWCore/Utilities/interface/Likely.h"
0018 
0019 namespace {
0020   constexpr int kInvalidLocation = 0;
0021   void const* const kInvalid = &kInvalidLocation;
0022 }  // namespace
0023 
0024 namespace edm {
0025   namespace eventsetup {
0026 
0027     static const ComponentDescription* dummyDescription() {
0028       static const ComponentDescription s_desc;
0029       return &s_desc;
0030     }
0031 
0032     ESProductResolver::ESProductResolver()
0033         : description_(dummyDescription()), cache_(kInvalid), nonTransientAccessRequested_(false) {}
0034 
0035     ESProductResolver::~ESProductResolver() {}
0036 
0037     bool ESProductResolver::cacheIsValid() const { return cache_.load() != kInvalid; }
0038 
0039     void ESProductResolver::clearCacheIsValid() {
0040       nonTransientAccessRequested_.store(false, std::memory_order_release);
0041       cache_.store(kInvalid);
0042     }
0043 
0044     void ESProductResolver::resetIfTransient() {
0045       if (!nonTransientAccessRequested_.load(std::memory_order_acquire)) {
0046         clearCacheIsValid();
0047         invalidateTransientCache();
0048       }
0049     }
0050 
0051     unsigned int ESProductResolver::produceMethodID() const { return 0; }
0052 
0053     void ESProductResolver::invalidateTransientCache() { invalidateCache(); }
0054 
0055     namespace {
0056       void throwMakeException(const EventSetupRecordImpl& iRecord, const DataKey& iKey) {
0057         throw MakeDataException(iRecord.key(), iKey);
0058       }
0059 
0060     }  // namespace
0061 
0062     void ESProductResolver::prefetchAsync(WaitingTaskHolder iTask,
0063                                           EventSetupRecordImpl const& iRecord,
0064                                           DataKey const& iKey,
0065                                           EventSetupImpl const* iEventSetupImpl,
0066                                           ServiceToken const& iToken,
0067                                           ESParentContext const& iParent) const noexcept {
0068       const_cast<ESProductResolver*>(this)->prefetchAsyncImpl(iTask, iRecord, iKey, iEventSetupImpl, iToken, iParent);
0069     }
0070 
0071     void const* ESProductResolver::getAfterPrefetch(const EventSetupRecordImpl& iRecord,
0072                                                     const DataKey& iKey,
0073                                                     bool iTransiently) const {
0074       //We need to set the AccessType for each request so this can't be called in an earlier function in the stack.
0075       //This also must be before the cache_ check since we want to setCacheIsValid before a possible
0076       // exception throw. If we don't, 'getImpl' will be called again on a second request for the data.
0077 
0078       if LIKELY (!iTransiently) {
0079         nonTransientAccessRequested_.store(true, std::memory_order_release);
0080       }
0081 
0082       auto cache = cache_.load();
0083       if UNLIKELY (cache == kInvalid) {
0084         // This is safe even if multiple threads get in here simultaneously
0085         // because cache_ is atomic and getAfterPrefetchImpl will return
0086         // the same pointer on all threads for the same IOV.
0087         // This is fast because the vast majority of the time only 1 thread per IOV
0088         // will get in here so most of the time only 1 atomic operation.
0089         cache = cache_ = getAfterPrefetchImpl();
0090       }
0091       if UNLIKELY (cache == nullptr) {
0092         throwMakeException(iRecord, iKey);
0093       }
0094       return cache;
0095     }
0096 
0097   }  // namespace eventsetup
0098 }  // namespace edm