-
Notifications
You must be signed in to change notification settings - Fork 4.4k
/
Copy pathDataProxy.cc
123 lines (104 loc) · 4.44 KB
/
DataProxy.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// -*- C++ -*-
//
// Package: Framework
// Class : DataProxy
//
// Implementation:
// <Notes on implementation>
//
// Author: Chris Jones
// Created: Thu Mar 31 12:49:19 EST 2005
//
// system include files
#include <mutex>
// user include files
#include "FWCore/Concurrency/interface/include_first_syncWait.h"
#include "FWCore/Framework/interface/DataProxy.h"
#include "FWCore/Framework/interface/ComponentDescription.h"
#include "FWCore/Framework/interface/MakeDataException.h"
#include "FWCore/Framework/interface/EventSetupRecord.h"
#include "FWCore/Framework/interface/EventSetupImpl.h"
#include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
#include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
#include "FWCore/ServiceRegistry/interface/ESParentContext.h"
#include "FWCore/Concurrency/interface/WaitingTaskList.h"
#include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
namespace edm {
namespace eventsetup {
static const ComponentDescription* dummyDescription() {
static ComponentDescription s_desc;
return &s_desc;
}
DataProxy::DataProxy()
: description_(dummyDescription()),
cache_(nullptr),
cacheIsValid_(false),
nonTransientAccessRequested_(false) {}
DataProxy::~DataProxy() {}
void DataProxy::clearCacheIsValid() {
nonTransientAccessRequested_.store(false, std::memory_order_release);
cache_ = nullptr;
cacheIsValid_.store(false, std::memory_order_release);
}
void DataProxy::resetIfTransient() {
if (!nonTransientAccessRequested_.load(std::memory_order_acquire)) {
clearCacheIsValid();
invalidateTransientCache();
}
}
void DataProxy::invalidateTransientCache() { invalidateCache(); }
namespace {
void throwMakeException(const EventSetupRecordImpl& iRecord, const DataKey& iKey) {
throw MakeDataException(iRecord.key(), iKey);
}
} // namespace
void DataProxy::prefetchAsync(WaitingTaskHolder iTask,
EventSetupRecordImpl const& iRecord,
DataKey const& iKey,
EventSetupImpl const* iEventSetupImpl,
ServiceToken const& iToken,
ESParentContext const& iParent) const {
const_cast<DataProxy*>(this)->prefetchAsyncImpl(iTask, iRecord, iKey, iEventSetupImpl, iToken, iParent);
}
void const* DataProxy::getAfterPrefetch(const EventSetupRecordImpl& iRecord,
const DataKey& iKey,
bool iTransiently) const {
//We need to set the AccessType for each request so this can't be called in an earlier function in the stack.
//This also must be before the cache_ check since we want to setCacheIsValid before a possible
// exception throw. If we don't, 'getImpl' will be called again on a second request for the data.
if LIKELY (!iTransiently) {
nonTransientAccessRequested_.store(true, std::memory_order_release);
}
if UNLIKELY (!cacheIsValid()) {
cache_ = getAfterPrefetchImpl();
cacheIsValid_.store(true, std::memory_order_release);
}
if UNLIKELY (nullptr == cache_) {
throwMakeException(iRecord, iKey);
}
return cache_;
}
const void* DataProxy::get(const EventSetupRecordImpl& iRecord,
const DataKey& iKey,
bool iTransiently,
ActivityRegistry const* activityRegistry,
EventSetupImpl const* iEventSetupImpl,
ESParentContext const& iParent) const {
if (!cacheIsValid()) {
auto token = ServiceRegistry::instance().presentToken();
std::exception_ptr exceptPtr{};
iEventSetupImpl->taskArena()->execute([this, &exceptPtr, &iRecord, &iKey, iEventSetupImpl, token, iParent]() {
exceptPtr = syncWait([&, this](WaitingTaskHolder&& holder) {
prefetchAsync(std::move(holder), iRecord, iKey, iEventSetupImpl, token, iParent);
});
});
cache_ = getAfterPrefetchImpl();
cacheIsValid_.store(true, std::memory_order_release);
if (exceptPtr) {
std::rethrow_exception(exceptPtr);
}
}
return getAfterPrefetch(iRecord, iKey, iTransiently);
}
} // namespace eventsetup
} // namespace edm