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