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.
This commit is contained in:
+13
-2
@@ -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
|
||||
*/
|
||||
|
||||
@@ -283,6 +283,7 @@ private:
|
||||
unsigned beaconAnomalyCount;
|
||||
unsigned short _serverPort;
|
||||
unsigned iiuExistenceCount;
|
||||
bool cacShutdownInProgress;
|
||||
|
||||
void recycleReadNotifyIO (
|
||||
epicsGuard < epicsMutex > &, netReadNotifyIO &io );
|
||||
|
||||
Reference in New Issue
Block a user