diff --git a/Control/IOVSvc/src/CondInputLoader.cxx b/Control/IOVSvc/src/CondInputLoader.cxx index ff3f6acc4d2151a355657bb6ab02bb09284ee72b..7e1423097b18d465c362c4c7ba30da0b76e0e881 100644 --- a/Control/IOVSvc/src/CondInputLoader.cxx +++ b/Control/IOVSvc/src/CondInputLoader.cxx @@ -24,6 +24,7 @@ #include "xAODEventInfo/EventInfo.h" #include "AthenaKernel/BaseInfo.h" +#include "ICondSvcSetupDone.h" #include "TClass.h" @@ -265,6 +266,12 @@ CondInputLoader::start() return StatusCode::FAILURE; } + // Let the conditions service know that we've finished creating + // conditions containers. + ServiceHandle<ICondSvcSetupDone> condSvcDone ("CondSvc", name()); + ATH_CHECK( condSvcDone.retrieve() ); + ATH_CHECK( condSvcDone->setupDone() ); + return StatusCode::SUCCESS; } diff --git a/Control/IOVSvc/src/CondSvc.cxx b/Control/IOVSvc/src/CondSvc.cxx index 8202e2c6be742f5cbd74cd87f51dd465db81424c..659e9dd302812286871d152af0f80f0113843a89 100644 --- a/Control/IOVSvc/src/CondSvc.cxx +++ b/Control/IOVSvc/src/CondSvc.cxx @@ -130,6 +130,15 @@ CondSvc::finalize() { } +StatusCode +CondSvc::start() +{ + // Call this now, in case there's no CondInputLoader. + ATH_CHECK( setupDone() ); + return StatusCode::SUCCESS; +} + + StatusCode CondSvc::stop() { @@ -342,7 +351,10 @@ CondSvc::getValidIDs(const EventContext& ctx, DataObjIDColl& validIDs) { bool CondSvc::isValidID(const EventContext& ctx, const DataObjID& id) const { - std::lock_guard<mutex_t> lock(m_lock); + // Don't take out the lock here. + // In many-thread jobs, a lock here becomes heavily contended. + // The only potential conflict is with startConditionSetup(), + // which should only be called during START. EventIDBase now(ctx.eventID()); @@ -352,13 +364,15 @@ CondSvc::isValidID(const EventContext& ctx, const DataObjID& id) const { sk.erase(0,15); } - if (m_sgs->contains<CondContBase>( sk ) ) { - CondContBase *cib; - if (m_sgs->retrieve(cib, sk).isSuccess()) { - ATH_MSG_VERBOSE("CondSvc::isValidID: now: " << ctx.eventID() << " id : " - << id << (cib->valid(now) ? ": T" : ": F") ); - return cib->valid(now); - } + auto it = m_condConts.find (sk); + if (it != m_condConts.end()) { + bool valid = it->second->valid (now); + ATH_MSG_VERBOSE("CondSvc::isValidID: now: " << ctx.eventID() << " id : " + << id << (valid ? ": T" : ": F") ); + return valid; + } + else { + ATH_MSG_ERROR( "Cannot find CondCont " << id ); } ATH_MSG_DEBUG("CondSvc::isValidID: now: " << ctx.eventID() << " id: " @@ -396,3 +410,20 @@ CondSvc::conditionIDs() const { } +//--------------------------------------------------------------------------- + + +StatusCode CondSvc::setupDone() +{ + std::lock_guard<mutex_t> lock(m_lock); + + SG::ConstIterator<CondContBase> cib, cie; + if (m_sgs->retrieve(cib,cie).isSuccess()) { + while(cib != cie) { + m_condConts[cib.key()] = &*cib; + ++cib; + } + } + + return StatusCode::SUCCESS; +} diff --git a/Control/IOVSvc/src/CondSvc.h b/Control/IOVSvc/src/CondSvc.h index 1e0185de4813ecd7c76d9bac4d43cfcd21972b3c..b8a62c368826c569d1febb1a63feec48f9577271 100644 --- a/Control/IOVSvc/src/CondSvc.h +++ b/Control/IOVSvc/src/CondSvc.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #ifndef IOVSVC_CONDSVC_H @@ -10,7 +10,9 @@ #include "AthenaBaseComps/AthService.h" #include "StoreGate/StoreGateSvc.h" #include "AthenaBaseComps/AthService.h" +#include "ICondSvcSetupDone.h" +#include <unordered_map> #include <map> #include <set> #include <vector> @@ -19,38 +21,45 @@ class ConditionSlotFuture; class ICondtionIOSvc; -class ATLAS_CHECK_THREAD_SAFETY CondSvc: public extends1<AthService, ICondSvc> { +class ATLAS_CHECK_THREAD_SAFETY CondSvc: public extends<AthService, ICondSvc, ICondSvcSetupDone> { public: CondSvc(const std::string& name, ISvcLocator* svc); ~CondSvc(); - virtual StatusCode initialize(); - virtual StatusCode finalize(); - virtual StatusCode stop(); + virtual StatusCode initialize() override; + virtual StatusCode finalize() override; + virtual StatusCode start() override; + virtual StatusCode stop() override; // from ICondSvc public: - virtual StatusCode regHandle(IAlgorithm* alg, const Gaudi::DataHandle& id); + virtual StatusCode regHandle(IAlgorithm* alg, const Gaudi::DataHandle& id) override; virtual bool getInvalidIDs(const EventContext&, DataObjIDColl& ids); virtual bool getValidIDs(const EventContext&, DataObjIDColl& ids); virtual bool getIDValidity(const EventContext&, DataObjIDColl& validIDs, DataObjIDColl& invalidIDs); - virtual bool isValidID(const EventContext&, const DataObjID&) const; + virtual bool isValidID(const EventContext&, const DataObjID&) const override; - virtual const std::set<IAlgorithm*>& condAlgs() const { return m_condAlgs; } + virtual const std::set<IAlgorithm*>& condAlgs() const override { return m_condAlgs; } - virtual bool isRegistered(const DataObjID&) const; - virtual bool isRegistered(IAlgorithm*) const; + virtual bool isRegistered(const DataObjID&) const override; + virtual bool isRegistered(IAlgorithm*) const override; - virtual const DataObjIDColl& conditionIDs() const; + virtual const DataObjIDColl& conditionIDs() const override; virtual StatusCode validRanges( std::vector<EventIDRange>& ranges, - const DataObjID& id ) const; + const DataObjID& id ) const override; // virtual void dump() const; - virtual void dump(std::ostream&) const; + virtual void dump(std::ostream&) const override; + + /// To be called after changes to the set of conditions containers + /// in the conditions store. + /// May not be called concurrently with any other methods of this class. + virtual StatusCode setupDone() override; + public: // unimplemented interfaces @@ -62,7 +71,7 @@ public: /// register an IConditionIOSvc (alternative to Algorithm processing of /// Conditions) - virtual StatusCode registerConditionIOSvc(IConditionIOSvc*) { + virtual StatusCode registerConditionIOSvc(IConditionIOSvc*) override { return StatusCode::FAILURE; } @@ -103,6 +112,11 @@ private: DataObjIDColl m_condIDs; + // Map from keys to CondContBase instances. + // Populated by startConditionSetup(). + typedef std::unordered_map<std::string, const CondContBase*> CondContMap_t; + CondContMap_t m_condConts; + typedef std::mutex mutex_t; mutable mutex_t m_lock; diff --git a/Control/IOVSvc/src/ICondSvcSetupDone.h b/Control/IOVSvc/src/ICondSvcSetupDone.h new file mode 100644 index 0000000000000000000000000000000000000000..bc5f870098d295ae099df4d6797677ba49b62d68 --- /dev/null +++ b/Control/IOVSvc/src/ICondSvcSetupDone.h @@ -0,0 +1,32 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. +/* + * Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration. + */ +/** + * @file IOVSvc/src/ICondSvcSetupDone.h + * @author scott snyder <snyder@bnl.gov> + * @date Nov, 2020 + * @brief Interface to tell CondSvc to cache conditions containers. + */ + + +#ifndef IOVSVC_ICONDSVCSETUPDONE_H +#define IOVSVC_ICONDSVCSETUPDONE_H + + +#include "GaudiKernel/IInterface.h" + + +class ICondSvcSetupDone + : virtual public IInterface +{ +public: + DeclareInterfaceID( ICondSvcSetupDone, 1, 0 ); + + /// To be called after creating conditions containers + /// in the conditions store. + virtual StatusCode setupDone() = 0; +}; + + +#endif // not IOVSVC_ICONDSVCSETUPDONE_H