diff -cr base-3.14.12.5/src/ca/cac.cpp fix-1580623/src/ca/cac.cpp *** base-3.14.12.5/src/ca/cac.cpp 2015-03-24 16:00:05.000000000 +0100 --- fix-1580623/src/ca/cac.cpp 2016-09-02 18:56:32.265659645 +0200 *************** *** 333,338 **** --- 333,344 ---- 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,611 **** --- 612,619 ---- 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,1302 **** --- 1305,1312 ---- 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 ); } Only in fix-1580623/src/ca: cac.cpp.orig diff -cr base-3.14.12.5/src/ca/cac.h fix-1580623/src/ca/cac.h *** base-3.14.12.5/src/ca/cac.h 2015-03-24 16:00:05.000000000 +0100 --- fix-1580623/src/ca/cac.h 2016-09-02 18:58:07.662292027 +0200 *************** *** 237,242 **** --- 237,243 ---- resTable < tcpiiu, caServerID > serverTable; tsDLList < tcpiiu > circuitList; tsDLList < SearchDest > searchDestList; + tsDLList < msgForMultiplyDefinedPV > msgMultiPVList; tsFreeList < class tcpiiu, 32, epicsMutexNOOP > freeListVirtualCircuit; Only in fix-1580623/src/ca: cac.h.orig Only in fix-1580623/src/ca: cac.h.rej diff -cr base-3.14.12.5/src/ca/msgForMultiplyDefinedPV.cpp fix-1580623/src/ca/msgForMultiplyDefinedPV.cpp *** base-3.14.12.5/src/ca/msgForMultiplyDefinedPV.cpp 2015-03-24 16:00:05.000000000 +0100 --- fix-1580623/src/ca/msgForMultiplyDefinedPV.cpp 2016-09-02 18:56:51.924965681 +0200 *************** *** 55,62 **** void msgForMultiplyDefinedPV::transactionComplete ( const char * pHostNameRej ) { this->cb.pvMultiplyDefinedNotify ( *this, this->channel, this->acc, pHostNameRej ); ! // !! dont touch this pointer after this point because object has been deleted !! } void * msgForMultiplyDefinedPV::operator new ( size_t size, --- 55,64 ---- 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 !! } void * msgForMultiplyDefinedPV::operator new ( size_t size, diff -cr base-3.14.12.5/src/ca/msgForMultiplyDefinedPV.h fix-1580623/src/ca/msgForMultiplyDefinedPV.h *** base-3.14.12.5/src/ca/msgForMultiplyDefinedPV.h 2015-03-24 16:00:05.000000000 +0100 --- fix-1580623/src/ca/msgForMultiplyDefinedPV.h 2016-09-02 18:57:08.748371809 +0200 *************** *** 33,38 **** --- 33,39 ---- #include "ipAddrToAsciiAsynchronous.h" #include "tsFreeList.h" + #include "tsDLList.h" #include "compilerDependencies.h" #ifdef msgForMultiplyDefinedPVh_epicsExportSharedSymbols *************** *** 47,53 **** const char * pAcc, const char * pRej ) = 0; }; ! class msgForMultiplyDefinedPV : public ipAddrToAsciiCallBack { public: msgForMultiplyDefinedPV ( ipAddrToAsciiEngine & engine, callbackForMultiplyDefinedPV &, const char * pChannelName, --- 48,56 ---- const char * pAcc, const char * pRej ) = 0; }; ! class msgForMultiplyDefinedPV : ! public ipAddrToAsciiCallBack, ! public tsDLNode < msgForMultiplyDefinedPV > { public: msgForMultiplyDefinedPV ( ipAddrToAsciiEngine & engine, callbackForMultiplyDefinedPV &, const char * pChannelName, *************** *** 62,69 **** ipAddrToAsciiTransaction & dnsTransaction; callbackForMultiplyDefinedPV & cb; void transactionComplete ( const char * pHostName ); ! msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & ); ! msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & ); void operator delete ( void * ); }; --- 65,72 ---- ipAddrToAsciiTransaction & dnsTransaction; callbackForMultiplyDefinedPV & cb; void transactionComplete ( const char * pHostName ); ! msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & ); ! msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & ); void operator delete ( void * ); }; diff -cr base-3.14.12.5/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp fix-1580623/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp *** base-3.14.12.5/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp 2015-03-24 16:00:05.000000000 +0100 --- fix-1580623/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp 2016-09-02 18:57:32.611529409 +0200 *************** *** 331,342 **** continue; } this->callbackInProgress = true; { epicsGuardRelease < epicsMutex > unguard ( guard ); // dont call callback with lock applied ! this->pCurrent->pCB->transactionComplete ( this->nameTmp ); } this->callbackInProgress = false; --- 331,346 ---- 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 ! pCur->pCB->transactionComplete ( this->nameTmp ); } this->callbackInProgress = false; Only in fix-1580623/src/libCom/misc: ipAddrToAsciiAsynchronous.cpp.orig