File indexing completed on 2023-03-17 11:02:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <algorithm>
0015 #include <cassert>
0016 #include <iterator>
0017 #include <sstream>
0018 #include <utility>
0019
0020
0021 #include "FWCore/Framework/interface/EventSetupRecordImpl.h"
0022 #include "FWCore/Framework/interface/DataProxy.h"
0023 #include "FWCore/Framework/interface/ComponentDescription.h"
0024 #include "FWCore/ServiceRegistry/interface/ESParentContext.h"
0025
0026 #include "FWCore/Utilities/interface/ConvertException.h"
0027 #include "FWCore/Utilities/interface/Exception.h"
0028
0029 namespace edm {
0030 namespace eventsetup {
0031
0032 EventSetupRecordImpl::EventSetupRecordImpl(EventSetupRecordKey const& iKey,
0033 ActivityRegistry const* activityRegistry,
0034 unsigned int iovIndex)
0035 : validity_(),
0036 key_(iKey),
0037 activityRegistry_(activityRegistry),
0038 cacheIdentifier_(1),
0039 iovIndex_(iovIndex),
0040 isAvailable_(true),
0041 validityModificationUnderway_(false) {}
0042
0043 EventSetupRecordImpl::EventSetupRecordImpl(EventSetupRecordImpl&& source)
0044 : validity_{source.validity_},
0045 key_{source.key_},
0046 keysForProxies_{std::move(source.keysForProxies_)},
0047 proxies_(std::move(source.proxies_)),
0048 activityRegistry_{source.activityRegistry_},
0049 cacheIdentifier_{source.cacheIdentifier_},
0050 iovIndex_{source.iovIndex_},
0051 isAvailable_{source.isAvailable_.load()},
0052 validityModificationUnderway_{source.validityModificationUnderway_.load()} {}
0053
0054 EventSetupRecordImpl& EventSetupRecordImpl::operator=(EventSetupRecordImpl&& rhs) {
0055 validity_ = rhs.validity_;
0056 key_ = rhs.key_;
0057 keysForProxies_ = std::move(rhs.keysForProxies_);
0058 proxies_ = std::move(rhs.proxies_);
0059 activityRegistry_ = rhs.activityRegistry_;
0060 cacheIdentifier_ = rhs.cacheIdentifier_;
0061 iovIndex_ = rhs.iovIndex_;
0062 isAvailable_.store(rhs.isAvailable_.load());
0063 validityModificationUnderway_.store(validityModificationUnderway_.load());
0064 return *this;
0065 }
0066
0067 ValidityInterval EventSetupRecordImpl::validityInterval() const {
0068 bool expected = false;
0069 while (not validityModificationUnderway_.compare_exchange_strong(expected, true)) {
0070 expected = false;
0071 }
0072 ValidityInterval temp = validity_;
0073 validityModificationUnderway_ = false;
0074 return temp;
0075 }
0076
0077 void EventSetupRecordImpl::initializeForNewIOV(unsigned long long iCacheIdentifier,
0078 ValidityInterval const& iValidityInterval,
0079 bool hasFinder) {
0080 cacheIdentifier_ = iCacheIdentifier;
0081 validity_ = iValidityInterval;
0082 if (hasFinder) {
0083 for (auto& dataProxy : proxies_) {
0084 dataProxy->initializeForNewIOV();
0085 }
0086 }
0087 }
0088
0089 void EventSetupRecordImpl::setSafely(const ValidityInterval& iInterval) const {
0090 bool expected = false;
0091 while (not validityModificationUnderway_.compare_exchange_strong(expected, true)) {
0092 expected = false;
0093 }
0094 validity_ = iInterval;
0095 validityModificationUnderway_ = false;
0096 }
0097
0098 void EventSetupRecordImpl::getESProducers(std::vector<ComponentDescription const*>& esproducers) const {
0099 esproducers.clear();
0100 esproducers.reserve(proxies_.size());
0101 for (auto const& iData : proxies_) {
0102 ComponentDescription const* componentDescription = iData->providerDescription();
0103 if (!componentDescription->isLooper_ && !componentDescription->isSource_) {
0104 esproducers.push_back(componentDescription);
0105 }
0106 }
0107 }
0108
0109 std::vector<ComponentDescription const*> EventSetupRecordImpl::componentsForRegisteredDataKeys() const {
0110 std::vector<ComponentDescription const*> ret;
0111 ret.reserve(proxies_.size());
0112 for (auto const& proxy : proxies_) {
0113 ret.push_back(proxy->providerDescription());
0114 }
0115 return ret;
0116 }
0117
0118 bool EventSetupRecordImpl::add(const DataKey& iKey, DataProxy* iProxy) {
0119 const DataProxy* proxy = find(iKey);
0120 if (nullptr != proxy) {
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 assert(proxy->providerDescription());
0131 assert(iProxy->providerDescription());
0132 if (iProxy->providerDescription()->isLooper_) {
0133 proxies_[std::distance(keysForProxies_.begin(),
0134 std::lower_bound(keysForProxies_.begin(), keysForProxies_.end(), iKey))] = iProxy;
0135 return true;
0136 }
0137
0138 if (proxy->providerDescription()->isSource_ == iProxy->providerDescription()->isSource_) {
0139
0140 throw cms::Exception("EventSetupConflict")
0141 << "two EventSetup " << (proxy->providerDescription()->isSource_ ? "Sources" : "Producers")
0142 << " want to deliver type=\"" << iKey.type().name() << "\" label=\"" << iKey.name().value() << "\"\n"
0143 << " from record " << key().type().name() << ". The two providers are \n"
0144 << "1) type=\"" << proxy->providerDescription()->type_ << "\" label=\""
0145 << proxy->providerDescription()->label_ << "\"\n"
0146 << "2) type=\"" << iProxy->providerDescription()->type_ << "\" label=\""
0147 << iProxy->providerDescription()->label_ << "\"\n"
0148 << "Please either\n remove one of these "
0149 << (proxy->providerDescription()->isSource_ ? "Sources" : "Producers")
0150 << "\n or find a way of configuring one of them so it does not deliver this data"
0151 << "\n or use an es_prefer statement in the configuration to choose one.";
0152 } else if (proxy->providerDescription()->isSource_) {
0153 proxies_[std::distance(keysForProxies_.begin(),
0154 std::lower_bound(keysForProxies_.begin(), keysForProxies_.end(), iKey))] = iProxy;
0155 } else {
0156 return false;
0157 }
0158 } else {
0159 auto lb = std::lower_bound(keysForProxies_.begin(), keysForProxies_.end(), iKey);
0160 auto index = std::distance(keysForProxies_.begin(), lb);
0161 keysForProxies_.insert(lb, iKey);
0162 proxies_.insert(proxies_.begin() + index, iProxy);
0163 }
0164 return true;
0165 }
0166
0167 void EventSetupRecordImpl::clearProxies() {
0168 keysForProxies_.clear();
0169 proxies_.clear();
0170 }
0171
0172 void EventSetupRecordImpl::invalidateProxies() {
0173 for (auto& dataProxy : proxies_) {
0174 dataProxy->invalidate();
0175 }
0176 }
0177
0178 void EventSetupRecordImpl::resetIfTransientInProxies() {
0179 for (auto& dataProxy : proxies_) {
0180 dataProxy->resetIfTransient();
0181 }
0182 }
0183
0184 void const* EventSetupRecordImpl::getFromProxyAfterPrefetch(ESProxyIndex iProxyIndex,
0185 bool iTransientAccessOnly,
0186 ComponentDescription const*& iDesc,
0187 DataKey const*& oGottenKey) const {
0188 const DataProxy* proxy = proxies_[iProxyIndex.value()];
0189 assert(nullptr != proxy);
0190 iDesc = proxy->providerDescription();
0191
0192 auto const& key = keysForProxies_[iProxyIndex.value()];
0193 oGottenKey = &key;
0194
0195 void const* hold = nullptr;
0196 try {
0197 convertException::wrap([&]() { hold = proxy->getAfterPrefetch(*this, key, iTransientAccessOnly); });
0198 } catch (cms::Exception& e) {
0199 addTraceInfoToCmsException(e, key.name().value(), proxy->providerDescription(), key);
0200 throw;
0201 }
0202 return hold;
0203 }
0204
0205 const DataProxy* EventSetupRecordImpl::find(const DataKey& iKey) const {
0206 auto lb = std::lower_bound(keysForProxies_.begin(), keysForProxies_.end(), iKey);
0207 if ((lb == keysForProxies_.end()) or (*lb != iKey)) {
0208 return nullptr;
0209 }
0210 return proxies_[std::distance(keysForProxies_.begin(), lb)].get();
0211 }
0212
0213 void EventSetupRecordImpl::prefetchAsync(WaitingTaskHolder iTask,
0214 ESProxyIndex iProxyIndex,
0215 EventSetupImpl const* iEventSetupImpl,
0216 ServiceToken const& iToken,
0217 ESParentContext iParent) const {
0218 if UNLIKELY (iProxyIndex.value() == std::numeric_limits<int>::max()) {
0219 return;
0220 }
0221
0222 const DataProxy* proxy = proxies_[iProxyIndex.value()];
0223 if (nullptr != proxy) {
0224 auto const& key = keysForProxies_[iProxyIndex.value()];
0225 proxy->prefetchAsync(iTask, *this, key, iEventSetupImpl, iToken, iParent);
0226 }
0227 }
0228
0229 bool EventSetupRecordImpl::wasGotten(const DataKey& aKey) const {
0230 const DataProxy* proxy = find(aKey);
0231 if (nullptr != proxy) {
0232 return proxy->cacheIsValid();
0233 }
0234 return false;
0235 }
0236
0237 edm::eventsetup::ComponentDescription const* EventSetupRecordImpl::providerDescription(const DataKey& aKey) const {
0238 const DataProxy* proxy = find(aKey);
0239 if (nullptr != proxy) {
0240 return proxy->providerDescription();
0241 }
0242 return nullptr;
0243 }
0244
0245 void EventSetupRecordImpl::fillRegisteredDataKeys(std::vector<DataKey>& oToFill) const {
0246 oToFill = keysForProxies_;
0247 }
0248
0249 void EventSetupRecordImpl::addTraceInfoToCmsException(cms::Exception& iException,
0250 const char* iName,
0251 const ComponentDescription* iDescription,
0252 const DataKey& iKey) const {
0253 std::ostringstream ost;
0254 ost << "Using EventSetup component " << iDescription->type_ << "/'" << iDescription->label_ << "' to make data "
0255 << iKey.type().name() << "/'" << iName << "' in record " << this->key().type().name();
0256 iException.addContext(ost.str());
0257 }
0258
0259 }
0260 }