File indexing completed on 2025-04-30 22:24:08
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/ESProductResolver.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 keysForResolvers_{std::move(source.keysForResolvers_)},
0047 resolvers_(std::move(source.resolvers_)),
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 keysForResolvers_ = std::move(rhs.keysForResolvers_);
0058 resolvers_ = std::move(rhs.resolvers_);
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& productResolver : resolvers_) {
0084 productResolver->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(resolvers_.size());
0101 for (auto const& iData : resolvers_) {
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(resolvers_.size());
0112 for (auto const& resolver : resolvers_) {
0113 ret.push_back(resolver->providerDescription());
0114 }
0115 return ret;
0116 }
0117
0118 std::vector<unsigned int> EventSetupRecordImpl::produceMethodIDsForRegisteredDataKeys() const {
0119 std::vector<unsigned int> ret;
0120 ret.reserve(resolvers_.size());
0121 for (auto const& resolver : resolvers_) {
0122 ret.push_back(resolver->produceMethodID());
0123 }
0124 return ret;
0125 }
0126
0127 bool EventSetupRecordImpl::add(const DataKey& iKey, ESProductResolver* iResolver) {
0128 const ESProductResolver* resolver = find(iKey);
0129 if (nullptr != resolver) {
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 assert(resolver->providerDescription());
0140 assert(iResolver->providerDescription());
0141 if (iResolver->providerDescription()->isLooper_) {
0142 resolvers_[std::distance(keysForResolvers_.begin(),
0143 std::lower_bound(keysForResolvers_.begin(), keysForResolvers_.end(), iKey))] =
0144 iResolver;
0145 return true;
0146 }
0147
0148 if (resolver->providerDescription()->isSource_ == iResolver->providerDescription()->isSource_) {
0149
0150 throw cms::Exception("EventSetupConflict")
0151 << "two EventSetup " << (resolver->providerDescription()->isSource_ ? "Sources" : "Producers")
0152 << " want to deliver type=\"" << iKey.type().name() << "\" label=\"" << iKey.name().value() << "\"\n"
0153 << " from record " << key().type().name() << ". The two providers are \n"
0154 << "1) type=\"" << resolver->providerDescription()->type_ << "\" label=\""
0155 << resolver->providerDescription()->label_ << "\"\n"
0156 << "2) type=\"" << iResolver->providerDescription()->type_ << "\" label=\""
0157 << iResolver->providerDescription()->label_ << "\"\n"
0158 << "Please either\n remove one of these "
0159 << (resolver->providerDescription()->isSource_ ? "Sources" : "Producers")
0160 << "\n or find a way of configuring one of them so it does not deliver this data"
0161 << "\n or use an es_prefer statement in the configuration to choose one.";
0162 } else if (resolver->providerDescription()->isSource_) {
0163 resolvers_[std::distance(keysForResolvers_.begin(),
0164 std::lower_bound(keysForResolvers_.begin(), keysForResolvers_.end(), iKey))] =
0165 iResolver;
0166 } else {
0167 return false;
0168 }
0169 } else {
0170 auto lb = std::lower_bound(keysForResolvers_.begin(), keysForResolvers_.end(), iKey);
0171 auto index = std::distance(keysForResolvers_.begin(), lb);
0172 keysForResolvers_.insert(lb, iKey);
0173 resolvers_.insert(resolvers_.begin() + index, iResolver);
0174 }
0175 return true;
0176 }
0177
0178 void EventSetupRecordImpl::clearResolvers() {
0179 keysForResolvers_.clear();
0180 resolvers_.clear();
0181 }
0182
0183 void EventSetupRecordImpl::invalidateResolvers() {
0184 for (auto& productResolver : resolvers_) {
0185 productResolver->invalidate();
0186 }
0187 }
0188
0189 void EventSetupRecordImpl::resetIfTransientInResolvers() {
0190 for (auto& productResolver : resolvers_) {
0191 productResolver->resetIfTransient();
0192 }
0193 }
0194
0195 void const* EventSetupRecordImpl::getFromResolverAfterPrefetch(ESResolverIndex iResolverIndex,
0196 bool iTransientAccessOnly,
0197 ComponentDescription const*& iDesc,
0198 DataKey const*& oGottenKey) const {
0199 const ESProductResolver* resolver = resolvers_[iResolverIndex.value()];
0200 assert(nullptr != resolver);
0201 iDesc = resolver->providerDescription();
0202
0203 auto const& key = keysForResolvers_[iResolverIndex.value()];
0204 oGottenKey = &key;
0205
0206 void const* hold = nullptr;
0207 try {
0208 convertException::wrap([&]() { hold = resolver->getAfterPrefetch(*this, key, iTransientAccessOnly); });
0209 } catch (cms::Exception& e) {
0210 addTraceInfoToCmsException(e, key.name().value(), resolver->providerDescription(), key);
0211 throw;
0212 }
0213 return hold;
0214 }
0215
0216 const ESProductResolver* EventSetupRecordImpl::find(const DataKey& iKey) const {
0217 auto lb = std::lower_bound(keysForResolvers_.begin(), keysForResolvers_.end(), iKey);
0218 if ((lb == keysForResolvers_.end()) or (*lb != iKey)) {
0219 return nullptr;
0220 }
0221 return resolvers_[std::distance(keysForResolvers_.begin(), lb)].get();
0222 }
0223
0224 void EventSetupRecordImpl::prefetchAsync(WaitingTaskHolder iTask,
0225 ESResolverIndex iResolverIndex,
0226 EventSetupImpl const* iEventSetupImpl,
0227 ServiceToken const& iToken,
0228 ESParentContext iParent) const noexcept {
0229 if UNLIKELY (iResolverIndex == ESResolverIndex::moduleLabelDoesNotMatch() ||
0230 iResolverIndex == ESResolverIndex::noResolverConfigured()) {
0231 return;
0232 }
0233
0234 const ESProductResolver* resolver = resolvers_[iResolverIndex.value()];
0235 if (nullptr != resolver) {
0236 auto const& key = keysForResolvers_[iResolverIndex.value()];
0237 resolver->prefetchAsync(iTask, *this, key, iEventSetupImpl, iToken, iParent);
0238 }
0239 }
0240
0241 bool EventSetupRecordImpl::wasGotten(const DataKey& aKey) const {
0242 const ESProductResolver* resolver = find(aKey);
0243 if (nullptr != resolver) {
0244 return resolver->cacheIsValid();
0245 }
0246 return false;
0247 }
0248
0249 edm::eventsetup::ComponentDescription const* EventSetupRecordImpl::providerDescription(const DataKey& aKey) const {
0250 const ESProductResolver* resolver = find(aKey);
0251 if (nullptr != resolver) {
0252 return resolver->providerDescription();
0253 }
0254 return nullptr;
0255 }
0256
0257 std::vector<DataKey> const& EventSetupRecordImpl::registeredDataKeys() const { return keysForResolvers_; }
0258
0259 void EventSetupRecordImpl::addTraceInfoToCmsException(cms::Exception& iException,
0260 const char* iName,
0261 const ComponentDescription* iDescription,
0262 const DataKey& iKey) const {
0263 std::ostringstream ost;
0264 ost << "Using EventSetup component " << iDescription->type_ << "/'" << iDescription->label_ << "' to make data "
0265 << iKey.type().name() << "/'" << iName << "' in record " << this->key().type().name();
0266 iException.addContext(ost.str());
0267 }
0268
0269 }
0270 }