ca: Fix client bug (race condition) in ipAddrToAsciiEngine

This commit is contained in:
Ralph Lange
2016-05-25 12:26:32 +02:00
parent 988614ae8a
commit 23fd4e202b
5 changed files with 25 additions and 5 deletions

View File

@@ -333,6 +333,12 @@ cac::~cac ()
this->ipToAEngine.release ();
// clean-up the list of un-notified msg objects
while ( msgForMultiplyDefinedPV * msg = this->msgMultiPVList.get() ) {
msg->~msgForMultiplyDefinedPV ();
this->mdpvFreeList.release ( msg );
}
errlogFlush ();
osiSockRelease ();
@@ -606,6 +612,8 @@ void cac::transferChanToVirtCircuit (
msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList )
msgForMultiplyDefinedPV ( this->ipToAEngine,
*this, pChan->pName ( guard ), acc );
// cac keeps a list of these objects for proper clean-up in ~cac
this->msgMultiPVList.add ( *pMsg );
// It is possible for the ioInitiate call below to
// call the callback directly if queue quota is exceeded.
// This callback takes the callback lock and therefore we
@@ -1297,6 +1305,8 @@ void cac::pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv,
epicsGuard < epicsMutex > guard ( this->mutex );
this->exception ( mgr.cbGuard, guard, ECA_DBLCHNL, buf, __FILE__, __LINE__ );
}
// remove from the list and delete msg object
this->msgMultiPVList.remove ( mfmdpv );
mfmdpv.~msgForMultiplyDefinedPV ();
this->mdpvFreeList.release ( & mfmdpv );
}

View File

@@ -237,6 +237,7 @@ private:
resTable < tcpiiu, caServerID > serverTable;
tsDLList < tcpiiu > circuitList;
tsDLList < SearchDest > searchDestList;
tsDLList < msgForMultiplyDefinedPV > msgMultiPVList;
tsFreeList
< class tcpiiu, 32, epicsMutexNOOP >
freeListVirtualCircuit;

View File

@@ -55,8 +55,10 @@ msgForMultiplyDefinedPV::~msgForMultiplyDefinedPV ()
void msgForMultiplyDefinedPV::transactionComplete ( const char * pHostNameRej )
{
// calls into cac for the notification
// the msg object (= this) is being deleted as part of the notification
this->cb.pvMultiplyDefinedNotify ( *this, this->channel, this->acc, pHostNameRej );
// !! dont touch this pointer after this point because object has been deleted !!
// !! dont touch 'this' pointer after this point because object has been deleted !!
}
void * msgForMultiplyDefinedPV::operator new ( size_t size,

View File

@@ -33,6 +33,7 @@
#include "ipAddrToAsciiAsynchronous.h"
#include "tsFreeList.h"
#include "tsDLList.h"
#include "compilerDependencies.h"
#ifdef msgForMultiplyDefinedPVh_epicsExportSharedSymbols
@@ -47,7 +48,9 @@ public:
const char * pAcc, const char * pRej ) = 0;
};
class msgForMultiplyDefinedPV : public ipAddrToAsciiCallBack {
class msgForMultiplyDefinedPV :
public ipAddrToAsciiCallBack,
public tsDLNode < msgForMultiplyDefinedPV > {
public:
msgForMultiplyDefinedPV ( ipAddrToAsciiEngine & engine,
callbackForMultiplyDefinedPV &, const char * pChannelName,
@@ -62,8 +65,8 @@ private:
ipAddrToAsciiTransaction & dnsTransaction;
callbackForMultiplyDefinedPV & cb;
void transactionComplete ( const char * pHostName );
msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & );
msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & );
msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & );
msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & );
void operator delete ( void * );
};

View File

@@ -265,12 +265,16 @@ void ipAddrToAsciiEnginePrivate::run ()
continue;
}
// fix for lp:1580623
// a destructing cac sets pCurrent to NULL, so
// make local copy to avoid race when releasing the guard
ipAddrToAsciiTransactionPrivate *pCur = this->pCurrent;
this->callbackInProgress = true;
{
epicsGuardRelease < epicsMutex > unguard ( guard );
// dont call callback with lock applied
this->pCurrent->pCB->transactionComplete ( this->nameTmp );
pCur->pCB->transactionComplete ( this->nameTmp );
}
this->callbackInProgress = false;