diff --git a/src/ca/CASG.cpp b/src/ca/CASG.cpp index d35863878..4cd090daf 100644 --- a/src/ca/CASG.cpp +++ b/src/ca/CASG.cpp @@ -40,13 +40,12 @@ CASG::~CASG () } void CASG::destructor ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ) { guard.assertIdenticalMutex ( this->client.mutexRef() ); if ( this->verify ( guard ) ) { - this->reset ( cbGuard, guard ); + this->reset ( guard ); this->client.uninstallCASG ( guard, *this ); this->magic = 0; } @@ -65,7 +64,7 @@ bool CASG::verify ( epicsGuard < epicsMutex > & ) const * CASG::block () */ int CASG::block ( - epicsGuard < epicsMutex > & cbGuard, + epicsGuard < epicsMutex > * pcbGuard, epicsGuard < epicsMutex > & guard, double timeout ) { @@ -110,9 +109,15 @@ int CASG::block ( break; } - { + if ( pcbGuard ) { + epicsGuardRelease < epicsMutex > unguard ( guard ); + { + epicsGuardRelease < epicsMutex > uncbGuard ( *pcbGuard ); + this->sem.wait ( remaining ); + } + } + else { epicsGuardRelease < epicsMutex > unguard ( guard ); - epicsGuardRelease < epicsMutex > uncbGuard ( cbGuard ); this->sem.wait ( remaining ); } @@ -124,18 +129,17 @@ int CASG::block ( delay = cur_time - beg_time; } - this->reset ( cbGuard, guard ); + this->reset ( guard ); return status; } void CASG::reset ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ) { guard.assertIdenticalMutex ( this->client.mutexRef() ); this->destroyCompletedIO ( guard ); - this->destroyPendingIO ( cbGuard, guard ); + this->destroyPendingIO ( guard ); } // lock must be applied @@ -150,13 +154,11 @@ void CASG::destroyCompletedIO ( } void CASG::destroyPendingIO ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ) { guard.assertIdenticalMutex ( this->client.mutexRef() ); - syncGroupNotify * pNotify; - while ( ( pNotify = this->ioPendingList.first () ) ) { - pNotify->cancel ( cbGuard, guard ); + while ( syncGroupNotify * pNotify = this->ioPendingList.first () ) { + pNotify->cancel ( guard ); // cancel must release the guard while // canceling put callbacks so we // must double check list membership @@ -201,7 +203,6 @@ void CASG::show ( } bool CASG::ioComplete ( - epicsGuard < epicsMutex > & /* cbGuard */, epicsGuard < epicsMutex > & guard ) { guard.assertIdenticalMutex ( this->client.mutexRef() ); diff --git a/src/ca/access.cpp b/src/ca/access.cpp index b440a08b5..700b8adc0 100644 --- a/src/ca/access.cpp +++ b/src/ca/access.cpp @@ -364,16 +364,15 @@ int epicsShareAPI ca_create_channel ( int epicsShareAPI ca_clear_channel ( chid pChan ) { ca_client_context & cac = pChan->getClientCtx (); - epicsGuard < epicsMutex > * pCBGuard = cac.pCallbackGuard.get(); - if ( pCBGuard ) { - epicsGuard < epicsMutex > guard ( cac.mutex ); - cac.destroyChannel ( *pCBGuard, guard, *pChan ); + epicsGuard < epicsMutex > guard ( cac.mutex ); + try { + pChan->eliminateExcessiveSendBacklog ( guard ); } - else { - epicsGuard < epicsMutex > cbGuard ( cac.cbMutex ); - epicsGuard < epicsMutex > guard ( cac.mutex ); - cac.destroyChannel ( cbGuard, guard, *pChan ); + catch ( cacChannel::notConnected & ) { + // intentionally ignored } + pChan->destructor ( guard ); + cac.oldChannelNotifyFreeList.release ( pChan ); return ECA_NORMAL; } diff --git a/src/ca/ca_client_context.cpp b/src/ca/ca_client_context.cpp index d32a6592f..0a5d3405e 100644 --- a/src/ca/ca_client_context.cpp +++ b/src/ca/ca_client_context.cpp @@ -43,6 +43,8 @@ epicsShareDef epicsThreadPrivateId caClientCallbackThreadId; static epicsThreadOnceId cacOnce = EPICS_THREAD_ONCE_INIT; +const unsigned ca_client_context :: flushBlockThreshold = 0x58000; + extern "C" void cacExitHandler ( void *) { epicsThreadPrivateDelete ( caClientCallbackThreadId ); @@ -65,6 +67,7 @@ cacService * ca_client_context::pDefaultService = 0; epicsMutex * ca_client_context::pDefaultServiceInstallMutex; ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) : + createdByThread ( epicsThreadGetIdSelf () ), ca_exception_func ( 0 ), ca_exception_arg ( 0 ), pVPrintfFunc ( errlogVprintf ), fdRegFunc ( 0 ), fdRegArg ( 0 ), pndRecvCnt ( 0u ), ioSeqNo ( 0u ), callbackThreadsPending ( 0u ), @@ -189,22 +192,6 @@ ca_client_context::~ca_client_context () } } -void ca_client_context::destroyChannel ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, - oldChannelNotify & chan ) -{ - try { - chan.eliminateExcessiveSendBacklog ( - &cbGuard, guard ); - } - catch ( cacChannel::notConnected & ) { - // intentionally ignored - } - chan.destructor ( cbGuard, guard ); - this->oldChannelNotifyFreeList.release ( & chan ); -} - void ca_client_context::destroyGetCopy ( epicsGuard < epicsMutex > & guard, getCopy & gc ) { @@ -663,7 +650,7 @@ void ca_client_context::callbackProcessingCompleteNotify () cacChannel & ca_client_context::createChannel ( epicsGuard < epicsMutex > & guard, const char * pChannelName, - oldChannelNotify & chan, cacChannel::priLev pri ) + cacChannelNotify & chan, cacChannel::priLev pri ) { guard.assertIdenticalMutex ( this->mutex ); return this->pServiceContext->createChannel ( @@ -753,32 +740,41 @@ epicsShareFunc int epicsShareAPI ca_clear_subscription ( evid pMon ) { oldChannelNotify & chan = pMon->channel (); ca_client_context & cac = chan.getClientCtx (); - epicsGuard < epicsMutex > * pCBGuard = cac.pCallbackGuard.get(); - if ( pCBGuard ) { - cac.clearSubscriptionPrivate ( *pCBGuard, *pMon ); - } - else { - epicsGuard < epicsMutex > cbGuard ( cac.cbMutex ); - cac.clearSubscriptionPrivate ( cbGuard, *pMon ); - } - return ECA_NORMAL; -} - -void ca_client_context::clearSubscriptionPrivate ( - epicsGuard < epicsMutex > & cbGuard, oldSubscription & subscr ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - oldChannelNotify & chan = subscr.channel (); + epicsGuard < epicsMutex > guard ( cac.mutex ); try { // if this stalls out on a live circuit then an exception // can be forthcoming which we must ignore as the clear // request must always be successful - chan.eliminateExcessiveSendBacklog ( - & cbGuard, guard ); + chan.eliminateExcessiveSendBacklog ( guard ); } catch ( cacChannel::notConnected & ) { // intentionally ignored } - subscr.cancel ( cbGuard, guard ); + pMon->cancel ( guard ); + return ECA_NORMAL; } +void ca_client_context :: eliminateExcessiveSendBacklog ( + epicsGuard < epicsMutex > & guard, cacChannel & chan ) +{ + if ( chan.requestMessageBytesPending ( guard ) > + ca_client_context :: flushBlockThreshold ) { + if ( this->pCallbackGuard.get() && + this->createdByThread == epicsThreadGetIdSelf () ) { + // we need to be very careful about lock hierarchy + // inversion in this situation + epicsGuardRelease < epicsMutex > unguard ( guard ); + { + epicsGuardRelease < epicsMutex > cbunguard ( + * this->pCallbackGuard.get() ); + { + epicsGuard < epicsMutex > nestedGuard ( this->mutex ); + chan.flush ( nestedGuard ); + } + } + } + else { + chan.flush ( guard ); + } + } +} diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index bf1a15312..4d36cb0bf 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -497,15 +497,15 @@ void cac::transferChanToVirtCircuit ( if ( ! sockAddrAreIdentical ( &addr, &chanAddr ) ) { char acc[64]; pChan->getPIIU(guard)->getHostName ( guard, acc, sizeof ( acc ) ); + msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList ) + msgForMultiplyDefinedPV ( this->ipToAEngine, + *this, pChan->pName ( guard ), acc ); // 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 // must release the primary mutex here to avoid a lock // hierarchy inversion. epicsGuardRelease < epicsMutex > unguard ( guard ); - msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList ) - msgForMultiplyDefinedPV ( this->ipToAEngine, - *this, pChan->pName ( guard ), acc ); pMsg->ioInitiate ( addr ); } return; @@ -566,19 +566,16 @@ void cac::transferChanToVirtCircuit ( } void cac::destroyChannel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard, nciu & chan ) { guard.assertIdenticalMutex ( this->mutex ); - cbGuard.assertIdenticalMutex ( this->cbMutex ); // uninstall channel so that recv threads // will not start a new callback for this channel's IO. if ( this->chanTable.remove ( chan ) != & chan ) { throw std::logic_error ( "Invalid channel identifier" ); } - chan.~nciu (); this->channelFreeList.release ( & chan ); } @@ -642,12 +639,10 @@ netReadNotifyIO & cac::readNotifyRequest ( return *pIO.release(); } -baseNMIU * cac::destroyIO ( - epicsGuard < epicsMutex > & cbGuard, +bool cac::destroyIO ( epicsGuard < epicsMutex > & guard, const cacChannel::ioid & idIn, nciu & chan ) { - cbGuard.assertIdenticalMutex ( this->cbMutex ); guard.assertIdenticalMutex ( this->mutex ); baseNMIU * pIO = this->ioTable.remove ( idIn ); @@ -660,8 +655,9 @@ baseNMIU * cac::destroyIO ( // this uninstalls from the list and destroys the IO pIO->exception ( guard, *this, ECA_CHANDESTROY, chan.pName ( guard ) ); + return true; } - return pIO; + return false; } void cac::ioShow ( diff --git a/src/ca/cac.h b/src/ca/cac.h index e56045d30..75c2c0211 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -135,9 +135,7 @@ public: epicsGuard < epicsMutex > & guard, const char * pChannelName, cacChannelNotify &, cacChannel::priLev ); void destroyChannel ( - epicsGuard < epicsMutex > & callbackControlGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - nciu & ); + epicsGuard < epicsMutex > &, nciu & ); void initiateConnect ( epicsGuard < epicsMutex > &, nciu &, netiiu * & ); nciu * lookupChannel ( @@ -156,8 +154,7 @@ public: epicsGuard < epicsMutex > &, nciu &, privateInterfaceForIO &, unsigned type, arrayElementCount nElem, unsigned mask, cacStateNotify &, bool channelIsInstalled ); - baseNMIU * destroyIO ( - epicsGuard < epicsMutex > & cbGuard, + bool destroyIO ( epicsGuard < epicsMutex > & guard, const cacChannel::ioid & idIn, nciu & chan ); diff --git a/src/ca/getCopy.cpp b/src/ca/getCopy.cpp index ff21e299f..339754e75 100644 --- a/src/ca/getCopy.cpp +++ b/src/ca/getCopy.cpp @@ -64,25 +64,28 @@ void getCopy::completion ( unsigned size = dbr_size_n ( typeIn, countIn ); memcpy ( this->pValue, pDataIn, size ); this->cacCtx.decrementOutstandingIO ( guard, this->ioSeqNo ); + this->cacCtx.destroyGetCopy ( guard, *this ); } else { this->exception ( guard, ECA_INTERNAL, "bad data type match in get copy back response", typeIn, countIn); } - this->cacCtx.destroyGetCopy ( guard, *this ); } void getCopy::exception ( epicsGuard < epicsMutex > & guard, int status, const char *pContext, unsigned /* typeIn */, arrayElementCount /* countIn */ ) { + oldChannelNotify & chanTmp ( this->chan ); + unsigned typeTmp ( this->type ); + arrayElementCount countTmp ( this->count ); + this->cacCtx.destroyGetCopy ( guard, *this ); if ( status != ECA_CHANDESTROY ) { this->cacCtx.exception ( guard, status, pContext, - __FILE__, __LINE__, this->chan, this->type, - this->count, CA_OP_GET ); + __FILE__, __LINE__, chanTmp, typeTmp, + countTmp, CA_OP_GET ); } - this->cacCtx.destroyGetCopy ( guard, *this ); } void getCopy::show ( unsigned level ) const diff --git a/src/ca/nciu.cpp b/src/ca/nciu.cpp index e59635bb2..be65d87d5 100644 --- a/src/ca/nciu.cpp +++ b/src/ca/nciu.cpp @@ -76,27 +76,22 @@ nciu::~nciu () // channels are created by the user, and only destroyed by the user // using this routine void nciu::destroy ( - epicsGuard < epicsMutex > & callbackControlGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ) + epicsGuard < epicsMutex > & guard ) { while ( baseNMIU * pNetIO = this->eventq.first () ) { assert ( this->cacCtx.destroyIO ( - callbackControlGuard, mutualExclusionGuard, - pNetIO->getId (), *this ) ); + guard, pNetIO->getId (), *this ) ); } - + // if the claim reply has not returned yet then we will issue // the clear channel request to the server when the claim reply // arrives and there is no matching nciu in the client - if ( this->channelNode::isInstalledInServer ( mutualExclusionGuard ) ) { - this->getPIIU(mutualExclusionGuard)->clearChannelRequest ( - mutualExclusionGuard, this->sid, this->id ); + if ( this->channelNode::isInstalledInServer ( guard ) ) { + this->getPIIU(guard)->clearChannelRequest ( + guard, this->sid, this->id ); } - - this->piiu->uninstallChan ( mutualExclusionGuard, *this ); - - this->cacCtx.destroyChannel ( - callbackControlGuard, mutualExclusionGuard, *this ); + this->piiu->uninstallChan ( guard, *this ); + this->cacCtx.destroyChannel ( guard, *this ); } void * nciu::operator new ( size_t ) // X aCC 361 @@ -268,12 +263,16 @@ unsigned nciu::nameLen ( return this->nameLength; } -void nciu::eliminateExcessiveSendBacklog ( - epicsGuard < epicsMutex > * pCallbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ) +unsigned nciu::requestMessageBytesPending ( + epicsGuard < epicsMutex > & guard ) { - this->piiu->eliminateExcessiveSendBacklog ( - pCallbackGuard, mutualExclusionGuard ); + return piiu->requestMessageBytesPending ( guard ); +} + +void nciu::flush ( + epicsGuard < epicsMutex > & guard ) +{ + piiu->flush ( guard ); } cacChannel::ioStatus nciu::read ( @@ -391,10 +390,9 @@ void nciu::subscribe ( } void nciu::ioCancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard, const ioid & idIn ) { - this->cacCtx.destroyIO ( cbGuard, guard, idIn, *this ); + this->cacCtx.destroyIO ( guard, idIn, *this ); } void nciu::ioShow ( @@ -577,7 +575,7 @@ void nciu::serviceShutdownNotify ( epicsGuard < epicsMutex > & mutualExclusionGuard ) { this->setServerAddressUnknown ( noopIIU, mutualExclusionGuard ); - this->notify().serviceShutdownNotify ( callbackControlGuard, mutualExclusionGuard ); + this->notify().serviceShutdownNotify ( mutualExclusionGuard ); } void channelNode::setRespPendingState ( diff --git a/src/ca/oldAccess.h b/src/ca/oldAccess.h index ec4fb63f6..ce9f1205e 100644 --- a/src/ca/oldAccess.h +++ b/src/ca/oldAccess.h @@ -46,14 +46,13 @@ #include "cadef.h" #include "syncGroup.h" -struct oldChannelNotify : public cacChannelNotify { +struct oldChannelNotify : private cacChannelNotify { public: oldChannelNotify ( epicsGuard < epicsMutex > &, struct ca_client_context &, const char * pName, caCh * pConnCallBackIn, void * pPrivateIn, capri priority ); void destructor ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); // legacy C API @@ -114,9 +113,6 @@ public: unsigned level ) const; void initiateConnect ( epicsGuard < epicsMutex > & ); - void eliminateExcessiveSendBacklog ( - epicsGuard < epicsMutex > * pCallbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ); void read ( epicsGuard < epicsMutex > &, unsigned type, arrayElementCount count, @@ -126,13 +122,15 @@ public: unsigned type, arrayElementCount count, const void *pValue, cacWriteNotify &, cacChannel::ioid *pId = 0 ); void ioCancel ( - epicsGuard < epicsMutex > & callbackControl, epicsGuard < epicsMutex > & mutualExclusionGuard, const cacChannel::ioid & ); void ioShow ( epicsGuard < epicsMutex > & guard, const cacChannel::ioid &, unsigned level ) const; ca_client_context & getClientCtx (); + void eliminateExcessiveSendBacklog ( + epicsGuard < epicsMutex > & ); + void * operator new ( size_t size, tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & ); epicsPlacementDeleteOperator (( void * , @@ -151,7 +149,6 @@ private: void connectNotify ( epicsGuard < epicsMutex > & ); void disconnectNotify ( epicsGuard < epicsMutex > & ); void serviceShutdownNotify ( - epicsGuard < epicsMutex > & callbackControlGuard, epicsGuard < epicsMutex > & mutualExclusionGuard ); void accessRightsNotify ( epicsGuard < epicsMutex > &, const caAccessRights & ); @@ -263,7 +260,6 @@ public: ~oldSubscription (); oldChannelNotify & channel () const; void cancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); void * operator new ( size_t size, tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & ); @@ -301,10 +297,10 @@ public: void replaceErrLogHandler ( caPrintfFunc * ca_printf_func ); cacChannel & createChannel ( epicsGuard < epicsMutex > &, const char * pChannelName, - oldChannelNotify &, cacChannel::priLev pri ); + cacChannelNotify &, cacChannel::priLev pri ); void flush ( epicsGuard < epicsMutex > & ); void eliminateExcessiveSendBacklog ( - oldChannelNotify & chan, epicsGuard < epicsMutex > & guard ); + epicsGuard < epicsMutex > &, cacChannel & ); int pendIO ( const double & timeout ); int pendEvent ( const double & timeout ); bool ioComplete () const; @@ -339,14 +335,14 @@ public: void vSignal ( int ca_status, const char * pfilenm, int lineno, const char *pFormat, va_list args ); bool preemptiveCallbakIsEnabled () const; - void destroyChannel ( epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, oldChannelNotify & chan ); void destroyGetCopy ( epicsGuard < epicsMutex > &, getCopy & ); void destroyGetCallback ( epicsGuard < epicsMutex > &, getCallback & ); void destroyPutCallback ( epicsGuard < epicsMutex > &, putCallback & ); void destroySubscription ( epicsGuard < epicsMutex > &, oldSubscription & ); epicsMutex & mutexRef () const; + + // legacy C API friend int epicsShareAPI ca_create_channel ( const char * name_str, caCh * conn_func, void * puser, capri priority, chid * chanptr ); @@ -365,8 +361,6 @@ public: chtype type, arrayElementCount count, chid pChan, long mask, caEventCallBackFunc * pCallBack, void * pCallBackArg, evid *monixptr ); - - // legacy C API friend int epicsShareAPI ca_flush_io (); friend int epicsShareAPI ca_clear_subscription ( evid pMon ); friend int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid ); @@ -389,6 +383,7 @@ private: mutable epicsMutex cbMutex; epicsEvent ioDone; epicsEvent callbackThreadActivityComplete; + epicsThreadId createdByThread; epics_auto_ptr < epicsGuard < epicsMutex > > pCallbackGuard; epics_auto_ptr < cacContext > pServiceContext; caExceptionHandler * ca_exception_func; @@ -409,8 +404,6 @@ private: void callbackProcessingCompleteNotify (); cacContext & createNetworkContext ( epicsMutex & mutualExclusion, epicsMutex & callbackControl ); - void clearSubscriptionPrivate ( - epicsGuard < epicsMutex > & cbGuard, oldSubscription & subscr ); ca_client_context ( const ca_client_context & ); ca_client_context & operator = ( const ca_client_context & ); @@ -419,6 +412,7 @@ private: friend void cacExitHandler ( void *); static cacService * pDefaultService; static epicsMutex * pDefaultServiceInstallMutex; + static const unsigned flushBlockThreshold; }; int fetchClientContext ( ca_client_context * * ppcac ); @@ -448,20 +442,11 @@ inline void oldChannelNotify::initiateConnect ( this->io.initiateConnect ( guard ); } -inline void oldChannelNotify::eliminateExcessiveSendBacklog ( - epicsGuard < epicsMutex > * pCallbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ) -{ - this->io.eliminateExcessiveSendBacklog ( - pCallbackGuard, mutualExclusionGuard ); -} - inline void oldChannelNotify::ioCancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard, const cacChannel::ioid & id ) { - this->io.ioCancel ( cbGuard, guard, id ); + this->io.ioCancel ( guard, id ); } inline void oldChannelNotify::ioShow ( @@ -471,6 +456,12 @@ inline void oldChannelNotify::ioShow ( this->io.ioShow ( guard, id, level ); } +inline void oldChannelNotify::eliminateExcessiveSendBacklog ( + epicsGuard < epicsMutex > & guard ) +{ + this->cacCtx.eliminateExcessiveSendBacklog ( guard, this->io ); +} + inline void * oldChannelNotify::operator new ( size_t size, tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & freeList ) { @@ -500,10 +491,9 @@ inline void oldSubscription::operator delete ( void *pCadaver, #endif inline void oldSubscription::cancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ) { - this->chan.ioCancel ( cbGuard, guard, this->id ); + this->chan.ioCancel ( guard, this->id ); } inline oldChannelNotify & oldSubscription::channel () const @@ -569,12 +559,5 @@ inline unsigned ca_client_context::sequenceNumberOfOutstandingIO ( // perhaps on SMP systems THERE should be lock/unlock around this return this->ioSeqNo; } - -inline void ca_client_context::eliminateExcessiveSendBacklog ( - oldChannelNotify & chan, epicsGuard < epicsMutex > & guard ) -{ - chan.eliminateExcessiveSendBacklog ( - this->pCallbackGuard.get(), guard ); -} #endif // ifndef oldAccessh diff --git a/src/ca/oldChannelNotify.cpp b/src/ca/oldChannelNotify.cpp index 95b95f75a..48ddde124 100644 --- a/src/ca/oldChannelNotify.cpp +++ b/src/ca/oldChannelNotify.cpp @@ -65,11 +65,10 @@ oldChannelNotify::~oldChannelNotify () } void oldChannelNotify::destructor ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ) { guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - this->io.destroy ( cbGuard, guard ); + this->io.destroy ( guard ); // no need to worry about a connect preempting here because // the io (the nciu) has been destroyed above if ( this->pConnCallBack == 0 && ! this->currentlyConnected ) { @@ -119,13 +118,9 @@ void oldChannelNotify::disconnectNotify ( } void oldChannelNotify::serviceShutdownNotify ( - epicsGuard < epicsMutex > & callbackControlGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ) + epicsGuard < epicsMutex > & guard ) { - this->cacCtx.destroyChannel ( - callbackControlGuard, - mutualExclusionGuard, - *this ); + this->disconnectNotify ( guard ); } void oldChannelNotify::accessRightsNotify ( @@ -287,8 +282,7 @@ int epicsShareAPI ca_array_get ( chtype type, } unsigned tmpType = static_cast < unsigned > ( type ); epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->eliminateExcessiveSendBacklog ( - pChan->getClientCtx().pCallbackGuard.get(), guard ); + pChan->eliminateExcessiveSendBacklog ( guard ); autoPtrFreeList < getCopy, 0x400, epicsMutexNOOP > pNotify ( pChan->getClientCtx().getCopyFreeList, new ( pChan->getClientCtx().getCopyFreeList ) @@ -355,8 +349,7 @@ int epicsShareAPI ca_array_get_callback ( chtype type, unsigned tmpType = static_cast < unsigned > ( type ); epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->eliminateExcessiveSendBacklog ( - pChan->getClientCtx().pCallbackGuard.get(), guard ); + pChan->eliminateExcessiveSendBacklog ( guard ); autoPtrFreeList < getCallback, 0x400, epicsMutexNOOP > pNotify ( pChan->getClientCtx().getCallbackFreeList, new ( pChan->getClientCtx().getCallbackFreeList ) @@ -427,8 +420,7 @@ int epicsShareAPI ca_array_put_callback ( chtype type, arrayElementCount count, return ECA_BADTYPE; } epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->eliminateExcessiveSendBacklog ( - pChan->getClientCtx().pCallbackGuard.get(), guard ); + pChan->eliminateExcessiveSendBacklog ( guard ); unsigned tmpType = static_cast < unsigned > ( type ); autoPtrFreeList < putCallback, 0x400, epicsMutexNOOP > pNotify ( pChan->getClientCtx().putCallbackFreeList, @@ -491,8 +483,7 @@ int epicsShareAPI ca_array_put ( chtype type, arrayElementCount count, int caStatus; try { epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->eliminateExcessiveSendBacklog ( - pChan->getClientCtx().pCallbackGuard.get(), guard ); + pChan->eliminateExcessiveSendBacklog ( guard ); pChan->io.write ( guard, tmpType, count, pValue ); caStatus = ECA_NORMAL; } @@ -569,8 +560,7 @@ int epicsShareAPI ca_create_subscription ( // can be forthcoming which we must ignore (this is a // special case preserving legacy ca_create_subscription // behavior) - pChan->eliminateExcessiveSendBacklog ( - pChan->getClientCtx().pCallbackGuard.get(), guard ); + pChan->eliminateExcessiveSendBacklog ( guard ); } catch ( cacChannel::notConnected & ) { // intentionally ignored (its ok to subscribe when not connected) diff --git a/src/ca/syncGroup.h b/src/ca/syncGroup.h index 28203b36d..4140a0175 100644 --- a/src/ca/syncGroup.h +++ b/src/ca/syncGroup.h @@ -68,7 +68,6 @@ public: virtual bool ioPending ( epicsGuard < epicsMutex > & guard ) = 0; virtual void cancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ) = 0; virtual void show ( epicsGuard < epicsMutex > &, @@ -92,7 +91,6 @@ public: void begin ( epicsGuard < epicsMutex > &, unsigned type, arrayElementCount count ); void cancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); void show ( epicsGuard < epicsMutex > &, unsigned level ) const; protected: @@ -135,7 +133,6 @@ public: void begin ( epicsGuard < epicsMutex > &, unsigned type, arrayElementCount count, const void * pValueIn ); void cancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); void show ( epicsGuard < epicsMutex > &, unsigned level ) const; protected: @@ -170,16 +167,13 @@ struct CASG : public chronIntIdRes < CASG >, private casgRecycle { public: CASG ( epicsGuard < epicsMutex > &, ca_client_context & cacIn ); void destructor ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); bool ioComplete ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); bool verify ( epicsGuard < epicsMutex > & ) const; - int block ( epicsGuard < epicsMutex > & cbGuard, + int block ( epicsGuard < epicsMutex > * pcbGuard, epicsGuard < epicsMutex > & guard, double timeout ); - void reset ( epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); + void reset ( epicsGuard < epicsMutex > & guard ); void show ( epicsGuard < epicsMutex > &, unsigned level ) const; void show ( unsigned level ) const; void get ( epicsGuard < epicsMutex > &, chid pChan, @@ -214,7 +208,6 @@ private: epicsGuard < epicsMutex > &, syncGroupReadNotify & io ); void destroyPendingIO ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); void destroyCompletedIO ( epicsGuard < epicsMutex > & guard ); diff --git a/src/ca/syncGroupReadNotify.cpp b/src/ca/syncGroupReadNotify.cpp index f84b52b85..2021dee3b 100644 --- a/src/ca/syncGroupReadNotify.cpp +++ b/src/ca/syncGroupReadNotify.cpp @@ -38,8 +38,7 @@ void syncGroupReadNotify::begin ( epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount count ) { - this->chan->getClientCtx(). - eliminateExcessiveSendBacklog ( *this->chan, guard ); + this->chan->eliminateExcessiveSendBacklog ( guard ); this->ioComplete = false; boolFlagManager mgr ( this->idIsValid ); this->chan->read ( guard, type, count, *this, &this->id ); @@ -47,11 +46,10 @@ void syncGroupReadNotify::begin ( } void syncGroupReadNotify::cancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ) { if ( this->idIsValid ) { - this->chan->ioCancel ( cbGuard, guard, this->id ); + this->chan->ioCancel ( guard, this->id ); this->idIsValid = false; } } diff --git a/src/ca/syncGroupWriteNotify.cpp b/src/ca/syncGroupWriteNotify.cpp index 267694662..2dfa3d7c3 100644 --- a/src/ca/syncGroupWriteNotify.cpp +++ b/src/ca/syncGroupWriteNotify.cpp @@ -36,8 +36,7 @@ void syncGroupWriteNotify::begin ( epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount count, const void * pValueIn ) { - this->chan->getClientCtx().eliminateExcessiveSendBacklog ( - *this->chan, guard ); + this->chan->eliminateExcessiveSendBacklog ( guard ); this->ioComplete = false; boolFlagManager mgr ( this->idIsValid ); this->chan->write ( guard, type, count, @@ -46,11 +45,10 @@ void syncGroupWriteNotify::begin ( } void syncGroupWriteNotify::cancel ( - epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ) { if ( this->idIsValid ) { - this->chan->ioCancel ( cbGuard, guard, this->id ); + this->chan->ioCancel ( guard, this->id ); this->idIsValid = false; } }