From 2654d383f52098c1f216478507e2f77fcc4bdc71 Mon Sep 17 00:00:00 2001
From: scott snyder <snyder@bnl.gov>
Date: Tue, 15 Dec 2020 16:17:58 +0100
Subject: [PATCH] StoreGate: Fix potential deadlock in removeProxy.

In removeProxy(), don't try to get a pointer from a proxy if it's
not valid.  Doing so may trigger I/O.  Besides being useless here,
we may get deadlocks if we call into I/O code while holding the SG lock.

See ATEAM-685.
---
 Control/StoreGate/src/SGImplSvc.cxx | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/Control/StoreGate/src/SGImplSvc.cxx b/Control/StoreGate/src/SGImplSvc.cxx
index 66d8f08d59c3..225df8b11272 100644
--- a/Control/StoreGate/src/SGImplSvc.cxx
+++ b/Control/StoreGate/src/SGImplSvc.cxx
@@ -1311,15 +1311,21 @@ SGImplSvc::removeProxy(DataProxy* proxy, const void* pTrans,
   }
 
   // remove all entries from t2p map
-  this->t2pRemove(pTrans);
-  SG::DataProxy::CLIDCont_t clids = proxy->transientID();
-  for (SG::DataProxy::CLIDCont_t::const_iterator i = clids.begin();
-       i != clids.end();
-       ++i)
+  //  --- only if the proxy actually has an object!
+  //      otherwise, we can trigger I/O.
+  //      besides being useless here, we can get deadlocks if we
+  //      call into the I/O code while holding the SG lock.
+  if (proxy->isValidObject()) {
+    this->t2pRemove(pTrans);
+    SG::DataProxy::CLIDCont_t clids = proxy->transientID();
+    for (SG::DataProxy::CLIDCont_t::const_iterator i = clids.begin();
+         i != clids.end();
+         ++i)
     {
       void* ptr = SG::DataProxy_cast (proxy, *i);
       this->t2pRemove(ptr);
     }
+  }
 
   // remove from store
   return m_pStore->removeProxy(proxy, forceRemove, true);
-- 
GitLab