From a0a9ee45530009092c814770e43bd403841e7957 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Mon, 23 Aug 2010 16:17:16 -0400 Subject: [PATCH] ca: Avoid possible race condition during cac shutdown. While the cac dtor runs and waits for TCP circuit threads to exit, new circuits could be opened by name resolution replies on existing (still active) circuits. Avoid this by setting a flag (lock being held) in the dtor, and checking it in cac::transferChanToVirtCircuit. --- src/ca/cac.cpp | 15 +++++++++++++-- src/ca/cac.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index 93de57480..42a491fec 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -146,7 +146,8 @@ cac::cac ( maxRecvBytesTCP ( MAX_TCP ), maxContigFrames ( contiguousMsgCountWhichTriggersFlowControl ), beaconAnomalyCount ( 0u ), - iiuExistenceCount ( 0u ) + iiuExistenceCount ( 0u ), + cacShutdownInProgress ( false ) { if ( ! osiSockAttach () ) { throwWithLocation ( caErrorCode (ECA_INTERNAL) ); @@ -282,7 +283,10 @@ cac::~cac () epicsGuard < epicsMutex > guard ( this->mutex ); if ( this->pudpiiu ) { this->pudpiiu->shutdown ( cbGuard, guard ); - + + // make sure no new tcp circuits are created + this->cacShutdownInProgress = true; + // // shutdown all tcp circuits // @@ -575,6 +579,13 @@ void cac::transferChanToVirtCircuit ( epicsGuard < epicsMutex > guard ( this->mutex ); + /* + * Do not open new circuits while the cac is shutting down + */ + if ( this->cacShutdownInProgress ) { + return; + } + /* * ignore search replies for deleted channels */ diff --git a/src/ca/cac.h b/src/ca/cac.h index 354704f43..4bac0cdb1 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -283,6 +283,7 @@ private: unsigned beaconAnomalyCount; unsigned short _serverPort; unsigned iiuExistenceCount; + bool cacShutdownInProgress; void recycleReadNotifyIO ( epicsGuard < epicsMutex > &, netReadNotifyIO &io );