diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index df0eb881c..3e05461ab 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -1752,7 +1752,7 @@ void cac::privateUninstallIIU ( epicsGuard < callbackMutex > & cbGuard, tcpiiu & if ( iiu.channelCount() ) { char hostNameTmp[64]; iiu.hostName ( hostNameTmp, sizeof ( hostNameTmp ) ); - genLocalExcep ( *this, ECA_DISCONN, hostNameTmp ); + genLocalExcep ( cbGuard, *this, ECA_DISCONN, hostNameTmp ); } osiSockAddr addr = iiu.getNetworkAddress(); if ( addr.sa.sa_family == AF_INET ) { diff --git a/src/ca/cac.h b/src/ca/cac.h index 49cf89683..77d400d06 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -151,8 +151,8 @@ public: void uninstallCASG ( CASG & ); // exception generation - void exception ( int status, const char *pContext, - const char *pFileName, unsigned lineNo ); + void exception ( epicsGuard < callbackMutex > &, int status, const char * pContext, + const char * pFileName, unsigned lineNo ); // callback preemption control int blockForEventAndEnableCallbacks ( epicsEvent &event, double timeout ); @@ -340,8 +340,8 @@ inline cacMutex & cac::mutexRef () return this->mutex; } -inline void cac::exception ( int status, const char *pContext, - const char *pFileName, unsigned lineNo ) +inline void cac::exception ( epicsGuard < callbackMutex > &, int status, + const char *pContext, const char *pFileName, unsigned lineNo ) { this->notify.exception ( status, pContext, pFileName, lineNo ); } diff --git a/src/ca/iocinf.h b/src/ca/iocinf.h index 25d3dacbc..d5c34ffc7 100644 --- a/src/ca/iocinf.h +++ b/src/ca/iocinf.h @@ -70,7 +70,7 @@ private: /* * CA internal functions */ -#define genLocalExcep( CAC, STAT, PCTX ) \ -(CAC).exception ( STAT, PCTX, __FILE__, __LINE__ ) +#define genLocalExcep( GUARD, CAC, STAT, PCTX ) \ +(CAC).exception ( GUARD, STAT, PCTX, __FILE__, __LINE__ ) #endif // ifdef INCiocinfh diff --git a/src/ca/msgForMultiplyDefinedPV.cpp b/src/ca/msgForMultiplyDefinedPV.cpp index 47ad593c5..f694ae0a9 100644 --- a/src/ca/msgForMultiplyDefinedPV.cpp +++ b/src/ca/msgForMultiplyDefinedPV.cpp @@ -45,6 +45,6 @@ void msgForMultiplyDefinedPV::ioCompletionNotify ( const char * pHostNameRej ) char buf[256]; sprintf ( buf, "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s", this->channel, this->acc, pHostNameRej ); - epicsGuard < callbackMutex > guard ( this->mutex ); - genLocalExcep ( this->cacRef, ECA_DBLCHNL, buf ); + epicsGuard < callbackMutex > cbGuard ( this->mutex ); + genLocalExcep ( cbGuard, this->cacRef, ECA_DBLCHNL, buf ); } diff --git a/src/ca/udpiiu.cpp b/src/ca/udpiiu.cpp index ba485d535..9315a1f52 100644 --- a/src/ca/udpiiu.cpp +++ b/src/ca/udpiiu.cpp @@ -56,7 +56,7 @@ const udpiiu::pProtoStubUDP udpiiu::udpJumpTableCAC [] = // // udpiiu::udpiiu () // -udpiiu::udpiiu ( epicsTimerQueueActive &timerQueue, callbackMutex & cbMutex, cac & cac ) : +udpiiu::udpiiu ( epicsTimerQueueActive & timerQueue, callbackMutex & cbMutex, cac & cac ) : recvThread ( *this, cbMutex, "CAC-UDP", epicsThreadGetStackSize ( epicsThreadStackMedium ), @@ -157,16 +157,8 @@ udpiiu::udpiiu ( epicsTimerQueueActive &timerQueue, callbackMutex & cbMutex, cac * load user and auto configured * broadcast address list */ - ellInit ( &this->dest ); // X aCC 392 + ellInit ( & this->dest ); // X aCC 392 configureChannelAccessAddressList ( &this->dest, this->sock, this->serverPort ); - if ( ellCount ( &this->dest ) == 0 ) { // X aCC 392 - // no need to lock callbacks here because - // 1) this is called while in a CA client function - // 2) no auxiliary threads are running at this point - // (taking the callback lock here would break the - // lock hierarchy and risk deadlocks) - genLocalExcep ( this->cacRef, ECA_NOSEARCHADDR, NULL ); - } caStartRepeaterIfNotInstalled ( this->repeaterPort ); @@ -300,6 +292,10 @@ void udpRecvThread::run () { epicsGuard < callbackMutex > cbGuard ( this->cbMutex ); this->iiu.cacRef.notifyNewFD ( cbGuard, this->iiu.sock ); + if ( ellCount ( & this->iiu.dest ) == 0 ) { // X aCC 392 + genLocalExcep ( cbGuard, this->iiu.cacRef, ECA_NOSEARCHADDR, NULL ); + } + } do {