Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-22 01:53:28

0001 // -*- C++ -*-
0002 //
0003 // Package:     Framework
0004 // Class  :     DataProxy
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 // system include files
0014 #include <mutex>
0015 
0016 // user include files
0017 #include "FWCore/Concurrency/interface/include_first_syncWait.h"
0018 
0019 #include "FWCore/Framework/interface/DataProxy.h"
0020 #include "FWCore/Framework/interface/ComponentDescription.h"
0021 #include "FWCore/Framework/interface/MakeDataException.h"
0022 #include "FWCore/Framework/interface/EventSetupRecord.h"
0023 #include "FWCore/Framework/interface/EventSetupImpl.h"
0024 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0025 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0026 #include "FWCore/ServiceRegistry/interface/ESParentContext.h"
0027 #include "FWCore/Concurrency/interface/WaitingTaskList.h"
0028 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0029 
0030 namespace edm {
0031   namespace eventsetup {
0032 
0033     static const ComponentDescription* dummyDescription() {
0034       static ComponentDescription s_desc;
0035       return &s_desc;
0036     }
0037 
0038     DataProxy::DataProxy()
0039         : description_(dummyDescription()),
0040           cache_(nullptr),
0041           cacheIsValid_(false),
0042           nonTransientAccessRequested_(false) {}
0043 
0044     DataProxy::~DataProxy() {}
0045 
0046     void DataProxy::clearCacheIsValid() {
0047       nonTransientAccessRequested_.store(false, std::memory_order_release);
0048       cache_ = nullptr;
0049       cacheIsValid_.store(false, std::memory_order_release);
0050     }
0051 
0052     void DataProxy::resetIfTransient() {
0053       if (!nonTransientAccessRequested_.load(std::memory_order_acquire)) {
0054         clearCacheIsValid();
0055         invalidateTransientCache();
0056       }
0057     }
0058 
0059     void DataProxy::invalidateTransientCache() { invalidateCache(); }
0060 
0061     namespace {
0062       void throwMakeException(const EventSetupRecordImpl& iRecord, const DataKey& iKey) {
0063         throw MakeDataException(iRecord.key(), iKey);
0064       }
0065 
0066     }  // namespace
0067 
0068     void DataProxy::prefetchAsync(WaitingTaskHolder iTask,
0069                                   EventSetupRecordImpl const& iRecord,
0070                                   DataKey const& iKey,
0071                                   EventSetupImpl const* iEventSetupImpl,
0072                                   ServiceToken const& iToken,
0073                                   ESParentContext const& iParent) const {
0074       const_cast<DataProxy*>(this)->prefetchAsyncImpl(iTask, iRecord, iKey, iEventSetupImpl, iToken, iParent);
0075     }
0076 
0077     void const* DataProxy::getAfterPrefetch(const EventSetupRecordImpl& iRecord,
0078                                             const DataKey& iKey,
0079                                             bool iTransiently) const {
0080       //We need to set the AccessType for each request so this can't be called in an earlier function in the stack.
0081       //This also must be before the cache_ check since we want to setCacheIsValid before a possible
0082       // exception throw. If we don't, 'getImpl' will be called again on a second request for the data.
0083 
0084       if LIKELY (!iTransiently) {
0085         nonTransientAccessRequested_.store(true, std::memory_order_release);
0086       }
0087 
0088       if UNLIKELY (!cacheIsValid()) {
0089         cache_ = getAfterPrefetchImpl();
0090         cacheIsValid_.store(true, std::memory_order_release);
0091       }
0092 
0093       if UNLIKELY (nullptr == cache_) {
0094         throwMakeException(iRecord, iKey);
0095       }
0096       return cache_;
0097     }
0098 
0099     const void* DataProxy::get(const EventSetupRecordImpl& iRecord,
0100                                const DataKey& iKey,
0101                                bool iTransiently,
0102                                ActivityRegistry const* activityRegistry,
0103                                EventSetupImpl const* iEventSetupImpl,
0104                                ESParentContext const& iParent) const {
0105       if (!cacheIsValid()) {
0106         throw edm::Exception(errors::LogicError) << "DataProxy::get called without first doing prefetch.\nThis should "
0107                                                     "not be able to happen.\nPlease contact framework developers";
0108       }
0109       return getAfterPrefetch(iRecord, iKey, iTransiently);
0110     }
0111 
0112   }  // namespace eventsetup
0113 }  // namespace edm