From e4fcabed1361c4cf29c52ee40e068b613a9ea0b0 Mon Sep 17 00:00:00 2001
From: Walter Lampl <Walter.Lampl@cern.ch>
Date: Tue, 9 Feb 2021 19:46:13 +0100
Subject: [PATCH 1/2] IOVSvc/CBnode.h: Make instance counter atomic

---
 Control/IOVSvc/src/CBNode.cxx | 2 +-
 Control/IOVSvc/src/CBNode.h   | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Control/IOVSvc/src/CBNode.cxx b/Control/IOVSvc/src/CBNode.cxx
index fe6799283a04..8bb8683959dc 100755
--- a/Control/IOVSvc/src/CBNode.cxx
+++ b/Control/IOVSvc/src/CBNode.cxx
@@ -17,7 +17,7 @@
 
 #include "SGTools/DataProxy.h"
 
-unsigned int CBNode::s_serial = 0;
+std::atomic<unsigned int> CBNode::s_serial = 0;
 
 CBNode::CBNode(const std::string& name, CBNode* parent): 
   m_name(name), m_proxy(0), m_fcn(0), m_trig(false), m_flag(false) {
diff --git a/Control/IOVSvc/src/CBNode.h b/Control/IOVSvc/src/CBNode.h
index 4a5f1781c17d..d0d751257fe0 100644
--- a/Control/IOVSvc/src/CBNode.h
+++ b/Control/IOVSvc/src/CBNode.h
@@ -21,6 +21,7 @@
 
 #include "AthenaKernel/IOVSvcDefs.h"
 #include "SGTools/CallBackID.h"
+#include <atomic>
 
 namespace SG {
   class DataProxy;
@@ -99,7 +100,7 @@ private:
   bool m_flag;
 
   unsigned int m_serial;
-  static unsigned int s_serial;
+  static std::atomic<unsigned int> s_serial;
 };
 
 #endif
-- 
GitLab


From 3f00615bdda5f447d896c3308248b9c39bbcadd1 Mon Sep 17 00:00:00 2001
From: Walter Lampl <Walter.Lampl@cern.ch>
Date: Tue, 9 Feb 2021 19:47:09 +0100
Subject: [PATCH 2/2] attempt to make IOVSvcTool::handle(inc) vaguely
 re-entrant

---
 Control/IOVSvc/IOVSvc/IIOVSvcTool.h |   3 +-
 Control/IOVSvc/src/IOVSvc.cxx       |  16 +++-
 Control/IOVSvc/src/IOVSvcTool.cxx   | 110 ++++++++++++++--------------
 Control/IOVSvc/src/IOVSvcTool.h     |  21 +++---
 4 files changed, 84 insertions(+), 66 deletions(-)

diff --git a/Control/IOVSvc/IOVSvc/IIOVSvcTool.h b/Control/IOVSvc/IOVSvc/IIOVSvcTool.h
index e4401e79010f..2b4326287971 100644
--- a/Control/IOVSvc/IOVSvc/IIOVSvcTool.h
+++ b/Control/IOVSvc/IOVSvc/IIOVSvcTool.h
@@ -69,7 +69,8 @@ public:
   // Get IOVRange from db for current event
   virtual StatusCode getRangeFromDB(const CLID& clid, const std::string& key, 
                                     IOVRange& range, std::string &tag,
-                                    std::unique_ptr<IOpaqueAddress>& ioa) const = 0;
+                                    std::unique_ptr<IOpaqueAddress>& ioa,
+				    const IOVTime& curTime) const = 0;
 
   // Get IOVRange from db for a particular event
   virtual StatusCode getRangeFromDB(const CLID& clid, const std::string& key, 
diff --git a/Control/IOVSvc/src/IOVSvc.cxx b/Control/IOVSvc/src/IOVSvc.cxx
index e968fe7af849..ab11b1f1315a 100755
--- a/Control/IOVSvc/src/IOVSvc.cxx
+++ b/Control/IOVSvc/src/IOVSvc.cxx
@@ -406,7 +406,7 @@ IOVSvc::getRange(const CLID& clid, const std::string& key,
 StatusCode 
 IOVSvc::getRangeFromDB(const CLID& clid, const std::string& key, 
                        IOVRange& range, std::string& tag,
-                       std::unique_ptr<IOpaqueAddress>& ioa) const { 
+                       std::unique_ptr<IOpaqueAddress>& ioa) const {
 
   std::lock_guard<std::recursive_mutex> lock(m_lock);
 
@@ -416,7 +416,19 @@ IOVSvc::getRangeFromDB(const CLID& clid, const std::string& key,
                    << fullProxyName(clid,key) << " not registered"  );
     return StatusCode::FAILURE;
   } else {
-    return ist->getRangeFromDB( clid, key, range, tag, ioa );
+    
+    //Get current time form thread-local context
+    const EventContext& context = Gaudi::Hive::currentContext();
+    const EventIDBase& eventID = context.eventID();
+    uint32_t event = eventID.lumi_block();
+    uint32_t run   = eventID.run_number();
+    IOVTime curTime;
+    curTime.setRunEvent(run,event);
+    // get ns timestamp from event
+    curTime.setTimestamp(1000000000L*(uint64_t)eventID.time_stamp() + eventID.time_stamp_ns_offset());
+
+
+    return ist->getRangeFromDB( clid, key, range, tag, ioa, curTime );
   }
 
 }
diff --git a/Control/IOVSvc/src/IOVSvcTool.cxx b/Control/IOVSvc/src/IOVSvcTool.cxx
index 3262ad00c508..b6a0deffe7ac 100644
--- a/Control/IOVSvc/src/IOVSvcTool.cxx
+++ b/Control/IOVSvc/src/IOVSvcTool.cxx
@@ -227,9 +227,9 @@ IOVSvcTool::initialize() {
 void 
 IOVSvcTool::handle(const Incident &inc) {
 
-  uint32_t event, run;
-  
-  std::string objname;
+  //The first part of the handle-function is non-const and not re-entrant
+  //In MT mode, only called during the serial part at the beginning of the job 
+  //(hopefully)
 
   const bool first = m_first;
   if (m_first) m_first = false;
@@ -253,9 +253,9 @@ IOVSvcTool::handle(const Incident &inc) {
         ATH_MSG_DEBUG("will ignore resetting proxy " << fullProxyName(proxy));
       }
     }
-  }
+  }//end first
+
 
-  set< DataProxy*, SortDPptr > proxiesToReset;
 
   // Forcing IOV checks on the first event in the run for AthenaMP (ATEAM-439)
   if(Gaudi::Concurrency::ConcurrencyFlags::numProcs()==0) {
@@ -271,25 +271,26 @@ IOVSvcTool::handle(const Incident &inc) {
     }
   }
 
+  set< DataProxy*, SortDPptr > proxiesToReset;
   if ( inc.type() == m_checkTrigger || inc.type() == IncidentType::BeginRun ) {
 
     const EventContext& context = inc.context();
 
-    m_curTime.reset();
+    IOVTime curTime;
     
     const EventIDBase& eventID = context.eventID();
-    event = eventID.lumi_block();
-    run   = eventID.run_number();
+    uint32_t event = eventID.lumi_block();
+    uint32_t run   = eventID.run_number();
     
     ATH_MSG_DEBUG("Got event info: " << "run="<< run << ", event=" << event);
-    m_curTime.setRunEvent(run,event);
+    curTime.setRunEvent(run,event);
 
     // get ns timestamp from event
-    m_curTime.setTimestamp(1000000000L*(uint64_t)eventID.time_stamp() + eventID.time_stamp_ns_offset());
+    curTime.setTimestamp(1000000000L*(uint64_t)eventID.time_stamp() + eventID.time_stamp_ns_offset());
 
     if (msgLvl(MSG::DEBUG)) {
       msg().setColor(MSG::YELLOW,MSG::RED);
-      msg() << inc.type() << ": [R/LB] = " << m_curTime << endmsg;
+      msg() << inc.type() << ": [R/LB] = " << curTime << endmsg;
     }
 
     if (inc.type() == IncidentType::BeginRun) {
@@ -299,14 +300,14 @@ IOVSvcTool::handle(const Incident &inc) {
         ATH_MSG_DEBUG("Unable to get the IOVDbSvc");
         return;
       }
-      if (StatusCode::SUCCESS != iovDB->signalBeginRun(m_curTime,
+      if (StatusCode::SUCCESS != iovDB->signalBeginRun(curTime,
                                                        inc.context()))
       {
         ATH_MSG_ERROR("Unable to signal begin run to IOVDbSvc");
         return;
       }
       else {
-        ATH_MSG_DEBUG("Signaled begin run to IOVDbSvc " << m_curTime);
+        ATH_MSG_DEBUG("Signaled begin run to IOVDbSvc " << curTime);
       }
     }
     
@@ -343,9 +344,9 @@ IOVSvcTool::handle(const Incident &inc) {
       IIOVDbSvc *iovDB = nullptr;
       if (service("IOVDbSvc", iovDB, false).isSuccess()) {
         iovDB->signalEndProxyPreload();
-        ATH_MSG_DEBUG("Signaled end proxy preload to IOVDbSvc " << m_curTime);
+        ATH_MSG_DEBUG("Signaled end proxy preload to IOVDbSvc " << curTime);
       }
-    }
+    }// end if first
     
     // If preLoadData has been set, never check validity of data again.
     if (m_preLoadData && m_checkOnce) {
@@ -376,18 +377,18 @@ IOVSvcTool::handle(const Incident &inc) {
       if (msgLvl(MSG::VERBOSE)) {
         std::set< const SG::DataProxy* >::const_iterator pit;
         for (SG::DataProxy* p : m_proxies) {
-          msg() << "   " << m_names[p] << std::endl;
+          msg() << "   " << m_names.at(p) << std::endl;
         }
         msg() << endmsg;
       }
       proxiesToReset = m_proxies;
       m_triggered = false;
     } else {
-      scanStartSet(m_startSet_Clock,"(ClockTime)",proxiesToReset);
-      scanStartSet(m_startSet_RE,"(R/E)",proxiesToReset);
+      scanStartSet(m_startSet_Clock,"(ClockTime)",proxiesToReset,curTime);
+      scanStartSet(m_startSet_RE,"(R/E)",proxiesToReset,curTime);
 
-      scanStopSet(m_stopSet_Clock,"(ClockTime)",proxiesToReset);
-      scanStopSet(m_stopSet_RE,"(R/E)",proxiesToReset);
+      scanStopSet(m_stopSet_Clock,"(ClockTime)",proxiesToReset,curTime);
+      scanStopSet(m_stopSet_RE,"(R/E)",proxiesToReset,curTime);
     }
 
     for (auto p : m_ignoredProxies) {
@@ -413,7 +414,7 @@ IOVSvcTool::handle(const Incident &inc) {
     //// 
     //
     for (DataProxy* prx : proxiesToReset) {
-      ATH_MSG_VERBOSE("clearing proxy payload for " << m_names[prx]);
+      ATH_MSG_VERBOSE("clearing proxy payload for " << m_names.at(prx));
 
       // Reset proxy except when one wants to reset callbacks
       
@@ -429,9 +430,9 @@ IOVSvcTool::handle(const Incident &inc) {
            m_preLoadData ) {       
         ATH_MSG_VERBOSE("preloading data");
 
-        Gaudi::Guards::AuditorGuard auditor(m_names[prx], auditorSvc(), "preLoadProxy");
+        Gaudi::Guards::AuditorGuard auditor(m_names.at(prx), auditorSvc(), "preLoadProxy");
         if (prx->accessData() == nullptr) {
-          ATH_MSG_ERROR("problems preloading data for " << m_names[prx]);
+          ATH_MSG_ERROR("problems preloading data for " << m_names.at(prx));
         }
       }
 
@@ -460,15 +461,16 @@ IOVSvcTool::handle(const Incident &inc) {
 
           if (node->trigger()) {
             BFCN *ff = node->fcn();
-            auditorSvc()->before("Callback",m_fcnMap[ff].name());
+            auditorSvc()->before("Callback",m_fcnMap.at(ff).name());
             if ((*ff)(i,resetKeys[ff]).isFailure()) {
-              auditorSvc()->after("Callback",m_fcnMap[ff].name());
-              ATH_MSG_ERROR("Problems calling " << m_fcnMap[ff].name()
+              auditorSvc()->after("Callback",m_fcnMap.at(ff).name());
+              ATH_MSG_ERROR("Problems calling " << m_fcnMap.at(ff).name()
                             << std::endl << "Skipping all subsequent callbacks.");
               // this will cause a mem leak, but I don't care
-              perr = new IOVCallbackError(m_fcnMap[ff].name());
-              break;            }
-            auditorSvc()->after("Callback",m_fcnMap[ff].name());
+              perr = new IOVCallbackError(m_fcnMap.at(ff).name());
+              break;            
+	    }
+	    auditorSvc()->after("Callback",m_fcnMap.at(ff).name());
 
           }
         }
@@ -496,10 +498,10 @@ IOVSvcTool::handle(const Incident &inc) {
     std::map<const DataProxy*, IOVEntry*>::iterator pitr;
     for (DataProxy* prx : proxiesToReset) {
       pitr = m_entries.find( prx );
-      if ( pitr != m_entries.end() && pitr->second->range()->isInRange(m_curTime) ) {
-        ATH_MSG_VERBOSE("range still valid for " << m_names[prx]);
+      if ( pitr != m_entries.end() && pitr->second->range()->isInRange(curTime) ) {
+        ATH_MSG_VERBOSE("range still valid for " << m_names.at(prx));
       } else {
-        ATH_MSG_DEBUG("calling provider()->udpateAddress(TAD) for " << m_names[prx]   );
+        ATH_MSG_DEBUG("calling provider()->udpateAddress(TAD) for " << m_names.at(prx)   );
         if (!prx->updateAddress()) {
           ATH_MSG_ERROR("handle: Could not update address");
           if (perr != nullptr) throw (*perr);
@@ -870,10 +872,11 @@ IOVSvcTool::getRange(const CLID& clid, const std::string& key,
 StatusCode 
 IOVSvcTool::getRangeFromDB(const CLID& clid, const std::string& key, 
                            IOVRange& range, std::string &tag, 
-                           std::unique_ptr<IOpaqueAddress>& ioa) const {
+                           std::unique_ptr<IOpaqueAddress>& ioa, 
+			   const IOVTime& curTime) const {
 
-  if (m_curTime.isValid()) {
-    return getRangeFromDB(clid, key, m_curTime, range, tag, ioa);
+  if (curTime.isValid()) {
+    return getRangeFromDB(clid, key, curTime, range, tag, ioa);
   } else {
     ATH_MSG_ERROR("Current Event not defined");
     return StatusCode::FAILURE;
@@ -1098,14 +1101,14 @@ IOVSvcTool::triggerCallback( const SG::DataProxy *dp,
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 void 
-IOVSvcTool::PrintStartSet() {
+IOVSvcTool::PrintStartSet() const {
   startITR start_itr;
   std::string objname;
   
   if (m_startSet_Clock.begin() != m_startSet_Clock.end()) {
     msg() << endl << "ClockTime start set: " << endl;
     for (start_itr = m_startSet_Clock.begin(); start_itr!=m_startSet_Clock.end(); ++start_itr ) {
-      objname = m_names[ (*start_itr)->proxy() ];
+      objname = m_names.at( (*start_itr)->proxy() );
       msg() << "  " << objname << " (" << (*start_itr)->proxy() << ") "
             << (*start_itr)->range()->start() << endl;    
     }
@@ -1115,7 +1118,7 @@ IOVSvcTool::PrintStartSet() {
   if (m_startSet_RE.begin() != m_startSet_RE.end()) {
     msg() << "Run/Event start set: " << endl;
     for (start_itr = m_startSet_RE.begin(); start_itr!=m_startSet_RE.end();++start_itr ) {
-      objname = m_names[ (*start_itr)->proxy() ];
+      objname = m_names.at( (*start_itr)->proxy() );
       msg() << "  " << objname << " (" << (*start_itr)->proxy() << ") "
             << (*start_itr)->range()->start() << endl;    
     }
@@ -1126,14 +1129,14 @@ IOVSvcTool::PrintStartSet() {
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 void 
-IOVSvcTool::PrintStopSet() {
+IOVSvcTool::PrintStopSet() const {
   stopITR  stop_itr;
   std::string objname;
   
   if (m_stopSet_Clock.begin() != m_stopSet_Clock.end()) {
     msg() << endl << "ClockTime stop set: " << endl;
     for( stop_itr=m_stopSet_Clock.begin(); stop_itr!=m_stopSet_Clock.end(); ++stop_itr ) {
-      objname = m_names[ (*stop_itr)->proxy() ];
+      objname = m_names.at((*stop_itr)->proxy());
       msg() << "  " << objname << " (" << (*stop_itr)->proxy() << ") "
             << (*stop_itr)->range()->stop() << endl;    
     }
@@ -1143,7 +1146,7 @@ IOVSvcTool::PrintStopSet() {
   if (m_stopSet_RE.begin() != m_stopSet_RE.end()) {
     msg() << "Run/Event stop set: " << endl;
     for( stop_itr=m_stopSet_RE.begin(); stop_itr!=m_stopSet_RE.end(); ++stop_itr ) {
-      objname = m_names[ (*stop_itr)->proxy() ];
+      objname = m_names.at((*stop_itr)->proxy());
       msg() << "  " << objname << " (" << (*stop_itr)->proxy() << ") "
             << (*stop_itr)->range()->stop() << endl;    
     }
@@ -1153,7 +1156,7 @@ IOVSvcTool::PrintStopSet() {
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 void 
-IOVSvcTool::PrintProxyMap(){
+IOVSvcTool::PrintProxyMap() const{
   msg() << endl;
   msg() << "------------------------------  IOVSvc Proxy Map  "
         << "------------------------------" << endl;
@@ -1168,18 +1171,15 @@ IOVSvcTool::PrintProxyMap(){
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 void 
-IOVSvcTool::PrintProxyMap(const SG::DataProxy* dp){
+IOVSvcTool::PrintProxyMap(const SG::DataProxy* dp) const {
 
   msg() << "  " << dp << "  " << dp->clID() << "  "
         << m_names.find(dp)->second << endl;
-
-  pair<pmITR,pmITR> pi = m_proxyMap.equal_range(dp);
-  pmITR pitr;
-  
+  auto pi = m_proxyMap.equal_range(dp);
   if (pi.first == pi.second) {
     msg() << "         ->  no callback associated" << endl;
   } else {
-    for (pitr=pi.first; pitr!=pi.second; ++pitr) {
+    for (auto pitr=pi.first; pitr!=pi.second; ++pitr) {
       BFCN* fcn = pitr->second;
       map<BFCN*,CallBackID>::const_iterator fitr = m_fcnMap.find(fcn);
       CallBackID cbid = fitr->second;
@@ -1445,7 +1445,8 @@ IOVSvcTool::reinitialize(){
 
 void 
 IOVSvcTool::scanStartSet(startSet &pSet, const std::string &type, 
-                         std::set<SG::DataProxy*, SortDPptr> &proxiesToReset) {
+                         std::set<SG::DataProxy*, SortDPptr> &proxiesToReset,
+			 const IOVTime& curTime) const {
 
   std::string objname;
   
@@ -1458,9 +1459,9 @@ IOVSvcTool::scanStartSet(startSet &pSet, const std::string &type,
   startITR start_itr( pSet.begin() );
   while ( start_itr != pSet.end() ) {
     
-    if (m_resetAllCallbacks || (*start_itr)->range()->start() > m_curTime) {
+    if (m_resetAllCallbacks || (*start_itr)->range()->start() > curTime) {
       if (msgLvl(MSG::DEBUG)) {
-        msg() << "\t" << m_names[ (*start_itr)->proxy() ] << ": "
+        msg() << "\t" << m_names.at((*start_itr)->proxy()) << ": "
               << (*start_itr)->range()->start()<<"   <- removed"<<endl;
       }
       proxiesToReset.insert( (*start_itr)->proxy() );
@@ -1483,7 +1484,8 @@ IOVSvcTool::scanStartSet(startSet &pSet, const std::string &type,
 
 void 
 IOVSvcTool::scanStopSet(stopSet &pSet, const std::string &type,
-                        std::set<SG::DataProxy*, SortDPptr> &proxiesToReset) {
+                        std::set<SG::DataProxy*, SortDPptr> &proxiesToReset,
+			const IOVTime& curTime) const {
 
   std::string objname;
 
@@ -1495,9 +1497,9 @@ IOVSvcTool::scanStopSet(stopSet &pSet, const std::string &type,
   stopITR  stop_itr(pSet.begin());
   while ( stop_itr != pSet.end() ) {
     
-    if (m_resetAllCallbacks || (*stop_itr)->range()->stop() <= m_curTime) {
+    if (m_resetAllCallbacks || (*stop_itr)->range()->stop() <= curTime) {
       if (msgLvl(MSG::DEBUG)) {
-        msg() << "   " << m_names[ (*stop_itr)->proxy() ] << ": "
+        msg() << "   " << m_names.at((*stop_itr)->proxy()) << ": "
               << (*stop_itr)->range()->stop()<< "  -> removed"<<endl;
       }
       proxiesToReset.insert( (*stop_itr)->proxy() );
diff --git a/Control/IOVSvc/src/IOVSvcTool.h b/Control/IOVSvc/src/IOVSvcTool.h
index 7b7bfd4ddb61..c61d2d0b6358 100644
--- a/Control/IOVSvc/src/IOVSvcTool.h
+++ b/Control/IOVSvc/src/IOVSvcTool.h
@@ -125,7 +125,8 @@ public:
   // Get IOVRange from db for current event
   virtual StatusCode getRangeFromDB(const CLID& clid, const std::string& key, 
                                     IOVRange& range, std::string &tag,
-                                    std::unique_ptr<IOpaqueAddress>& ioa) const override;
+                                    std::unique_ptr<IOpaqueAddress>& ioa,
+				    const IOVTime& curTime) const override;
 
   // Get IOVRange from db for a particular event
   virtual StatusCode getRangeFromDB(const CLID& clid, const std::string& key, 
@@ -187,7 +188,7 @@ private:
   ServiceHandle<IClassIDSvc> p_CLIDSvc;
   ServiceHandle<IToolSvc> p_toolSvc;
 
-  IOVTime m_curTime{0};
+  //IOVTime m_curTime{0};
 
   typedef IOVSvcCallBackFcn BFCN;
   typedef std::multimap<const SG::DataProxy*, BFCN*>::iterator pmITR;
@@ -235,7 +236,7 @@ private:
   bool m_checkOnce{false};
   bool m_triggered{false};
   bool m_firstEventOfRun{false};
-  bool m_resetAllCallbacks{false};
+  bool m_resetAllCallbacks{false}; 
   std::string m_checkTrigger;
 
   Gaudi::Property<bool> m_preLoadRanges{this, "preLoadRanges", false};
@@ -248,14 +249,16 @@ private:
 
 
   void scanStartSet(startSet &pSet, const std::string &type,
-                    std::set<SG::DataProxy*, SortDPptr> &proxiesToReset);
+                    std::set<SG::DataProxy*, SortDPptr> &proxiesToReset,
+		    const IOVTime& curTime) const;
   void scanStopSet(stopSet &pSet, const std::string &type,
-                   std::set<SG::DataProxy*, SortDPptr> &proxiesToReset);
+                   std::set<SG::DataProxy*, SortDPptr> &proxiesToReset,
+		   const IOVTime& curTime) const;
 
-  void PrintStartSet();
-  void PrintStopSet();
-  void PrintProxyMap();
-  void PrintProxyMap(const SG::DataProxy*);
+  void PrintStartSet() const;
+  void PrintStopSet() const;
+  void PrintProxyMap() const;
+  void PrintProxyMap(const SG::DataProxy*) const;
 
 };
 
-- 
GitLab