From 05f943341cb0f15a55a380fb431904f5a247d7c7 Mon Sep 17 00:00:00 2001
From: abarton <Adam.Edward.Barton@cern.ch>
Date: Fri, 18 Jan 2019 11:23:32 +0000
Subject: [PATCH] Fix bug where algorthm returns before both objects are
 checked. Made reentrant, minor optimizations

---
 .../src/PixelDCSCondStateAlg.cxx              | 166 +++++++++---------
 .../src/PixelDCSCondStateAlg.h                |   6 +-
 2 files changed, 85 insertions(+), 87 deletions(-)

diff --git a/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixelDCSCondStateAlg.cxx b/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixelDCSCondStateAlg.cxx
index 20d9d369839..66d213198d5 100644
--- a/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixelDCSCondStateAlg.cxx
+++ b/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixelDCSCondStateAlg.cxx
@@ -8,7 +8,7 @@
 #include <memory>
 
 PixelDCSCondStateAlg::PixelDCSCondStateAlg(const std::string& name, ISvcLocator* pSvcLocator):
-  ::AthAlgorithm(name, pSvcLocator),
+  ::AthReentrantAlgorithm(name, pSvcLocator),
   m_condSvc("CondSvc", name)
 {
 }
@@ -34,103 +34,101 @@ StatusCode PixelDCSCondStateAlg::initialize() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode PixelDCSCondStateAlg::execute() {
+StatusCode PixelDCSCondStateAlg::execute(const EventContext& ctx) const {
   ATH_MSG_DEBUG("PixelDCSCondStateAlg::execute()");
 
   //===========
   // FSM_STATE
   //===========
-  SG::WriteCondHandle<PixelDCSConditionsData> writeHandleState(m_writeKeyState);
+  SG::WriteCondHandle<PixelDCSConditionsData> writeHandleState(m_writeKeyState, ctx);
   if (writeHandleState.isValid()) {
     ATH_MSG_DEBUG("CondHandle " << writeHandleState.fullKey() << " is already valid.. In theory this should not be called, but may happen if multiple concurrent events are being processed out of order.");
-    return StatusCode::SUCCESS; 
+  }else{
+     SG::ReadCondHandle<CondAttrListCollection> readHandleState(m_readKeyState, ctx);
+     const CondAttrListCollection* readCdoState(*readHandleState); 
+     if (readCdoState==nullptr) {
+       ATH_MSG_FATAL("Null pointer to the read conditions object (state)");
+       return StatusCode::FAILURE;
+     }
+     // Get the validitiy range (state)
+     EventIDRange rangeState;
+     if (not readHandleState.range(rangeState)) {
+       ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandleState.key());
+       return StatusCode::FAILURE;
+     }
+     ATH_MSG_INFO("Size of CondAttrListCollection " << readHandleState.fullKey() << " readCdo->size()= " << readCdoState->size());
+     ATH_MSG_INFO("Range of state input is " << rangeState);
+     
+     // Construct the output Cond Object and fill it in
+     std::unique_ptr<PixelDCSConditionsData> writeCdoState(std::make_unique<PixelDCSConditionsData>());
+   
+     // Read state info
+     std::string paramState = "FSM_state";
+     for (CondAttrListCollection::const_iterator attrListState=readCdoState->begin(); attrListState!=readCdoState->end(); ++attrListState) {
+       const CondAttrListCollection::ChanNum &channelNumber = attrListState->first;
+       const CondAttrListCollection::AttributeList &payload = attrListState->second;
+       if (payload.exists(paramState.c_str()) and not payload[paramState.c_str()].isNull()) {
+         std::string val = payload[paramState.c_str()].data<std::string>();
+         writeCdoState -> setValue(channelNumber, val);
+       } 
+       else {
+         ATH_MSG_WARNING(paramState << " does not exist for ChanNum " << channelNumber);
+         writeCdoState -> setValue(channelNumber, "NO_DATA");
+       }
+     }
+   
+     if (writeHandleState.record(rangeState, std::move(writeCdoState)).isFailure()) {
+       ATH_MSG_FATAL("Could not record PixelDCSConditionsData " << writeHandleState.key() << " with EventRange " << rangeState << " into Conditions Store");
+       return StatusCode::FAILURE;
+     }
+     ATH_MSG_INFO("recorded new CDO " << writeHandleState.key() << " with range " << rangeState << " into Conditions Store");
   }
-  SG::ReadCondHandle<CondAttrListCollection> readHandleState(m_readKeyState);
-  const CondAttrListCollection* readCdoState(*readHandleState); 
-  if (readCdoState==nullptr) {
-    ATH_MSG_FATAL("Null pointer to the read conditions object (state)");
-    return StatusCode::FAILURE;
-  }
-  // Get the validitiy range (state)
-  EventIDRange rangeState;
-  if (not readHandleState.range(rangeState)) {
-    ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandleState.key());
-    return StatusCode::FAILURE;
-  }
-  ATH_MSG_INFO("Size of CondAttrListCollection " << readHandleState.fullKey() << " readCdo->size()= " << readCdoState->size());
-  ATH_MSG_INFO("Range of state input is " << rangeState);
-  
-  // Construct the output Cond Object and fill it in
-  std::unique_ptr<PixelDCSConditionsData> writeCdoState(std::make_unique<PixelDCSConditionsData>());
-
-  // Read state info
-  std::string paramState = "FSM_state";
-  for (CondAttrListCollection::const_iterator attrListState=readCdoState->begin(); attrListState!=readCdoState->end(); ++attrListState) {
-    CondAttrListCollection::ChanNum channelNumber = attrListState->first;
-    CondAttrListCollection::AttributeList payload = attrListState->second;
-    if (payload.exists(paramState.c_str()) and not payload[paramState.c_str()].isNull()) {
-      std::string val = payload[paramState.c_str()].data<std::string>();
-      writeCdoState -> setValue(channelNumber, val);
-    } 
-    else {
-      ATH_MSG_WARNING(paramState << " does not exist for ChanNum " << channelNumber);
-      writeCdoState -> setValue(channelNumber, "NO_DATA");
-    }
-  }
-
-  if (writeHandleState.record(rangeState, std::move(writeCdoState)).isFailure()) {
-    ATH_MSG_FATAL("Could not record PixelDCSConditionsData " << writeHandleState.key() << " with EventRange " << rangeState << " into Conditions Store");
-    return StatusCode::FAILURE;
-  }
-  ATH_MSG_INFO("recorded new CDO " << writeHandleState.key() << " with range " << rangeState << " into Conditions Store");
-
   //============
   // FSM_STATUS
   //============
-  SG::WriteCondHandle<PixelDCSConditionsData> writeHandleStatus(m_writeKeyStatus);
+  SG::WriteCondHandle<PixelDCSConditionsData> writeHandleStatus(m_writeKeyStatus, ctx);
   if (writeHandleStatus.isValid()) {
     ATH_MSG_DEBUG("CondHandle " << writeHandleStatus.fullKey() << " is already valid.. In theory this should not be called, but may happen if multiple concurrent events are being processed out of order.");
-    return StatusCode::SUCCESS; 
+  }else{
+     SG::ReadCondHandle<CondAttrListCollection> readHandleStatus(m_readKeyStatus, ctx);
+     const CondAttrListCollection* readCdoStatus(*readHandleStatus); 
+     if (readCdoStatus==nullptr) {
+       ATH_MSG_FATAL("Null pointer to the read conditions object (state)");
+       return StatusCode::FAILURE;
+     }
+     // Get the validitiy range (state)
+     EventIDRange rangeStatus;
+     if (not readHandleStatus.range(rangeStatus)) {
+       ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandleStatus.key());
+       return StatusCode::FAILURE;
+     }
+     ATH_MSG_INFO("Size of CondAttrListCollection " << readHandleStatus.fullKey() << " readCdo->size()= " << readCdoStatus->size());
+     ATH_MSG_INFO("Range of state input is " << rangeStatus);
+     
+     // Construct the output Cond Object and fill it in
+     std::unique_ptr<PixelDCSConditionsData> writeCdoStatus(std::make_unique<PixelDCSConditionsData>());
+   
+     // Read state info
+     std::string paramStatus = "FSM_status";
+     for (CondAttrListCollection::const_iterator attrListStatus=readCdoStatus->begin(); attrListStatus!=readCdoStatus->end(); ++attrListStatus) {
+       const CondAttrListCollection::ChanNum &channelNumber = attrListStatus->first;
+       const CondAttrListCollection::AttributeList &payload = attrListStatus->second;
+       if (payload.exists(paramStatus.c_str()) and not payload[paramStatus.c_str()].isNull()) {
+         std::string val = payload[paramStatus.c_str()].data<std::string>();
+         writeCdoStatus -> setValue(channelNumber, val);
+       } 
+       else {
+         ATH_MSG_WARNING(paramStatus << " does not exist for ChanNum " << channelNumber);
+         writeCdoStatus -> setValue(channelNumber, "NO_DATA");
+       }
+     }
+   
+     if (writeHandleStatus.record(rangeStatus, std::move(writeCdoStatus)).isFailure()) {
+       ATH_MSG_FATAL("Could not record PixelDCSConditionsData " << writeHandleStatus.key() << " with EventRange " << rangeStatus << " into Conditions Store");
+       return StatusCode::FAILURE;
+     }
+     ATH_MSG_INFO("recorded new CDO " << writeHandleStatus.key() << " with range " << rangeStatus << " into Conditions Store");
   }
-  SG::ReadCondHandle<CondAttrListCollection> readHandleStatus(m_readKeyStatus);
-  const CondAttrListCollection* readCdoStatus(*readHandleStatus); 
-  if (readCdoStatus==nullptr) {
-    ATH_MSG_FATAL("Null pointer to the read conditions object (state)");
-    return StatusCode::FAILURE;
-  }
-  // Get the validitiy range (state)
-  EventIDRange rangeStatus;
-  if (not readHandleStatus.range(rangeStatus)) {
-    ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandleStatus.key());
-    return StatusCode::FAILURE;
-  }
-  ATH_MSG_INFO("Size of CondAttrListCollection " << readHandleStatus.fullKey() << " readCdo->size()= " << readCdoStatus->size());
-  ATH_MSG_INFO("Range of state input is " << rangeStatus);
-  
-  // Construct the output Cond Object and fill it in
-  std::unique_ptr<PixelDCSConditionsData> writeCdoStatus(std::make_unique<PixelDCSConditionsData>());
-
-  // Read state info
-  std::string paramStatus = "FSM_status";
-  for (CondAttrListCollection::const_iterator attrListStatus=readCdoStatus->begin(); attrListStatus!=readCdoStatus->end(); ++attrListStatus) {
-    CondAttrListCollection::ChanNum channelNumber = attrListStatus->first;
-    CondAttrListCollection::AttributeList payload = attrListStatus->second;
-    if (payload.exists(paramStatus.c_str()) and not payload[paramStatus.c_str()].isNull()) {
-      std::string val = payload[paramStatus.c_str()].data<std::string>();
-      writeCdoStatus -> setValue(channelNumber, val);
-    } 
-    else {
-      ATH_MSG_WARNING(paramStatus << " does not exist for ChanNum " << channelNumber);
-      writeCdoStatus -> setValue(channelNumber, "NO_DATA");
-    }
-  }
-
-  if (writeHandleStatus.record(rangeStatus, std::move(writeCdoStatus)).isFailure()) {
-    ATH_MSG_FATAL("Could not record PixelDCSConditionsData " << writeHandleStatus.key() << " with EventRange " << rangeStatus << " into Conditions Store");
-    return StatusCode::FAILURE;
-  }
-  ATH_MSG_INFO("recorded new CDO " << writeHandleStatus.key() << " with range " << rangeStatus << " into Conditions Store");
-
   return StatusCode::SUCCESS;
 }
 
diff --git a/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixelDCSCondStateAlg.h b/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixelDCSCondStateAlg.h
index 92be61b01c2..546f92d4e5b 100644
--- a/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixelDCSCondStateAlg.h
+++ b/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixelDCSCondStateAlg.h
@@ -5,7 +5,7 @@
 #ifndef PIXELDCSCONDSTATEALG
 #define PIXELDCSCONDSTATEALG
 
-#include "AthenaBaseComps/AthAlgorithm.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
 
 #include "StoreGate/ReadCondHandleKey.h"
 #include "AthenaPoolUtilities/CondAttrListCollection.h"
@@ -16,13 +16,13 @@
 #include "GaudiKernel/ICondSvc.h"
 #include "GaudiKernel/Property.h"
 
-class PixelDCSCondStateAlg : public AthAlgorithm {  
+class PixelDCSCondStateAlg : public AthReentrantAlgorithm {  
   public:
     PixelDCSCondStateAlg(const std::string& name, ISvcLocator* pSvcLocator);
     virtual ~PixelDCSCondStateAlg() = default;
 
     virtual StatusCode initialize() override;
-    virtual StatusCode execute() override;
+    virtual StatusCode execute(const EventContext& ctx) const override;
     virtual StatusCode finalize() override;
 
   private:
-- 
GitLab