diff --git a/src/ca/cac.h b/src/ca/cac.h index 6b4141fa7..d48439356 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -74,16 +74,19 @@ public: void flushRequest (); int pendIO ( const double &timeout ); int pendEvent ( const double &timeout ); - bool executeResponse ( tcpiiu &, caHdrLargeArray &, char *pMsgBody ); + bool executeResponse ( class callbackAutoMutex &, tcpiiu &, + caHdrLargeArray &, char *pMsgBody ); void ioCancel ( nciu &chan, const cacChannel::ioid &id ); void ioShow ( const cacChannel::ioid &id, unsigned level ) const; // channel routines void installNetworkChannel ( nciu &, netiiu *&piiu ); - bool lookupChannelAndTransferToTCP ( unsigned cid, unsigned sid, - ca_uint16_t typeCode, arrayElementCount count, - unsigned minorVersionNumber, const osiSockAddr &, - const epicsTime & currentTime ); + bool lookupChannelAndTransferToTCP ( + class callbackAutoMutex & cbMutex, + unsigned cid, unsigned sid, + ca_uint16_t typeCode, arrayElementCount count, + unsigned minorVersionNumber, const osiSockAddr &, + const epicsTime & currentTime ); void uninstallChannel ( nciu & ); cacChannel & createChannel ( const char *name_str, cacChannelNotify &chan, cacChannel::priLev pri ); @@ -135,14 +138,14 @@ public: epicsMutex & mutexRef (); void attachToClientCtx (); void selfTest () const; - void notifyNewFD ( SOCKET ) const; - void notifyDestroyFD ( SOCKET ) const; + void notifyNewFD ( class callbackAutoMutex &, SOCKET ) const; + void notifyDestroyFD ( class callbackAutoMutex &, SOCKET ) const; void uninstallIIU ( tcpiiu &iiu ); bool preemptiveCallbakIsEnabled () const; double beaconPeriod ( const nciu & chan ) const; - void udpWakeup (); static unsigned lowestPriorityLevelAbove ( unsigned priority ); static unsigned highestPriorityLevelBelow ( unsigned priority ); + void tcpCircuitShutdown ( tcpiiu &, bool discardMessages ); private: ipAddrToAsciiEngine ipToAEngine; @@ -168,6 +171,9 @@ private: freeListSubscription; epicsTime programBeginTime; double connTMO; + // **** lock hierarchy **** + // callback lock must always be acquired before + // the primary mutex if both locks are needed mutable epicsMutex mutex; epicsMutex callbackMutex; epicsEvent ioDone; @@ -190,21 +196,24 @@ private: unsigned readSeq; unsigned recvThreadsPendingCount; - void privateUninstallIIU ( tcpiiu &iiu ); + void privateUninstallIIU ( class callbackAutoMutex &, tcpiiu &iiu ); void flushRequestPrivate (); void run (); bool setupUDP (); void connectAllIO ( nciu &chan ); - void disconnectAllIO ( nciu &chan, bool enableCallbacks ); - void ioCancelPrivate ( nciu &chan, const cacChannel::ioid &id ); + void disconnectAllIO ( epicsAutoMutex &locker, nciu &chan, bool enableCallbacks ); void flushIfRequired ( netiiu & ); void recycleReadNotifyIO ( netReadNotifyIO &io ); void recycleWriteNotifyIO ( netWriteNotifyIO &io ); void recycleSubscription ( netSubscription &io ); void preemptiveCallbackLock (); void preemptiveCallbackUnlock (); - void removeAllChan ( netiiu & srcIIU, netiiu * pDstIIU = 0 ); - void disconnectChannelPrivate ( nciu & chan, netiiu *pDstIIU ); + void removeAllChan ( + callbackAutoMutex & cbLocker, epicsAutoMutex &locker, + netiiu & srcIIU, netiiu & dstIIU ); + void disconnectChannelPrivate ( + class callbackAutoMutex &, epicsAutoMutex &, + nciu & chan, netiiu & dstIIU ); void ioCompletionNotify ( unsigned id, unsigned type, arrayElementCount count, const void *pData ); @@ -222,42 +231,56 @@ private: int status, const char *pContext, unsigned type, arrayElementCount count ); // recv protocol stubs - bool noopAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool echoRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool writeNotifyRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool readNotifyRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool eventRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool readRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool clearChannelRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool exceptionRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool accessRightsRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool claimCIURespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool verifyAndDisconnectChan ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool badTCPRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); + bool noopAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool echoRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool writeNotifyRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool readNotifyRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool eventRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool readRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool clearChannelRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool exceptionRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool accessRightsRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool claimCIURespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool verifyAndDisconnectChan ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); + bool badTCPRespAction ( callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); typedef bool ( cac::*pProtoStubTCP ) ( - tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); + callbackAutoMutex &, tcpiiu &, + const caHdrLargeArray &, void *pMsgBdy ); static const pProtoStubTCP tcpJumpTableCAC []; - bool defaultExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr, + bool defaultExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool eventAddExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr, + bool eventAddExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool readExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr, + bool readExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool writeExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr, + bool writeExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool clearChanExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr, + bool clearChanExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool readNotifyExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr, + bool readNotifyExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool writeNotifyExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr, + bool writeNotifyExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); typedef bool ( cac::*pExcepProtoStubTCP ) ( - tcpiiu &iiu, const caHdrLargeArray &hdr, + callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); static const pExcepProtoStubTCP tcpExcepJumpTableCAC []; friend class callbackAutoMutex; + friend class callbackAutoMutexRelease; cac ( const cac & ); cac & operator = ( const cac & ); @@ -271,6 +294,17 @@ private: cac & ctx; callbackAutoMutex ( const callbackAutoMutex & ); callbackAutoMutex & operator = ( const callbackAutoMutex & ); + friend class callbackAutoMutexRelease; +}; + +class callbackAutoMutexRelease { +public: + callbackAutoMutexRelease ( callbackAutoMutex & autoMutexIn ); + ~callbackAutoMutexRelease (); +private: + callbackAutoMutex & autoMutex; + callbackAutoMutexRelease ( const callbackAutoMutexRelease & ); + callbackAutoMutexRelease & operator = ( const callbackAutoMutexRelease & ); }; inline const char * cac::userNamePointer () const @@ -364,5 +398,16 @@ inline callbackAutoMutex::~callbackAutoMutex () this->ctx.preemptiveCallbackUnlock (); } +inline callbackAutoMutexRelease::callbackAutoMutexRelease ( callbackAutoMutex & autoMutexIn ) : + autoMutex ( autoMutexIn ) +{ + this->autoMutex.ctx.preemptiveCallbackUnlock (); +} + +inline callbackAutoMutexRelease::~callbackAutoMutexRelease () +{ + this->autoMutex.ctx.preemptiveCallbackLock (); +} + #endif // ifdef cach diff --git a/src/ca/netiiu.cpp b/src/ca/netiiu.cpp index 5196a4f18..81b759640 100644 --- a/src/ca/netiiu.cpp +++ b/src/ca/netiiu.cpp @@ -107,7 +107,7 @@ bool netiiu::isVirtualCircuit ( const char *, const osiSockAddr & ) const return false; } -void netiiu::lastChannelDetachNotify () +void netiiu::lastChannelDetachNotify ( class callbackAutoMutex & /* cbLocker */ ) { } diff --git a/src/ca/netiiu.h b/src/ca/netiiu.h index 63628a06f..f4d42f9bf 100644 --- a/src/ca/netiiu.h +++ b/src/ca/netiiu.h @@ -38,7 +38,7 @@ public: bool searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThisChannel ); void resetChannelRetryCounts (); void attachChannel ( nciu &chan ); - void detachChannel ( nciu &chan ); + void detachChannel ( class callbackAutoMutex & cbLocker, nciu &chan ); nciu * firstChannel (); int printf ( const char *pformat, ... ); virtual void hostName (char *pBuf, unsigned bufLength) const; @@ -64,7 +64,7 @@ protected: private: tsDLList < nciu > channelList; cac *pClientCtx; - virtual void lastChannelDetachNotify (); + virtual void lastChannelDetachNotify ( class callbackAutoMutex & cbLocker ); netiiu ( const netiiu & ); netiiu & operator = ( const netiiu & ); }; @@ -96,11 +96,12 @@ inline void netiiu::attachChannel ( class nciu &chan ) } // cac lock must also be applied when calling this -inline void netiiu::detachChannel ( class nciu & chan ) +inline void netiiu::detachChannel ( + class callbackAutoMutex & cbLocker, class nciu & chan ) { this->channelList.remove ( chan ); if ( this->channelList.count () == 0u ) { - this->lastChannelDetachNotify (); + this->lastChannelDetachNotify ( cbLocker ); } } diff --git a/src/ca/searchTimer.cpp b/src/ca/searchTimer.cpp index 0af60ef3d..663c10460 100644 --- a/src/ca/searchTimer.cpp +++ b/src/ca/searchTimer.cpp @@ -67,31 +67,38 @@ void searchTimer::resetPeriod ( double delayToNextTry ) { bool start; - // upper bound - double newPeriod = this->roundTripDelayEstimate * 2.0; - if ( newPeriod > initialRoundTripEstimate * 2.0 ) { - newPeriod = initialRoundTripEstimate * 2.0; - } - // lower bound - if ( newPeriod < minSearchPeriod ) { - newPeriod = minSearchPeriod; - } - - this->retry = 0; - if ( this->iiu.channelCount() > 0 ) { - if ( ! this->active ) { - this->active = true; - this->noDelay = ( delayToNextTry == 0.0 ); - start = true; + { + epicsAutoMutex locker ( this->mutex ); + + // upper bound + double newPeriod = this->roundTripDelayEstimate * 2.0; + if ( newPeriod > initialRoundTripEstimate * 2.0 ) { + newPeriod = initialRoundTripEstimate * 2.0; } - else if ( this->period > newPeriod ) { - double delay = this->timer.getExpireDelay(); - if ( delay > newPeriod ) { + // lower bound + if ( newPeriod < minSearchPeriod ) { + newPeriod = minSearchPeriod; + } + + this->retry = 0; + if ( this->iiu.channelCount() > 0 ) { + if ( ! this->active ) { this->active = true; this->noDelay = ( delayToNextTry == 0.0 ); - delayToNextTry = newPeriod; start = true; } + else if ( this->period > newPeriod ) { + double delay = this->timer.getExpireDelay(); + if ( delay > newPeriod ) { + this->active = true; + this->noDelay = ( delayToNextTry == 0.0 ); + delayToNextTry = newPeriod; + start = true; + } + else { + start = false; + } + } else { start = false; } @@ -99,15 +106,11 @@ void searchTimer::resetPeriod ( double delayToNextTry ) else { start = false; } - } - else { - start = false; - } - this->period = newPeriod; + this->period = newPeriod; + } if ( start ) { - epicsAutoMutexRelease autoRelease ( this->mutex ); this->timer.start ( *this, delayToNextTry ); // debugPrintf ( ("rescheduled search timer for completion in %f sec\n", delayToNextTry) ); } @@ -115,6 +118,7 @@ void searchTimer::resetPeriod ( double delayToNextTry ) /* * searchTimer::setRetryInterval () + * (lock must be applied) */ void searchTimer::setRetryInterval ( unsigned retryNo ) { @@ -152,35 +156,38 @@ void searchTimer::notifySearchResponse ( unsigned short retrySeqNoIn, { bool reschedualNeeded; - if ( this->retrySeqAtPassBegin <= retrySeqNoIn ) { - if ( this->searchResponses < UINT_MAX ) { - this->searchResponses++; + { + epicsAutoMutex locker ( this->mutex ); + + if ( this->retrySeqAtPassBegin <= retrySeqNoIn ) { + if ( this->searchResponses < UINT_MAX ) { + this->searchResponses++; + } + } + + if ( retrySeqNoIn == this->retrySeqNo && ! this->noDelay ) { + double curRTT = currentTime - this->timeAtLastRetry; + this->roundTripDelayEstimate = + ( this->roundTripDelayEstimate + curRTT ) / 2.0; + this->period = this->roundTripDelayEstimate * 2.0; + this->period = tsMin ( maxSearchPeriod, this->period ); + this->period = tsMax ( minSearchPeriod, this->period ); + reschedualNeeded = true; + this->active = true; + this->noDelay = true; } - } - if ( retrySeqNoIn == this->retrySeqNo && ! this->noDelay ) { - double curRTT = currentTime - this->timeAtLastRetry; - this->roundTripDelayEstimate = - ( this->roundTripDelayEstimate + curRTT ) / 2.0; - this->period = this->roundTripDelayEstimate * 2.0; - this->period = tsMin ( maxSearchPeriod, this->period ); - this->period = tsMax ( minSearchPeriod, this->period ); - reschedualNeeded = true; - this->active = true; - this->noDelay = true; - } - - if ( this->searchResponses == this->searchAttempts ) { - reschedualNeeded = true; - this->active = true; - this->noDelay = true; - } - else { - reschedualNeeded = false; + if ( this->searchResponses == this->searchAttempts ) { + reschedualNeeded = true; + this->active = true; + this->noDelay = true; + } + else { + reschedualNeeded = false; + } } if ( reschedualNeeded ) { - epicsAutoMutexRelease autoRelease (this->mutex ); # if defined(DEBUG) && 0 char buf[64]; epicsTime ts = epicsTime::getCurrent(); diff --git a/src/ca/udpiiu.cpp b/src/ca/udpiiu.cpp index 03b9e6fa6..fb8ee2648 100644 --- a/src/ca/udpiiu.cpp +++ b/src/ca/udpiiu.cpp @@ -52,7 +52,7 @@ const udpiiu::pProtoStubUDP udpiiu::udpJumpTableCAC [] = // // udpiiu::udpiiu () // -udpiiu::udpiiu ( cac &cac ) : +udpiiu::udpiiu ( callbackAutoMutex &cbLocker, cac & cac ) : netiiu ( &cac ), shutdownCmd ( false ), sockCloseCompleted ( false ) { @@ -173,13 +173,7 @@ udpiiu::udpiiu ( cac &cac ) : caStartRepeaterIfNotInstalled ( this->repeaterPort ); - // no callback lock required since this is - // always called by the user thread - its - // better to call this here from the user - // thread so the udp recv thread does not - // block to do this when there is data in - // the udp input queue - this->pCAC()->notifyNewFD ( this->sock ); + this->pCAC ()->notifyNewFD ( cbLocker, this->sock ); } /* @@ -263,8 +257,8 @@ void udpiiu::recvMsg () SOCKERRSTR (errnoCpy) ); } else if ( status > 0 ) { - this->postMsg ( src, this->recvBuf, (arrayElementCount) status, - epicsTime::getCurrent() ); + this->postMsg ( autoMutex, src, this->recvBuf, + (arrayElementCount) status, epicsTime::getCurrent() ); } } return; @@ -280,10 +274,6 @@ extern "C" void cacRecvThreadUDP ( void *pParam ) do { piiu->recvMsg (); } while ( ! piiu->shutdownCmd ); - { - callbackAutoMutex autoMutex ( *piiu->pCAC() ); - piiu->pCAC()->notifyDestroyFD ( piiu->sock ); - } epicsEventSignal ( piiu->recvThreadExitSignal ); } @@ -502,7 +492,7 @@ void udpiiu::shutdown () epicsEventMustWait ( this->recvThreadExitSignal ); } -bool udpiiu::badUDPRespAction ( const caHdr &msg, +bool udpiiu::badUDPRespAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &netAddr, const epicsTime ¤tTime ) { char buf[64]; @@ -514,12 +504,14 @@ bool udpiiu::badUDPRespAction ( const caHdr &msg, return false; } -bool udpiiu::noopAction ( const caHdr &, const osiSockAddr &, const epicsTime & ) +bool udpiiu::noopAction ( callbackAutoMutex &, + const caHdr &, const osiSockAddr &, const epicsTime & ) { return true; } -bool udpiiu::searchRespAction ( const caHdr &msg, // X aCC 361 +bool udpiiu::searchRespAction ( callbackAutoMutex & cbLocker, + const caHdr &msg, // X aCC 361 const osiSockAddr &addr, const epicsTime ¤tTime ) { osiSockAddr serverAddr; @@ -572,17 +564,17 @@ bool udpiiu::searchRespAction ( const caHdr &msg, // X aCC 361 if ( CA_V42 ( minorVersion ) ) { return this->pCAC ()->lookupChannelAndTransferToTCP - ( msg.m_available, msg.m_cid, 0xffff, + ( cbLocker, msg.m_available, msg.m_cid, 0xffff, 0, minorVersion, serverAddr, currentTime ); } else { return this->pCAC ()->lookupChannelAndTransferToTCP - ( msg.m_available, msg.m_cid, msg.m_dataType, + ( cbLocker, msg.m_available, msg.m_cid, msg.m_dataType, msg.m_count, minorVersion, serverAddr, currentTime ); } } -bool udpiiu::beaconAction ( const caHdr &msg, +bool udpiiu::beaconAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime ¤tTime ) { struct sockaddr_in ina; @@ -626,20 +618,20 @@ bool udpiiu::beaconAction ( const caHdr &msg, return true; } -bool udpiiu::repeaterAckAction ( const caHdr &, +bool udpiiu::repeaterAckAction ( callbackAutoMutex &, const caHdr &, const osiSockAddr &, const epicsTime &) { this->pCAC ()->repeaterSubscribeConfirmNotify (); return true; } -bool udpiiu::notHereRespAction ( const caHdr &, +bool udpiiu::notHereRespAction ( callbackAutoMutex &, const caHdr &, const osiSockAddr &, const epicsTime & ) { return true; } -bool udpiiu::exceptionRespAction ( const caHdr &msg, +bool udpiiu::exceptionRespAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime ¤tTime ) { const caHdr &reqMsg = * ( &msg + 1 ); @@ -661,7 +653,8 @@ bool udpiiu::exceptionRespAction ( const caHdr &msg, return true; } -void udpiiu::postMsg ( const osiSockAddr & net_addr, +void udpiiu::postMsg ( callbackAutoMutex & cbLocker, + const osiSockAddr & net_addr, char * pInBuf, arrayElementCount blockSize, const epicsTime & currentTime ) { @@ -724,7 +717,7 @@ void udpiiu::postMsg ( const osiSockAddr & net_addr, else { pStub = &udpiiu::badUDPRespAction; } - bool success = ( this->*pStub ) ( *pCurMsg, net_addr, currentTime ); + bool success = ( this->*pStub ) ( cbLocker, *pCurMsg, net_addr, currentTime ); if ( ! success ) { char buf[256]; sockAddrToDottedIP ( &net_addr.sa, buf, sizeof ( buf ) ); diff --git a/src/ca/udpiiu.h b/src/ca/udpiiu.h index 4426c650a..05187d7ed 100644 --- a/src/ca/udpiiu.h +++ b/src/ca/udpiiu.h @@ -43,11 +43,11 @@ class epicsTime; class udpiiu : public netiiu { public: - udpiiu ( class cac & ); + udpiiu ( callbackAutoMutex &, class cac & ); virtual ~udpiiu (); void shutdown (); void recvMsg (); - void postMsg ( const osiSockAddr & net_addr, + void postMsg ( callbackAutoMutex &, const osiSockAddr & net_addr, char *pInBuf, arrayElementCount blockSize, const epicsTime ¤Time ); void repeaterRegistrationMessage ( unsigned attemptNumber ); @@ -76,26 +76,27 @@ private: bool pushDatagramMsg ( const caHdr &msg, const void *pExt, ca_uint16_t extsize ); - typedef bool ( udpiiu::*pProtoStubUDP ) ( const caHdr &, + typedef bool ( udpiiu::*pProtoStubUDP ) ( + callbackAutoMutex &, const caHdr &, const osiSockAddr &, const epicsTime & ); // UDP protocol dispatch table static const pProtoStubUDP udpJumpTableCAC[]; // UDP protocol stubs - bool noopAction ( const caHdr &, + bool noopAction ( callbackAutoMutex &, const caHdr &, const osiSockAddr &, const epicsTime & ); - bool badUDPRespAction ( const caHdr &msg, + bool badUDPRespAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &netAddr, const epicsTime & ); - bool searchRespAction ( const caHdr &msg, + bool searchRespAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool exceptionRespAction ( const caHdr &msg, + bool exceptionRespAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool beaconAction ( const caHdr &msg, + bool beaconAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool notHereRespAction ( const caHdr &msg, + bool notHereRespAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool repeaterAckAction ( const caHdr &msg, + bool repeaterAckAction ( callbackAutoMutex &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); friend void cacRecvThreadUDP ( void *pParam ); diff --git a/src/ca/virtualCircuit.h b/src/ca/virtualCircuit.h index 4ec8101e5..6e4b489a0 100644 --- a/src/ca/virtualCircuit.h +++ b/src/ca/virtualCircuit.h @@ -57,17 +57,18 @@ public: unsigned minorVersion, ipAddrToAsciiEngine & engineIn, const cacChannel::priLev & priorityIn ); ~tcpiiu (); - bool start (); + bool start ( class callbackAutoMutex & ); void cleanShutdown (); + void forcedShutdown (); + void shutdown ( class callbackAutoMutex & cbLocker, bool discardPendingMessages ); void beaconAnomalyNotify (); void beaconArrivalNotify (); - void forcedShutdown (); void flushRequest (); bool flushBlockThreshold () const; void flushRequestIfAboveEarlyThreshold (); void blockUntilSendBacklogIsReasonable - ( epicsMutex * pCallBack, epicsMutex & primary ); + ( epicsAutoMutex * pCallBackLocker, epicsAutoMutex & primaryLocker ); virtual void show ( unsigned level ) const; bool setEchoRequestPending (); void requestRecvProcessPostponedFlush (); @@ -113,12 +114,11 @@ private: bool earlyFlush; bool recvProcessPostponedFlush; - void shutdown ( bool discardPendingMessages ); void stopThreads (); - bool processIncoming (); + bool processIncoming ( callbackAutoMutex & ); unsigned sendBytes ( const void *pBuf, unsigned nBytesInBuf ); unsigned recvBytes ( void *pBuf, unsigned nBytesInBuf ); - void lastChannelDetachNotify (); + void lastChannelDetachNotify ( class callbackAutoMutex & cbLocker ); void connect (); // send protocol stubs diff --git a/src/db/dbPutNotifyBlocker.cpp b/src/db/dbPutNotifyBlocker.cpp index 6962ba4a0..a8ee38cf8 100644 --- a/src/db/dbPutNotifyBlocker.cpp +++ b/src/db/dbPutNotifyBlocker.cpp @@ -107,7 +107,7 @@ extern "C" void putNotifyCompletion ( putNotify *ppn ) pBlocker->block.signal (); } -void dbPutNotifyBlocker::initiatePutNotify ( epicsMutex &mutex, cacWriteNotify & notify, +void dbPutNotifyBlocker::initiatePutNotify ( epicsAutoMutex &locker, cacWriteNotify & notify, struct dbAddr & addr, unsigned type, unsigned long count, const void * pValue ) { int status; @@ -129,7 +129,7 @@ void dbPutNotifyBlocker::initiatePutNotify ( epicsMutex &mutex, cacWriteNotify & beginTimeInit = true; } { - epicsAutoMutexRelease autoRelease ( mutex ); + epicsAutoMutexRelease autoRelease ( locker ); this->block.wait ( 1.0 ); } } @@ -161,7 +161,7 @@ void dbPutNotifyBlocker::initiatePutNotify ( epicsMutex &mutex, cacWriteNotify & memset ( &this->pn, '\0', sizeof ( this->pn ) ); this->pNotify = 0; { - epicsAutoMutexRelease autoRelease ( mutex ); + epicsAutoMutexRelease autoRelease ( locker ); notify.exception ( ECA_PUTFAIL, "dbPutNotify() returned failure", static_cast (this->pn.dbrType),