From bb05cea3c1aeeba9cf1ce6f0a3b3dd38cf7f13d5 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Fri, 23 Jan 2004 19:55:11 +0000 Subject: [PATCH] fixed solaris warnings --- src/ca/access.cpp | 53 +++++--- src/ca/ca_client_context.cpp | 19 --- src/ca/cac.cpp | 213 ++++++++++++++++---------------- src/ca/cac.h | 11 +- src/ca/cacChannel.cpp | 25 ++-- src/ca/cacIO.h | 37 ++++-- src/ca/nciu.cpp | 107 +++++++++------- src/ca/nciu.h | 76 ++++++++---- src/ca/netIO.h | 31 +++-- src/ca/netReadNotifyIO.cpp | 8 +- src/ca/netSubscription.cpp | 8 +- src/ca/netWriteNotifyIO.cpp | 7 ++ src/ca/netiiu.cpp | 49 +++++--- src/ca/netiiu.h | 61 ++++++--- src/ca/oldAccess.h | 157 +++++++++++++++-------- src/ca/oldChannelNotify.cpp | 56 ++++++--- src/ca/syncGroupReadNotify.cpp | 2 +- src/ca/syncGroupWriteNotify.cpp | 2 +- src/ca/tcpiiu.cpp | 102 +++++++++------ src/ca/udpiiu.cpp | 89 ++++++++----- src/ca/udpiiu.h | 90 +++++++++----- src/ca/virtualCircuit.h | 130 ++++++++++++------- src/db/dbChannelIO.cpp | 32 ++++- src/db/dbChannelIO.h | 66 +++++----- src/db/dbSubscriptionIO.cpp | 2 +- src/libCom/osi/epicsMutex.cpp | 3 +- src/libCom/osi/epicsThread.cpp | 6 +- 27 files changed, 891 insertions(+), 551 deletions(-) diff --git a/src/ca/access.cpp b/src/ca/access.cpp index bee1fb297..edba95c00 100644 --- a/src/ca/access.cpp +++ b/src/ca/access.cpp @@ -623,7 +623,8 @@ int epicsShareAPI ca_array_put ( chtype type, arrayElementCount count, // extern "C" int epicsShareAPI ca_change_connection_event ( chid pChan, caCh *pfunc ) { - return pChan->changeConnCallBack ( pfunc ); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->changeConnCallBack ( guard, pfunc ); } /* @@ -632,7 +633,8 @@ int epicsShareAPI ca_change_connection_event ( chid pChan, caCh *pfunc ) // extern "C" int epicsShareAPI ca_replace_access_rights_event ( chid pChan, caArh *pfunc ) { - return pChan->replaceAccessRightsEvent ( pfunc ); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->replaceAccessRightsEvent ( guard, pfunc ); } /* @@ -971,16 +973,21 @@ int epicsShareAPI ca_add_fd_registration ( CAFDHANDLER * func, void * arg ) // extern "C" void epicsShareAPI ca_get_host_name ( chid pChan, char *pBuf, unsigned bufLength ) { - pChan->hostName ( pBuf, bufLength ); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + pChan->hostName ( guard, pBuf, bufLength ); } /* * ca_host_name () + * + * !!!! not thread safe !!!! + * */ // extern "C" const char * epicsShareAPI ca_host_name ( chid pChan ) { - return pChan->pHostName (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->pHostName ( guard ); } /* @@ -989,7 +996,8 @@ const char * epicsShareAPI ca_host_name ( chid pChan ) // extern "C" int epicsShareAPI ca_v42_ok ( chid pChan ) { - return pChan->ca_v42_ok (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->ca_v42_ok ( guard ); } /* @@ -1025,7 +1033,8 @@ int epicsShareAPI ca_replace_printf_handler ( caPrintfFunc *ca_printf_func ) // extern "C" short epicsShareAPI ca_field_type ( chid pChan ) { - return pChan->nativeType (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->nativeType ( guard ); } /* @@ -1034,7 +1043,8 @@ short epicsShareAPI ca_field_type ( chid pChan ) // extern "C" arrayElementCount epicsShareAPI ca_element_count ( chid pChan ) { - return pChan->nativeElementCount (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->nativeElementCount ( guard ); } /* @@ -1043,10 +1053,11 @@ arrayElementCount epicsShareAPI ca_element_count ( chid pChan ) // extern "C" enum channel_state epicsShareAPI ca_state ( chid pChan ) // X aCC 361 { - if ( pChan->connected() ) { + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + if ( pChan->connected ( guard ) ) { return cs_conn; } - else if ( pChan->previouslyConnected() ){ + else if ( pChan->previouslyConnected ( guard ) ){ return cs_prev_conn; } else { @@ -1060,7 +1071,8 @@ enum channel_state epicsShareAPI ca_state ( chid pChan ) // X aCC 361 // extern "C" void epicsShareAPI ca_set_puser ( chid pChan, void *puser ) { - pChan->setPrivatePointer ( puser ); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + pChan->setPrivatePointer ( guard, puser ); } /* @@ -1069,7 +1081,8 @@ void epicsShareAPI ca_set_puser ( chid pChan, void *puser ) // extern "C" void * epicsShareAPI ca_puser ( chid pChan ) { - return pChan->privatePointer (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->privatePointer ( guard ); } /* @@ -1078,7 +1091,8 @@ void * epicsShareAPI ca_puser ( chid pChan ) // extern "C" unsigned epicsShareAPI ca_read_access ( chid pChan ) { - return pChan->accessRights().readPermit(); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->accessRights(guard).readPermit(); } /* @@ -1087,7 +1101,8 @@ unsigned epicsShareAPI ca_read_access ( chid pChan ) // extern "C" unsigned epicsShareAPI ca_write_access ( chid pChan ) { - return pChan->accessRights().writePermit(); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->accessRights(guard).writePermit(); } /* @@ -1096,24 +1111,28 @@ unsigned epicsShareAPI ca_write_access ( chid pChan ) // extern "C" const char * epicsShareAPI ca_name ( chid pChan ) { - return pChan->pName (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->pName ( guard ); } // extern "C" unsigned epicsShareAPI ca_search_attempts ( chid pChan ) { - return pChan->searchAttempts (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->searchAttempts ( guard ); } // extern "C" double epicsShareAPI ca_beacon_period ( chid pChan ) { - return pChan->beaconPeriod (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->beaconPeriod ( guard ); } double epicsShareAPI ca_receive_watchdog_delay ( chid pChan ) { - return pChan->receiveWatchdogDelay (); + epicsGuard < epicsMutex > guard ( pChan->getClientCtx().mutex ); + return pChan->receiveWatchdogDelay ( guard ); } /* diff --git a/src/ca/ca_client_context.cpp b/src/ca/ca_client_context.cpp index 1c66719c7..1531d1cb0 100644 --- a/src/ca/ca_client_context.cpp +++ b/src/ca/ca_client_context.cpp @@ -656,25 +656,6 @@ void ca_client_context::callbackProcessingCompleteNotify () } } -void ca_client_context::changeConnCallBack ( - caCh * pfunc, caCh * & pConnCallBack, const bool & currentlyConnected ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( ! currentlyConnected ) { - if ( pfunc ) { - if ( ! pConnCallBack ) { - this->decrementOutstandingIO ( guard, this->ioSeqNo ); - } - } - else { - if ( pConnCallBack ) { - this->incrementOutstandingIO ( guard, this->ioSeqNo ); - } - } - } - pConnCallBack = pfunc; -} - cacChannel & ca_client_context::createChannel ( epicsGuard < epicsMutex > & guard, const char * pChannelName, oldChannelNotify & chan, cacChannel::priLev pri ) diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index 7777a5faf..b7d5b4d14 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -426,7 +426,7 @@ void cac::beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime, this->beaconAnomalyCount++; - this->pudpiiu->beaconAnomalyNotify ( currentTime ); + this->pudpiiu->beaconAnomalyNotify ( guard, currentTime ); # if DEBUG { @@ -482,86 +482,84 @@ bool cac::transferChanToVirtCircuit ( return false; } - { - epicsGuard < epicsMutex > guard ( this->mutex ); + epicsGuard < epicsMutex > guard ( this->mutex ); - /* - * ignore search replies for deleted channels - */ - nciu * pChan = this->chanTable.lookup ( cid ); - if ( ! pChan ) { + /* + * ignore search replies for deleted channels + */ + nciu * pChan = this->chanTable.lookup ( cid ); + if ( ! pChan ) { + return false; + } + + /* + * Ignore duplicate search replies + */ + osiSockAddr chanAddr = pChan->getPIIU(guard)->getNetworkAddress (guard); + if ( chanAddr.sa.sa_family != AF_UNSPEC ) { + if ( ! sockAddrAreIdentical ( &addr, &chanAddr ) ) { + char acc[64]; + pChan->getPIIU(guard)->hostName ( guard, acc, sizeof ( acc ) ); + msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList ) + msgForMultiplyDefinedPV ( this->ipToAEngine, + *this, pChan->pName ( guard ), acc ); + pMsg->ioInitiate ( addr ); + } + return false; + } + + /* + * look for an existing virtual circuit + */ + caServerID servID ( addr.ia, pChan->getPriority(guard) ); + piiu = this->serverTable.lookup ( servID ); + if ( piiu ) { + if ( ! piiu->alive ( guard ) ) { return false; } - - /* - * Ignore duplicate search replies - */ - osiSockAddr chanAddr = pChan->getPIIU()->getNetworkAddress (); - if ( chanAddr.sa.sa_family != AF_UNSPEC ) { - if ( ! sockAddrAreIdentical ( &addr, &chanAddr ) ) { - char acc[64]; - pChan->getPIIU()->hostName ( acc, sizeof ( acc ) ); - msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList ) - msgForMultiplyDefinedPV ( this->ipToAEngine, - *this, pChan->pName (), acc ); - pMsg->ioInitiate ( addr ); - } - return false; - } - - /* - * look for an existing virtual circuit - */ - caServerID servID ( addr.ia, pChan->getPriority() ); - piiu = this->serverTable.lookup ( servID ); - if ( piiu ) { - if ( ! piiu->alive () ) { - return false; - } - } - else { - try { - autoPtrFreeList < tcpiiu, 32, epicsMutexNOOP > pnewiiu ( - this->freeListVirtualCircuit, - new ( this->freeListVirtualCircuit ) tcpiiu ( - *this, this->mutex, this->cbMutex, this->notify, this->connTMO, - this->timerQueue, addr, this->comBufMemMgr, minorVersionNumber, - this->ipToAEngine, pChan->getPriority() ) ); - bhe * pBHE = this->beaconTable.lookup ( addr.ia ); - if ( ! pBHE ) { - pBHE = new ( this->bheFreeList ) - bhe ( this->mutex, epicsTime (), 0u, addr.ia ); - if ( this->beaconTable.add ( *pBHE ) < 0 ) { - return false; - } + } + else { + try { + autoPtrFreeList < tcpiiu, 32, epicsMutexNOOP > pnewiiu ( + this->freeListVirtualCircuit, + new ( this->freeListVirtualCircuit ) tcpiiu ( + *this, this->mutex, this->cbMutex, this->notify, this->connTMO, + this->timerQueue, addr, this->comBufMemMgr, minorVersionNumber, + this->ipToAEngine, pChan->getPriority(guard) ) ); + bhe * pBHE = this->beaconTable.lookup ( addr.ia ); + if ( ! pBHE ) { + pBHE = new ( this->bheFreeList ) + bhe ( this->mutex, epicsTime (), 0u, addr.ia ); + if ( this->beaconTable.add ( *pBHE ) < 0 ) { + return false; } - this->serverTable.add ( *pnewiiu ); - this->serverList.add ( *pnewiiu ); - pBHE->registerIIU ( guard, *pnewiiu ); - piiu = pnewiiu.release (); - newIIU = true; - } - catch ( std::bad_alloc & ) { - return false; - } - catch ( ... ) { - errlogPrintf ( - "CAC: Unexpected exception during virtual circuit creation\n" ); - return false; } + this->serverTable.add ( *pnewiiu ); + this->serverList.add ( *pnewiiu ); + pBHE->registerIIU ( guard, *pnewiiu ); + piiu = pnewiiu.release (); + newIIU = true; } - - this->pudpiiu->uninstallChan ( cbGuard, guard, *pChan ); - piiu->installChannel ( cbGuard, guard, *pChan, sid, typeCode, count ); - - if ( ! piiu->ca_v42_ok () ) { - // connect to old server with lock applied - pChan->connect ( cbGuard, guard ); + catch ( std::bad_alloc & ) { + return false; + } + catch ( ... ) { + errlogPrintf ( + "CAC: Unexpected exception during virtual circuit creation\n" ); + return false; } } + this->pudpiiu->uninstallChan ( cbGuard, guard, *pChan ); + piiu->installChannel ( cbGuard, guard, *pChan, sid, typeCode, count ); + + if ( ! piiu->ca_v42_ok ( guard ) ) { + // connect to old server with lock applied + pChan->connect ( cbGuard, guard ); + } + if ( newIIU ) { - piiu->start (); + piiu->start ( guard ); } return true; @@ -581,7 +579,7 @@ void cac::destroyChannel ( throw std::logic_error ( "Invalid channel identifier" ); } - chan.getPIIU()->uninstallChan ( cbGuard, guard, chan ); + chan.getPIIU(guard)->uninstallChan ( cbGuard, guard, chan ); chan.destructor ( cbGuard, guard ); @@ -597,7 +595,7 @@ void cac::disconnectAllIO ( guard.assertIdenticalMutex ( this->mutex ); char buf[128]; - sprintf ( buf, "host = %.100s", chan.pHostName() ); + sprintf ( buf, "host = %.100s", chan.pHostName ( guard ) ); tsDLIter < baseNMIU > pNetIO = ioList.firstIter(); while ( pNetIO.valid () ) { @@ -650,8 +648,8 @@ void cac::writeRequest ( arrayElementCount nElem, const void * pValue ) { guard.assertIdenticalMutex ( this->mutex ); - this->flushIfRequired ( guard, *chan.getPIIU() ); - chan.getPIIU()->writeRequest ( guard, chan, type, nElem, pValue ); + this->flushIfRequired ( guard, *chan.getPIIU(guard) ); + chan.getPIIU(guard)->writeRequest ( guard, chan, type, nElem, pValue ); } netWriteNotifyIO & cac::writeNotifyRequest ( @@ -663,8 +661,8 @@ netWriteNotifyIO & cac::writeNotifyRequest ( guard, this->ioTable, *this, netWriteNotifyIO::factory ( this->freeListWriteNotifyIO, icni, notifyIn ) ); this->ioTable.add ( *pIO ); - this->flushIfRequired ( guard, *chan.getPIIU() ); - chan.getPIIU()->writeNotifyRequest ( + this->flushIfRequired ( guard, *chan.getPIIU(guard) ); + chan.getPIIU(guard)->writeNotifyRequest ( guard, chan, *pIO, type, nElem, pValue ); return *pIO.release(); } @@ -678,8 +676,8 @@ netReadNotifyIO & cac::readNotifyRequest ( guard, this->ioTable, *this, netReadNotifyIO::factory ( this->freeListReadNotifyIO, icni, notifyIn ) ); this->ioTable.add ( *pIO ); - this->flushIfRequired ( guard, *chan.getPIIU() ); - chan.getPIIU()->readNotifyRequest ( guard, chan, *pIO, type, nElem ); + this->flushIfRequired ( guard, *chan.getPIIU(guard) ); + chan.getPIIU(guard)->readNotifyRequest ( guard, chan, *pIO, type, nElem ); return *pIO.release(); } @@ -698,23 +696,24 @@ baseNMIU * cac::destroyIO ( if ( pIO ) { class netSubscription * pSubscr = pIO->isSubscription (); if ( pSubscr && chan.connected ( guard ) ) { - chan.getPIIU()->subscriptionCancelRequest ( + chan.getPIIU(guard)->subscriptionCancelRequest ( guard, chan, *pSubscr ); } // this uninstalls from the list and destroys the IO pIO->exception ( guard, *this, - ECA_CHANDESTROY, chan.pName() ); + ECA_CHANDESTROY, chan.pName ( guard ) ); } return pIO; } -void cac::ioShow ( const cacChannel::ioid & idIn, unsigned level ) const +void cac::ioShow ( + epicsGuard < epicsMutex > & guard, + const cacChannel::ioid & idIn, unsigned level ) const { - epicsGuard < epicsMutex > autoMutex ( this->mutex ); baseNMIU * pmiu = this->ioTable.lookup ( idIn ); if ( pmiu ) { - pmiu->show ( level ); + pmiu->show ( guard, level ); } } @@ -775,8 +774,8 @@ netSubscription & cac::subscriptionRequest ( privChan, type, nElem, mask, notifyIn ) ); this->ioTable.add ( *pIO ); if ( chan.connected ( guard ) ) { - this->flushIfRequired ( guard, *chan.getPIIU() ); - chan.getPIIU()->subscriptionRequest ( guard, chan, *pIO ); + this->flushIfRequired ( guard, *chan.getPIIU(guard) ); + chan.getPIIU(guard)->subscriptionRequest ( guard, chan, *pIO ); } return *pIO.release (); } @@ -816,12 +815,14 @@ bool cac::writeNotifyRespAction ( bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu, const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy ) { + epicsGuard < epicsMutex > guard ( this->mutex ); + /* * the channel id field is abused for * read notify status starting with CA V4.1 */ int caStatus; - if ( iiu.ca_v41_ok() ) { + if ( iiu.ca_v41_ok ( guard ) ) { caStatus = hdr.m_cid; } else { @@ -842,7 +843,6 @@ bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu, } # endif - epicsGuard < epicsMutex > guard ( this->mutex ); baseNMIU * pmiu = this->ioTable.remove ( hdr.m_available ); // // The IO destroy routines take the call back mutex @@ -883,11 +883,13 @@ bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu, return true; } + epicsGuard < epicsMutex > guard ( this->mutex ); + /* * the channel id field is abused for * read notify status starting with CA V4.1 */ - if ( iiu.ca_v41_ok() ) { + if ( iiu.ca_v41_ok ( guard ) ) { caStatus = hdr.m_cid; } else { @@ -913,7 +915,6 @@ bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu, // no need to worry here about the baseNMIU being deleted while // it is in use here. // - epicsGuard < epicsMutex > guard ( this->mutex ); baseNMIU * pmiu = this->ioTable.lookup ( hdr.m_available ); if ( pmiu ) { if ( caStatus == ECA_NORMAL ) { @@ -957,14 +958,12 @@ bool cac::defaultExcep ( callbackManager &, tcpiiu & iiu, const caHdrLargeArray &, const char * pCtx, unsigned status ) { + epicsGuard < epicsMutex > guard ( this->mutex ); char buf[512]; char hostName[64]; - iiu.hostName ( hostName, sizeof ( hostName ) ); + iiu.hostName ( guard, hostName, sizeof ( hostName ) ); sprintf ( buf, "host=%s ctx=%.400s", hostName, pCtx ); - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->notify.exception ( guard, status, buf, 0, 0u ); - } + this->notify.exception ( guard, status, buf, 0, 0u ); return true; } @@ -1095,17 +1094,17 @@ bool cac::createChannelRespAction ( nciu * pChan = this->chanTable.lookup ( hdr.m_cid ); if ( pChan ) { unsigned sidTmp; - if ( iiu.ca_v44_ok() ) { + if ( iiu.ca_v44_ok ( guard ) ) { sidTmp = hdr.m_available; } else { - sidTmp = pChan->getSID (); + sidTmp = pChan->getSID (guard); } iiu.connectNotify ( guard, *pChan ); pChan->connect ( hdr.m_dataType, hdr.m_count, sidTmp, mgr.cbGuard, guard ); } - else if ( iiu.ca_v44_ok() ) { + else if ( iiu.ca_v44_ok ( guard ) ) { // this indicates a claim response for a resource that does // not exist in the client - so just remove it from the server iiu.clearChannelRequest ( guard, hdr.m_available, hdr.m_cid ); @@ -1135,7 +1134,7 @@ void cac::disconnectChannel ( guard.assertIdenticalMutex ( this->mutex ); assert ( this->pudpiiu ); chan.disconnectAllIO ( cbGuard, guard ); - chan.getPIIU()->uninstallChan ( cbGuard, guard, chan ); + chan.getPIIU(guard)->uninstallChan ( cbGuard, guard, chan ); this->pudpiiu->installDisconnectedChannel ( chan ); chan.setServerAddressUnknown ( *this->pudpiiu, guard ); chan.unresponsiveCircuitNotify ( cbGuard, guard ); @@ -1144,8 +1143,9 @@ void cac::disconnectChannel ( bool cac::badTCPRespAction ( callbackManager &, tcpiiu & iiu, const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBdy */ ) { + epicsGuard < epicsMutex > guard ( this->mutex ); char hostName[64]; - iiu.hostName ( hostName, sizeof ( hostName ) ); + iiu.hostName ( guard, hostName, sizeof ( hostName ) ); errlogPrintf ( "CAC: Undecipherable TCP message ( bad response type %u ) from %s\n", hdr.m_cmmd, hostName ); return false; @@ -1181,10 +1181,10 @@ void cac::destroyIIU ( tcpiiu & iiu ) epicsGuard < epicsMutex > guard ( this->mutex ); if ( iiu.channelCount ( guard ) ) { char hostNameTmp[64]; - iiu.hostName ( hostNameTmp, sizeof ( hostNameTmp ) ); + iiu.hostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) ); genLocalExcep ( cbGuard, guard, *this, ECA_DISCONN, hostNameTmp ); } - osiSockAddr addr = iiu.getNetworkAddress(); + osiSockAddr addr = iiu.getNetworkAddress ( guard ); if ( addr.sa.sa_family == AF_INET ) { inetAddrID tmp ( addr.ia ); bhe * pBHE = this->beaconTable.lookup ( tmp ); @@ -1216,12 +1216,13 @@ void cac::destroyIIU ( tcpiiu & iiu ) } } -double cac::beaconPeriod ( const nciu & chan ) const +double cac::beaconPeriod ( + epicsGuard < epicsMutex > & guard, + const nciu & chan ) const { - epicsGuard < epicsMutex > guard ( this->mutex ); - const netiiu * pIIU = chan.getConstPIIU (); + const netiiu * pIIU = chan.getConstPIIU ( guard ); if ( pIIU ) { - osiSockAddr addr = pIIU->getNetworkAddress (); + osiSockAddr addr = pIIU->getNetworkAddress ( guard ); if ( addr.sa.sa_family == AF_INET ) { inetAddrID tmp ( addr.ia ); bhe *pBHE = this->beaconTable.lookup ( tmp ); diff --git a/src/ca/cac.h b/src/ca/cac.h index bed44185e..3dc222907 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -176,7 +176,9 @@ public: epicsGuard < epicsMutex > & guard, nciu &, tsDLList < baseNMIU > & ioList ); - void ioShow ( const cacChannel::ioid &id, unsigned level ) const; + void ioShow ( + epicsGuard < epicsMutex > & guard, + const cacChannel::ioid &id, unsigned level ) const; // sync group routines CASG * lookupCASG ( epicsGuard < epicsMutex > &, unsigned id ); @@ -210,8 +212,11 @@ public: unsigned getInitializingThreadsPriority () const; epicsMutex & mutexRef (); void attachToClientCtx (); - void selfTest ( epicsGuard < epicsMutex > & ) const; - double beaconPeriod ( const nciu & chan ) const; + void selfTest ( + epicsGuard < epicsMutex > & ) const; + double beaconPeriod ( + epicsGuard < epicsMutex > &, + const nciu & chan ) const; static unsigned lowestPriorityLevelAbove ( unsigned priority ); static unsigned highestPriorityLevelBelow ( unsigned priority ); void destroyIIU ( tcpiiu & iiu ); diff --git a/src/ca/cacChannel.cpp b/src/ca/cacChannel.cpp index a724a14d3..0aa5286f3 100644 --- a/src/ca/cacChannel.cpp +++ b/src/ca/cacChannel.cpp @@ -43,39 +43,47 @@ cacChannel::~cacChannel () { } -caAccessRights cacChannel::accessRights () const +caAccessRights cacChannel::accessRights ( + epicsGuard < epicsMutex > & ) const { static caAccessRights ar ( true, true ); return ar; } -unsigned cacChannel::searchAttempts () const +unsigned cacChannel::searchAttempts ( + epicsGuard < epicsMutex > & ) const { return 0u; } -double cacChannel::beaconPeriod () const +double cacChannel::beaconPeriod ( + epicsGuard < epicsMutex > & ) const { return - DBL_MAX; } -double cacChannel::receiveWatchdogDelay () const +double cacChannel::receiveWatchdogDelay ( + epicsGuard < epicsMutex > & ) const { return - DBL_MAX; } -bool cacChannel::ca_v42_ok () const +bool cacChannel::ca_v42_ok ( + epicsGuard < epicsMutex > & ) const { return true; } -bool cacChannel::connected () const +bool cacChannel::connected ( + epicsGuard < epicsMutex > & ) const { return true; } // the default is to assume that it is a locally hosted channel -void cacChannel::hostName ( char *pBuf, unsigned bufLength ) const +void cacChannel::hostName ( + epicsGuard < epicsMutex > &, + char *pBuf, unsigned bufLength ) const { if ( bufLength ) { epicsSingleton < localHostName >::reference @@ -86,7 +94,8 @@ void cacChannel::hostName ( char *pBuf, unsigned bufLength ) const // deprecated - please do not use // the default is to assume that it is a locally hosted channel -const char * cacChannel::pHostName () const +const char * cacChannel::pHostName ( + epicsGuard < epicsMutex > & ) const { epicsSingleton < localHostName >::reference ref ( localHostNameAtLoadTime.getReference () ); diff --git a/src/ca/cacIO.h b/src/ca/cacIO.h index 0bf448644..c4c1a244c 100644 --- a/src/ca/cacIO.h +++ b/src/ca/cacIO.h @@ -176,9 +176,11 @@ public: virtual void destroy ( epicsGuard < epicsMutex > & callbackControlGuard, epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0; - cacChannelNotify & notify () const; - virtual const char * pName () const = 0; // not thread safe + cacChannelNotify & notify () const; // required ????? + virtual const char * pName ( + epicsGuard < epicsMutex > & ) const = 0; virtual void show ( + epicsGuard < epicsMutex > &, unsigned level ) const = 0; virtual void initiateConnect ( epicsGuard < epicsMutex > & ) = 0; @@ -203,18 +205,29 @@ public: epicsGuard < epicsMutex > & mutualExclusionGuard, const ioid & ) = 0; virtual void ioShow ( + epicsGuard < epicsMutex > &, const ioid &, unsigned level ) const = 0; - virtual short nativeType () const = 0; - virtual arrayElementCount nativeElementCount () const = 0; - virtual caAccessRights accessRights () const; // defaults to unrestricted access - virtual unsigned searchAttempts () const; // defaults to zero - virtual double beaconPeriod () const; // defaults to negative DBL_MAX - virtual double receiveWatchdogDelay () const; // defaults to negative DBL_MAX - virtual bool ca_v42_ok () const; // defaults to true - virtual bool connected () const; // defaults to true + virtual short nativeType ( + epicsGuard < epicsMutex > & ) const = 0; + virtual arrayElementCount nativeElementCount ( + epicsGuard < epicsMutex > & ) const = 0; + virtual caAccessRights accessRights ( + epicsGuard < epicsMutex > & ) const; + virtual unsigned searchAttempts ( + epicsGuard < epicsMutex > & ) const; + virtual double beaconPeriod ( + epicsGuard < epicsMutex > & ) const; // negative DBL_MAX if UKN + virtual double receiveWatchdogDelay ( + epicsGuard < epicsMutex > & ) const; // negative DBL_MAX if UKN + virtual bool ca_v42_ok ( + epicsGuard < epicsMutex > & ) const; + virtual bool connected ( + epicsGuard < epicsMutex > & ) const; virtual void hostName ( - char * pBuf, unsigned bufLength ) const; // defaults to local host name - virtual const char * pHostName () const; + epicsGuard < epicsMutex > &, + char * pBuf, unsigned bufLength ) const; + virtual const char * pHostName ( + epicsGuard < epicsMutex > & ) const; // exceptions class badString {}; diff --git a/src/ca/nciu.cpp b/src/ca/nciu.cpp index 61a9723ba..da12d18c7 100644 --- a/src/ca/nciu.cpp +++ b/src/ca/nciu.cpp @@ -105,7 +105,7 @@ void nciu::destructor ( // the clear channel request to the server when the claim reply // arrives and there is no matching nciu in the client if ( this->connected ( guard ) ) { - this->getPIIU()->clearChannelRequest ( + this->getPIIU(guard)->clearChannelRequest ( guard, this->sid, this->id ); } @@ -155,7 +155,7 @@ void nciu::connect ( unsigned nativeType, * if less than v4.1 then the server will never * send access rights and there will always be access */ - bool v41Ok = this->piiu->ca_v41_ok (); + bool v41Ok = this->piiu->ca_v41_ok ( guard ); if ( ! v41Ok ) { this->accessRightState.setReadPermit(); this->accessRightState.setWritePermit(); @@ -253,14 +253,17 @@ bool nciu::searchMsg ( udpiiu & iiu, unsigned & retryNoForThisChannel ) return success; } - -const char *nciu::pName () const +const char *nciu::pName ( + epicsGuard < epicsMutex > & guard ) const { + guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); return this->pNameStr; } -unsigned nciu::nameLen () const +unsigned nciu::nameLen ( + epicsGuard < epicsMutex > & guard ) const { + guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); return this->nameLength; } @@ -269,6 +272,8 @@ cacChannel::ioStatus nciu::read ( unsigned type, arrayElementCount countIn, cacReadNotify ¬ify, ioid *pId ) { + guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); + if ( ! this->isConnected ( guard ) ) { throw cacChannel::notConnected (); } @@ -315,6 +320,8 @@ void nciu::write ( epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount countIn, const void * pValue ) { + guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); + // make sure that they get this and not "no write access" // if disconnected if ( ! this->connected ( guard ) ) { @@ -381,32 +388,37 @@ void nciu::ioCancel ( this->cacCtx.destroyIO ( cbGuard, guard, idIn, *this ); } -void nciu::ioShow ( const ioid &idIn, unsigned level ) const +void nciu::ioShow ( + epicsGuard < epicsMutex > & guard, + const ioid &idIn, unsigned level ) const { - this->cacCtx.ioShow ( idIn, level ); + this->cacCtx.ioShow ( guard, idIn, level ); } -void nciu::hostName ( char *pBuf, unsigned bufLength ) const +void nciu::hostName ( + epicsGuard < epicsMutex > & guard, + char *pBuf, unsigned bufLength ) const { - epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); - this->piiu->hostName ( pBuf, bufLength ); + this->piiu->hostName ( + guard, pBuf, bufLength ); } // deprecated - please do not use, this is _not_ thread safe -const char * nciu::pHostName () const +const char * nciu::pHostName ( + epicsGuard < epicsMutex > & guard ) const { - return this->piiu->pHostName (); // ouch ! + return this->piiu->pHostName ( guard ); } -bool nciu::ca_v42_ok () const +bool nciu::ca_v42_ok ( + epicsGuard < epicsMutex > & guard ) const { - epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); - return this->piiu->ca_v42_ok (); + return this->piiu->ca_v42_ok ( guard ); } -short nciu::nativeType () const +short nciu::nativeType ( + epicsGuard < epicsMutex > & guard ) const { - epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef() ); short type; if ( this->channelNode::isConnected ( guard ) ) { if ( this->typeCode < SHRT_MAX ) { @@ -422,34 +434,41 @@ short nciu::nativeType () const return type; } -arrayElementCount nciu::nativeElementCount () const +arrayElementCount nciu::nativeElementCount ( + epicsGuard < epicsMutex > & guard ) const { - epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef() ); - return this->nativeElementCount ( guard ); + arrayElementCount countOut; + if ( this->channelNode::isConnected ( guard ) ) { + countOut = this->count; + } + else { + countOut = 0ul; + } + return countOut; } -caAccessRights nciu::accessRights () const +caAccessRights nciu::accessRights ( + epicsGuard < epicsMutex > & guard ) const { - epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); - caAccessRights tmp = this->accessRightState; - return tmp; + return this->accessRightState; } -unsigned nciu::searchAttempts () const +unsigned nciu::searchAttempts ( + epicsGuard < epicsMutex > & guard ) const { - epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); return this->retry; } -double nciu::beaconPeriod () const +double nciu::beaconPeriod ( + epicsGuard < epicsMutex > & guard ) const { - return this->cacCtx.beaconPeriod ( *this ); + return this->cacCtx.beaconPeriod ( guard, *this ); } -double nciu::receiveWatchdogDelay () const +double nciu::receiveWatchdogDelay ( + epicsGuard < epicsMutex > & guard ) const { - epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); - return this->piiu->receiveWatchdogDelay (); + return this->piiu->receiveWatchdogDelay ( guard ); } bool nciu::connected ( epicsGuard < epicsMutex > & guard ) const @@ -461,9 +480,15 @@ bool nciu::connected ( epicsGuard < epicsMutex > & guard ) const void nciu::show ( unsigned level ) const { epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef() ); + this->show ( guard, level ); +} + +void nciu::show ( + epicsGuard < epicsMutex > & guard, unsigned level ) const +{ if ( this->channelNode::isConnected ( guard ) ) { char hostNameTmp [256]; - this->hostName ( hostNameTmp, sizeof ( hostNameTmp ) ); + this->hostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) ); ::printf ( "Channel \"%s\", connected to server %s", this->pNameStr, hostNameTmp ); if ( level > 1u ) { @@ -489,7 +514,8 @@ void nciu::show ( unsigned level ) const } } -void nciu::beaconAnomalyNotify () +void nciu::beaconAnomalyNotify ( + epicsGuard < epicsMutex > & guard ) { if ( this->retry > beaconAnomalyRetrySetpoint ) { this->retry = beaconAnomalyRetrySetpoint; @@ -515,7 +541,7 @@ void nciu::resubscribe ( epicsGuard < epicsMutex > & guard ) // them here. if ( pSubscr ) { try { - this->getPIIU()->subscriptionRequest ( guard, *this, *pSubscr ); + this->getPIIU(guard)->subscriptionRequest ( guard, *this, *pSubscr ); } catch ( ... ) { errlogPrintf ( "CAC: failed to send subscription request during channel connect\n" ); @@ -553,16 +579,3 @@ void nciu::disconnectAllIO ( *this, this->eventq ); } -arrayElementCount nciu::nativeElementCount ( - epicsGuard < epicsMutex > & guard ) const -{ - arrayElementCount countOut; - if ( this->channelNode::isConnected ( guard ) ) { - countOut = this->count; - } - else { - countOut = 0ul; - } - return countOut; -} - diff --git a/src/ca/nciu.h b/src/ca/nciu.h index a835f87c9..3e9b0a251 100644 --- a/src/ca/nciu.h +++ b/src/ca/nciu.h @@ -110,32 +110,45 @@ public: void setServerAddressUnknown ( udpiiu & newiiu, epicsGuard < epicsMutex > & guard ); bool searchMsg ( class udpiiu & iiu, unsigned & retryNoForThisChannel ); - void beaconAnomalyNotify (); + void beaconAnomalyNotify ( + epicsGuard < epicsMutex > & ); void serviceShutdownNotify (); void accessRightsStateChange ( const caAccessRights &, epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); - ca_uint32_t getSID () const; - ca_uint32_t getCID () const; - netiiu * getPIIU (); - const netiiu * getConstPIIU () const; + ca_uint32_t getSID ( + epicsGuard < epicsMutex > & ) const; + ca_uint32_t getCID ( + epicsGuard < epicsMutex > & ) const; + netiiu * getPIIU ( + epicsGuard < epicsMutex > & ); + const netiiu * getConstPIIU ( + epicsGuard < epicsMutex > & ) const; cac & getClient (); void searchReplySetUp ( netiiu &iiu, unsigned sidIn, ca_uint16_t typeIn, arrayElementCount countIn, epicsGuard < epicsMutex > & ); - void show ( unsigned level ) const; - const char * pName () const; - unsigned nameLen () const; - const char * pHostName () const; // deprecated - please do not use + void show ( + unsigned level ) const; + void show ( + epicsGuard < epicsMutex > &, + unsigned level ) const; + const char * pName ( + epicsGuard < epicsMutex > & ) const; + unsigned nameLen ( + epicsGuard < epicsMutex > & ) const; + const char * pHostName ( + epicsGuard < epicsMutex > & ) const; // deprecated - please do not use void writeException ( epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > &, int status, const char *pContext, unsigned type, arrayElementCount count ); - cacChannel::priLev getPriority () const; + cacChannel::priLev getPriority ( + epicsGuard < epicsMutex > & ) const; void * operator new ( size_t size, tsFreeList < class nciu, 1024, epicsMutexNOOP > & ); epicsPlacementDeleteOperator ( ( void *, tsFreeList < class nciu, 1024, epicsMutexNOOP > & )) - arrayElementCount nativeElementCount ( epicsGuard < epicsMutex > & ) const; + //arrayElementCount nativeElementCount ( epicsGuard < epicsMutex > & ) const; void resubscribe ( epicsGuard < epicsMutex > & ); void sendSubscriptionUpdateRequests ( epicsGuard < epicsMutex > & ); void disconnectAllIO ( @@ -183,15 +196,25 @@ private: epicsGuard < epicsMutex > & mutualExclusionGuard, const ioid & ); void ioShow ( + epicsGuard < epicsMutex > &, const ioid &, unsigned level ) const; - short nativeType () const; - caAccessRights accessRights () const; - unsigned searchAttempts () const; - double beaconPeriod () const; - double receiveWatchdogDelay () const; - bool ca_v42_ok () const; - void hostName ( char *pBuf, unsigned bufLength ) const; - arrayElementCount nativeElementCount () const; + short nativeType ( + epicsGuard < epicsMutex > & ) const; + caAccessRights accessRights ( + epicsGuard < epicsMutex > & ) const; + unsigned searchAttempts ( + epicsGuard < epicsMutex > & ) const; + double beaconPeriod ( + epicsGuard < epicsMutex > & ) const; + double receiveWatchdogDelay ( + epicsGuard < epicsMutex > & ) const; + bool ca_v42_ok ( + epicsGuard < epicsMutex > & ) const; + void hostName ( + epicsGuard < epicsMutex > &, + char *pBuf, unsigned bufLength ) const; + arrayElementCount nativeElementCount ( + epicsGuard < epicsMutex > & ) const; static void stringVerify ( const char *pStr, const unsigned count ); virtual void ioCompletionNotify ( epicsGuard < epicsMutex > &, class baseNMIU & ); @@ -215,12 +238,14 @@ inline void nciu::operator delete ( void * pCadaver, } #endif -inline ca_uint32_t nciu::getSID () const +inline ca_uint32_t nciu::getSID ( + epicsGuard < epicsMutex > & ) const { return this->sid; } -inline ca_uint32_t nciu::getCID () const +inline ca_uint32_t nciu::getCID ( + epicsGuard < epicsMutex > & ) const { return this->id; } @@ -243,7 +268,8 @@ inline void nciu::searchReplySetUp ( netiiu &iiu, unsigned sidIn, this->sid = sidIn; } -inline netiiu * nciu::getPIIU () +inline netiiu * nciu::getPIIU ( + epicsGuard < epicsMutex > & ) { return this->piiu; } @@ -258,7 +284,8 @@ inline void nciu::writeException ( status, pContext, typeIn, countIn ); } -inline const netiiu * nciu::getConstPIIU () const +inline const netiiu * nciu::getConstPIIU ( + epicsGuard < epicsMutex > & ) const { return this->piiu; } @@ -273,7 +300,8 @@ inline cac & nciu::getClient () return this->cacCtx; } -inline cacChannel::priLev nciu::getPriority () const +inline cacChannel::priLev nciu::getPriority ( + epicsGuard < epicsMutex > & ) const { return this->priority; } diff --git a/src/ca/netIO.h b/src/ca/netIO.h index 398acd244..ad52c66e4 100644 --- a/src/ca/netIO.h +++ b/src/ca/netIO.h @@ -62,7 +62,11 @@ public: unsigned type, arrayElementCount count, const void * pData ) = 0; virtual class netSubscription * isSubscription () = 0; - virtual void show ( unsigned level ) const = 0; + virtual void show ( + unsigned level ) const = 0; + virtual void show ( + epicsGuard < epicsMutex > &, + unsigned level ) const = 0; protected: NETIO_VIRTUAL_DESTRUCTOR ~baseNMIU (); }; @@ -73,11 +77,16 @@ public: tsFreeList < class netSubscription, 1024, epicsMutexNOOP > &, class privateInterfaceForIO &, unsigned type, arrayElementCount count, unsigned mask, cacStateNotify & ); - void show ( unsigned level ) const; + void show ( + unsigned level ) const; + void show ( + epicsGuard < epicsMutex > &, unsigned level ) const; arrayElementCount getCount ( epicsGuard < epicsMutex > & ) const; - unsigned getType () const; - unsigned getMask () const; + unsigned getType ( + epicsGuard < epicsMutex > & ) const; + unsigned getMask ( + epicsGuard < epicsMutex > & ) const; void subscriptionUpdateIfRequired ( epicsGuard < epicsMutex > &, nciu & ); protected: @@ -123,7 +132,10 @@ public: static netReadNotifyIO * factory ( tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > &, privateInterfaceForIO &, cacReadNotify & ); - void show ( unsigned level ) const; + void show ( + unsigned level ) const; + void show ( + epicsGuard < epicsMutex > &, unsigned level ) const; protected: ~netReadNotifyIO (); private: @@ -161,7 +173,10 @@ public: static netWriteNotifyIO * factory ( tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > &, privateInterfaceForIO &, cacWriteNotify & ); - void show ( unsigned level ) const; + void show ( + unsigned level ) const; + void show ( + epicsGuard < epicsMutex > &, unsigned level ) const; protected: ~netWriteNotifyIO (); private: @@ -230,12 +245,12 @@ inline arrayElementCount netSubscription::getCount ( } } -inline unsigned netSubscription::getType () const +inline unsigned netSubscription::getType ( epicsGuard < epicsMutex > & ) const { return this->type; } -inline unsigned netSubscription::getMask () const +inline unsigned netSubscription::getMask ( epicsGuard < epicsMutex > & ) const { return this->mask; } diff --git a/src/ca/netReadNotifyIO.cpp b/src/ca/netReadNotifyIO.cpp index a0a4169c2..b9bac9046 100644 --- a/src/ca/netReadNotifyIO.cpp +++ b/src/ca/netReadNotifyIO.cpp @@ -41,10 +41,16 @@ netReadNotifyIO::~netReadNotifyIO () void netReadNotifyIO::show ( unsigned /* level */ ) const { - ::printf ( "read notify IO at %p\n", + ::printf ( "netReadNotifyIO at %p\n", static_cast < const void * > ( this ) ); } +void netReadNotifyIO::show ( + epicsGuard < epicsMutex > &, unsigned level ) const +{ + this->show ( level ); +} + void netReadNotifyIO::destroy ( epicsGuard < epicsMutex > & guard, cacRecycle & recycle ) { diff --git a/src/ca/netSubscription.cpp b/src/ca/netSubscription.cpp index 9c9ae8660..c69458e13 100644 --- a/src/ca/netSubscription.cpp +++ b/src/ca/netSubscription.cpp @@ -71,6 +71,12 @@ void netSubscription::show ( unsigned /* level */ ) const this->count, this->mask ); } +void netSubscription::show ( + epicsGuard < epicsMutex > &, unsigned level ) const +{ + this->show ( level ); +} + void netSubscription::completion ( epicsGuard < epicsMutex > & guard, cacRecycle & ) { @@ -152,7 +158,7 @@ void netSubscription::subscriptionUpdateIfRequired ( epicsGuard < epicsMutex > & guard, nciu & chan ) { if ( this->updateWhileDisconnected ) { - chan.getPIIU()->subscriptionUpdateRequest ( + chan.getPIIU(guard)->subscriptionUpdateRequest ( guard, chan, *this ); this->updateWhileDisconnected = false; } diff --git a/src/ca/netWriteNotifyIO.cpp b/src/ca/netWriteNotifyIO.cpp index 4696555b6..43e15915c 100644 --- a/src/ca/netWriteNotifyIO.cpp +++ b/src/ca/netWriteNotifyIO.cpp @@ -44,6 +44,13 @@ void netWriteNotifyIO::show ( unsigned /* level */ ) const static_cast < const void * > ( this ) ); } +void netWriteNotifyIO::show ( + epicsGuard < epicsMutex > &, + unsigned level ) const +{ + this->show ( level ); +} + void netWriteNotifyIO::destroy ( epicsGuard < epicsMutex > & guard, cacRecycle & recycle ) diff --git a/src/ca/netiiu.cpp b/src/ca/netiiu.cpp index 22bbf981a..f2950f5d9 100644 --- a/src/ca/netiiu.cpp +++ b/src/ca/netiiu.cpp @@ -32,29 +32,35 @@ netiiu::~netiiu () { } -bool netiiu::ca_v42_ok () const +bool netiiu::ca_v42_ok ( + epicsGuard < epicsMutex > & ) const { return false; } -bool netiiu::ca_v41_ok () const +bool netiiu::ca_v41_ok ( + epicsGuard < epicsMutex > & ) const { return false; } -void netiiu::writeRequest ( epicsGuard < epicsMutex > &, nciu &, - unsigned, arrayElementCount, const void * ) +void netiiu::writeRequest ( + epicsGuard < epicsMutex > &, nciu &, + unsigned, arrayElementCount, const void * ) { throw cacChannel::notConnected(); } -void netiiu::writeNotifyRequest ( epicsGuard < epicsMutex > &, - nciu &, netWriteNotifyIO &, unsigned, arrayElementCount, const void * ) +void netiiu::writeNotifyRequest ( + epicsGuard < epicsMutex > &, + nciu &, netWriteNotifyIO &, unsigned, + arrayElementCount, const void * ) { throw cacChannel::notConnected(); } -void netiiu::readNotifyRequest ( epicsGuard < epicsMutex > &, +void netiiu::readNotifyRequest ( + epicsGuard < epicsMutex > &, nciu &, netReadNotifyIO &, unsigned, arrayElementCount ) { throw cacChannel::notConnected(); @@ -80,36 +86,43 @@ void netiiu::subscriptionUpdateRequest ( { } -void netiiu::hostName ( char *pBuf, unsigned bufLength ) const +void netiiu::hostName ( + epicsGuard < epicsMutex > & guard, + char *pBuf, unsigned bufLength ) const { if ( bufLength ) { - strncpy ( pBuf, this->pHostName (), bufLength ); + strncpy ( pBuf, this->pHostName ( guard ), bufLength ); pBuf[bufLength - 1u] = '\0'; } } -const char * netiiu::pHostName () const +const char * netiiu::pHostName ( + epicsGuard < epicsMutex > & ) const { return ""; } -osiSockAddr netiiu::getNetworkAddress () const +osiSockAddr netiiu::getNetworkAddress ( + epicsGuard < epicsMutex > & ) const { osiSockAddr addr; addr.sa.sa_family = AF_UNSPEC; return addr; } -void netiiu::flushRequest ( epicsGuard < epicsMutex > & ) +void netiiu::flushRequest ( + epicsGuard < epicsMutex > & ) { } -bool netiiu::flushBlockThreshold ( epicsGuard < epicsMutex > & ) const +bool netiiu::flushBlockThreshold ( + epicsGuard < epicsMutex > & ) const { return false; } -void netiiu::flushRequestIfAboveEarlyThreshold ( epicsGuard < epicsMutex > & ) +void netiiu::flushRequestIfAboveEarlyThreshold ( + epicsGuard < epicsMutex > & ) { } @@ -118,13 +131,15 @@ void netiiu::blockUntilSendBacklogIsReasonable { } -void netiiu::requestRecvProcessPostponedFlush () +void netiiu::requestRecvProcessPostponedFlush ( + epicsGuard < epicsMutex > & ) { return; } -void netiiu::uninstallChan ( epicsGuard < epicsMutex > &, - epicsGuard < epicsMutex > &, nciu & ) +void netiiu::uninstallChan ( + epicsGuard < epicsMutex > &, + epicsGuard < epicsMutex > &, nciu & ) { throw cacChannel::notConnected(); } diff --git a/src/ca/netiiu.h b/src/ca/netiiu.h index 70d714f16..32a9c5535 100644 --- a/src/ca/netiiu.h +++ b/src/ca/netiiu.h @@ -40,36 +40,57 @@ class cac; class netiiu { public: virtual ~netiiu (); - virtual void hostName ( char *pBuf, unsigned bufLength ) const = 0; - virtual const char * pHostName () const = 0; // deprecated - please do not use - virtual bool ca_v41_ok () const = 0; - virtual bool ca_v42_ok () const = 0; - virtual void writeRequest ( epicsGuard < epicsMutex > &, nciu &, - unsigned type, arrayElementCount nElem, const void *pValue ) = 0; - virtual void writeNotifyRequest ( epicsGuard < epicsMutex > &, + virtual void hostName ( + epicsGuard < epicsMutex > &, char * pBuf, + unsigned bufLength ) const = 0; + virtual const char * pHostName ( + epicsGuard < epicsMutex > & ) const = 0; + virtual bool ca_v41_ok ( + epicsGuard < epicsMutex > & ) const = 0; + virtual bool ca_v42_ok ( + epicsGuard < epicsMutex > & ) const = 0; + virtual void writeRequest ( + epicsGuard < epicsMutex > &, nciu &, + unsigned type, arrayElementCount nElem, + const void *pValue ) = 0; + virtual void writeNotifyRequest ( + epicsGuard < epicsMutex > &, nciu &, netWriteNotifyIO &, - unsigned type, arrayElementCount nElem, const void *pValue ) = 0; - virtual void readNotifyRequest ( epicsGuard < epicsMutex > &, nciu &, - netReadNotifyIO &, unsigned type, arrayElementCount nElem ) = 0; - virtual void clearChannelRequest ( epicsGuard < epicsMutex > &, + unsigned type, arrayElementCount nElem, + const void *pValue ) = 0; + virtual void readNotifyRequest ( + epicsGuard < epicsMutex > &, nciu &, + netReadNotifyIO &, unsigned type, + arrayElementCount nElem ) = 0; + virtual void clearChannelRequest ( + epicsGuard < epicsMutex > &, ca_uint32_t sid, ca_uint32_t cid ) = 0; - virtual void subscriptionRequest ( epicsGuard < epicsMutex > &, + virtual void subscriptionRequest ( + epicsGuard < epicsMutex > &, nciu &, netSubscription & ) = 0; virtual void subscriptionUpdateRequest ( - epicsGuard < epicsMutex > &, nciu &, netSubscription & ) = 0; - virtual void subscriptionCancelRequest ( epicsGuard < epicsMutex > &, + epicsGuard < epicsMutex > &, + nciu &, netSubscription & ) = 0; + virtual void subscriptionCancelRequest ( + epicsGuard < epicsMutex > &, nciu & chan, netSubscription & subscr ) = 0; - virtual void flushRequest ( epicsGuard < epicsMutex > & ) = 0; - virtual bool flushBlockThreshold ( epicsGuard < epicsMutex > & ) const = 0; - virtual void flushRequestIfAboveEarlyThreshold ( epicsGuard < epicsMutex > & ) = 0; + virtual void flushRequest ( + epicsGuard < epicsMutex > & ) = 0; + virtual bool flushBlockThreshold ( + epicsGuard < epicsMutex > & ) const = 0; + virtual void flushRequestIfAboveEarlyThreshold ( + epicsGuard < epicsMutex > & ) = 0; virtual void blockUntilSendBacklogIsReasonable ( cacContextNotify &, epicsGuard < epicsMutex > & ) = 0; - virtual void requestRecvProcessPostponedFlush () = 0; - virtual osiSockAddr getNetworkAddress () const = 0; + virtual void requestRecvProcessPostponedFlush ( + epicsGuard < epicsMutex > & ) = 0; + virtual osiSockAddr getNetworkAddress ( + epicsGuard < epicsMutex > & ) const = 0; virtual void uninstallChan ( epicsGuard < epicsMutex > & cbMutex, epicsGuard < epicsMutex > & mutex, nciu & ) = 0; - virtual double receiveWatchdogDelay () const = 0; + virtual double receiveWatchdogDelay ( + epicsGuard < epicsMutex > & ) const = 0; }; #endif // netiiuh diff --git a/src/ca/oldAccess.h b/src/ca/oldAccess.h index 0de35d373..245c69a25 100644 --- a/src/ca/oldAccess.h +++ b/src/ca/oldAccess.h @@ -56,12 +56,19 @@ public: void destructor ( epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); - void setPrivatePointer ( void * ); - void * privatePointer () const; - int changeConnCallBack ( caCh *pfunc ); - int replaceAccessRightsEvent ( caArh *pfunc ); - const char *pName () const; - void show ( unsigned level ) const; + void setPrivatePointer ( + epicsGuard < epicsMutex > &, void * ); + void * privatePointer ( + epicsGuard < epicsMutex > & ) const; + int changeConnCallBack ( + epicsGuard < epicsMutex > &, caCh *pfunc ); + int replaceAccessRightsEvent ( + epicsGuard < epicsMutex > &, caArh *pfunc ); + const char * pName ( + epicsGuard < epicsMutex > & ) const; + void show ( + epicsGuard < epicsMutex > &, + unsigned level ) const; void initiateConnect ( epicsGuard < epicsMutex > & ); void read ( @@ -88,18 +95,32 @@ public: epicsGuard < epicsMutex > & callbackControl, epicsGuard < epicsMutex > & mutualExclusionGuard, const cacChannel::ioid & ); - void ioShow ( const cacChannel::ioid &, unsigned level ) const; - short nativeType () const; - arrayElementCount nativeElementCount () const; - caAccessRights accessRights () const; // defaults to unrestricted access - unsigned searchAttempts () const; // defaults to zero - double beaconPeriod () const; // defaults to negative DBL_MAX - double receiveWatchdogDelay () const; // defaults to negative DBL_MAX - bool ca_v42_ok () const; - bool connected () const; - bool previouslyConnected () const; - void hostName ( char *pBuf, unsigned bufLength ) const; // defaults to local host name - const char * pHostName () const; // deprecated - please do not use + void ioShow ( + epicsGuard < epicsMutex > & guard, + const cacChannel::ioid &, unsigned level ) const; + short nativeType ( + epicsGuard < epicsMutex > & ) const; + arrayElementCount nativeElementCount ( + epicsGuard < epicsMutex > & ) const; + caAccessRights accessRights ( + epicsGuard < epicsMutex > & ) const; + unsigned searchAttempts ( + epicsGuard < epicsMutex > & ) const; + double beaconPeriod ( + epicsGuard < epicsMutex > & ) const; + double receiveWatchdogDelay ( + epicsGuard < epicsMutex > & ) const; + bool ca_v42_ok ( + epicsGuard < epicsMutex > & ) const; + bool connected ( + epicsGuard < epicsMutex > & ) const; + bool previouslyConnected ( + epicsGuard < epicsMutex > & ) const; + void hostName ( + epicsGuard < epicsMutex > &, + char *pBuf, unsigned bufLength ) const; // defaults to local host name + const char * pHostName ( + epicsGuard < epicsMutex > & ) const; // deprecated - please do not use ca_client_context & getClientCtx (); void * operator new ( size_t size, tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & ); @@ -255,8 +276,10 @@ struct ca_client_context : public cacContextNotify public: ca_client_context ( bool enablePreemptiveCallback = false ); virtual ~ca_client_context (); - void changeExceptionEvent ( caExceptionHandler * pfunc, void * arg ); - void registerForFileDescriptorCallBack ( CAFDHANDLER * pFunc, void * pArg ); + void changeExceptionEvent ( + caExceptionHandler * pfunc, void * arg ); + void registerForFileDescriptorCallBack ( + CAFDHANDLER * pFunc, void * pArg ); void replaceErrLogHandler ( caPrintfFunc * ca_printf_func ); cacChannel & createChannel ( epicsGuard < epicsMutex > &, const char * pChannelName, @@ -300,8 +323,6 @@ public: void destroyGetCallback ( epicsGuard < epicsMutex > &, getCallback & ); void destroyPutCallback ( epicsGuard < epicsMutex > &, putCallback & ); void destroySubscription ( epicsGuard < epicsMutex > &, oldSubscription & ); - void changeConnCallBack ( caCh * pfunc, caCh * & pConnCallBack, - const bool & currentlyConnected ); epicsMutex & mutexRef () const; // exceptions @@ -369,6 +390,23 @@ private: friend int epicsShareAPI ca_sg_reset ( const CA_SYNC_GID gid ); friend int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid ); friend void epicsShareAPI caInstallDefaultService ( cacService & ); + friend int epicsShareAPI ca_change_connection_event ( chid pChan, caCh *pfunc ); + friend int epicsShareAPI ca_replace_access_rights_event ( chid pChan, caArh *pfunc ); + friend void epicsShareAPI ca_get_host_name ( chid pChan, char *pBuf, unsigned bufLength ); + friend const char * epicsShareAPI ca_host_name ( chid pChan ); + friend int epicsShareAPI ca_v42_ok ( chid pChan ); + friend short epicsShareAPI ca_field_type ( chid pChan ); + friend arrayElementCount epicsShareAPI ca_element_count ( chid pChan ); + friend enum channel_state epicsShareAPI ca_state ( chid pChan ); + friend void epicsShareAPI ca_set_puser ( chid pChan, void *puser ); + friend void * epicsShareAPI ca_puser ( chid pChan ); + friend void * epicsShareAPI ca_puser ( chid pChan ); + friend unsigned epicsShareAPI ca_read_access ( chid pChan ); + friend unsigned epicsShareAPI ca_write_access ( chid pChan ); + friend unsigned epicsShareAPI ca_search_attempts ( chid pChan ); + friend double epicsShareAPI ca_beacon_period ( chid pChan ); + friend double epicsShareAPI ca_receive_watchdog_delay ( chid pChan ); + friend const char * epicsShareAPI ca_name ( chid pChan ); }; int fetchClientContext ( ca_client_context * * ppcac ); @@ -378,14 +416,17 @@ inline ca_client_context & oldChannelNotify::getClientCtx () return this->cacCtx; } -inline const char * oldChannelNotify::pName () const +inline const char * oldChannelNotify::pName ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.pName (); + return this->io.pName ( guard ); } -inline void oldChannelNotify::show ( unsigned level ) const +inline void oldChannelNotify::show ( + epicsGuard < epicsMutex > & guard, + unsigned level ) const { - this->io.show ( level ); + this->io.show ( guard, level ); } inline void oldChannelNotify::initiateConnect ( @@ -403,64 +444,79 @@ inline void oldChannelNotify::ioCancel ( } inline void oldChannelNotify::ioShow ( + epicsGuard < epicsMutex > & guard, const cacChannel::ioid & id, unsigned level ) const { - this->io.ioShow ( id, level ); + this->io.ioShow ( guard, id, level ); } -inline short oldChannelNotify::nativeType () const +inline short oldChannelNotify::nativeType ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.nativeType (); + return this->io.nativeType ( guard ); } -inline arrayElementCount oldChannelNotify::nativeElementCount () const +inline arrayElementCount oldChannelNotify::nativeElementCount ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.nativeElementCount (); + return this->io.nativeElementCount ( guard ); } -inline caAccessRights oldChannelNotify::accessRights () const +inline caAccessRights oldChannelNotify::accessRights ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.accessRights (); + return this->io.accessRights ( guard ); } -inline unsigned oldChannelNotify::searchAttempts () const +inline unsigned oldChannelNotify::searchAttempts ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.searchAttempts (); + return this->io.searchAttempts ( guard ); } -inline double oldChannelNotify::beaconPeriod () const +inline double oldChannelNotify::beaconPeriod ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.beaconPeriod (); + return this->io.beaconPeriod ( guard ); } -inline double oldChannelNotify::receiveWatchdogDelay () const +inline double oldChannelNotify::receiveWatchdogDelay ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.receiveWatchdogDelay (); + return this->io.receiveWatchdogDelay ( guard ); } -inline bool oldChannelNotify::ca_v42_ok () const +inline bool oldChannelNotify::ca_v42_ok ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.ca_v42_ok (); + return this->io.ca_v42_ok ( guard ); } -inline bool oldChannelNotify::connected () const +inline bool oldChannelNotify::connected ( + epicsGuard < epicsMutex > & guard ) const { + guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); return this->currentlyConnected; } -inline bool oldChannelNotify::previouslyConnected () const +inline bool oldChannelNotify::previouslyConnected ( + epicsGuard < epicsMutex > & guard ) const { + guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); return this->prevConnected; } -inline void oldChannelNotify::hostName ( char *pBuf, unsigned bufLength ) const +inline void oldChannelNotify::hostName ( + epicsGuard < epicsMutex > & guard, + char *pBuf, unsigned bufLength ) const { - this->io.hostName ( pBuf, bufLength ); + this->io.hostName ( guard, pBuf, bufLength ); } -inline const char * oldChannelNotify::pHostName () const +inline const char * oldChannelNotify::pHostName ( + epicsGuard < epicsMutex > & guard ) const { - return this->io.pHostName (); + return this->io.pHostName ( guard ); } inline void * oldChannelNotify::operator new ( size_t size, @@ -514,13 +570,6 @@ inline oldChannelNotify & oldSubscription::channel () const return this->chan; } -inline int oldChannelNotify::changeConnCallBack ( caCh * pfunc ) -{ - this->cacCtx.changeConnCallBack ( pfunc, - this->pConnCallBack, this->currentlyConnected ); - return ECA_NORMAL; -} - inline void * getCopy::operator new ( size_t size, tsFreeList < class getCopy, 1024, epicsMutexNOOP > & freeList ) { diff --git a/src/ca/oldChannelNotify.cpp b/src/ca/oldChannelNotify.cpp index 6b9ea3e87..fbf7511f7 100644 --- a/src/ca/oldChannelNotify.cpp +++ b/src/ca/oldChannelNotify.cpp @@ -76,38 +76,56 @@ void oldChannelNotify::destructor ( this->~oldChannelNotify (); } -void oldChannelNotify::setPrivatePointer ( void *pPrivateIn ) +int oldChannelNotify::changeConnCallBack ( + epicsGuard < epicsMutex > & guard, caCh * pfunc ) +{ + guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); + if ( ! this->currentlyConnected ) { + if ( pfunc ) { + if ( ! this->pConnCallBack ) { + this->cacCtx.decrementOutstandingIO ( guard, this->ioSeqNo ); + } + } + else { + if ( this->pConnCallBack ) { + this->cacCtx.incrementOutstandingIO ( guard, this->ioSeqNo ); + } + } + } + pConnCallBack = pfunc; + + return ECA_NORMAL; +} + +void oldChannelNotify::setPrivatePointer ( + epicsGuard < epicsMutex > & guard, void *pPrivateIn ) { - epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef () ); this->pPrivate = pPrivateIn; } -void * oldChannelNotify::privatePointer () const +void * oldChannelNotify::privatePointer ( + epicsGuard < epicsMutex > & guard ) const { - epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef () ); return this->pPrivate; } -int oldChannelNotify::replaceAccessRightsEvent ( caArh *pfunc ) +int oldChannelNotify::replaceAccessRightsEvent ( + epicsGuard < epicsMutex > & guard, caArh * pfunc ) { - bool isConnected; - caAccessRights tmp; - { - epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef () ); - // The order of the following is significant to guarantee that the - // access rights handler is always gets called even if the channel connects - // while this is running. There is some very small chance that the - // handler could be called twice here with the same access rights state, but - // that will not upset the application. - this->pAccessRightsFunc = pfunc ? pfunc : cacNoopAccesRightsHandler; - isConnected = this->currentlyConnected; - tmp = this->io.accessRights (); - } - if ( isConnected ) { + // The order of the following is significant to guarantee that the + // access rights handler is always gets called even if the channel connects + // while this is running. There is some very small chance that the + // handler could be called twice here with the same access rights state, but + // that will not upset the application. + this->pAccessRightsFunc = pfunc ? pfunc : cacNoopAccesRightsHandler; + caAccessRights tmp = this->io.accessRights ( guard ); + + if ( this->currentlyConnected ) { struct access_rights_handler_args args; args.chid = this; args.ar.read_access = tmp.readPermit (); args.ar.write_access = tmp.writePermit (); + epicsGuardRelease < epicsMutex > unguard ( guard ); ( *pfunc ) ( args ); } return ECA_NORMAL; diff --git a/src/ca/syncGroupReadNotify.cpp b/src/ca/syncGroupReadNotify.cpp index c4912bd71..3ec917497 100644 --- a/src/ca/syncGroupReadNotify.cpp +++ b/src/ca/syncGroupReadNotify.cpp @@ -117,7 +117,7 @@ void syncGroupReadNotify::show ( ::printf ( "pending sg read op: pVal=%p\n", this->pValue ); if ( level > 0u ) { ::printf ( "pending sg op: chan=%s magic=%u sg=%p\n", - this->chan->pName(), this->magic, + this->chan->pName(guard), this->magic, static_cast < void * > ( & this->sg ) ); } } diff --git a/src/ca/syncGroupWriteNotify.cpp b/src/ca/syncGroupWriteNotify.cpp index d384f5eed..4f794c9a4 100644 --- a/src/ca/syncGroupWriteNotify.cpp +++ b/src/ca/syncGroupWriteNotify.cpp @@ -107,7 +107,7 @@ void syncGroupWriteNotify::show ( ::printf ( "pending write sg op\n" ); if ( level > 0u ) { ::printf ( "pending sg op: chan=%s magic=%u sg=%p\n", - this->chan->pName(), this->magic, + this->chan->pName(guard), this->magic, static_cast < void * > ( &this->sg ) ); } } diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp index daabbab87..8fc5e69a8 100644 --- a/src/ca/tcpiiu.cpp +++ b/src/ca/tcpiiu.cpp @@ -396,12 +396,13 @@ void tcpRecvThread::run () break; } else if ( stat.circuitState == swioLocalAbort ) { + callbackManager mgr ( this->ctxNotify, this->cbMutex ); + epicsGuard < epicsMutex > guard ( this->iiu.mutex ); char name[64]; - this->iiu.hostName ( name, sizeof ( name ) ); + this->iiu.hostName ( guard, name, sizeof ( name ) ); char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - callbackManager mgr ( this->ctxNotify, this->cbMutex ); this->iiu.printf ( mgr.cbGuard, "Unexpected problem with CA circuit to", " server \"%s\" was \"%s\" - disconnecting\n", @@ -471,8 +472,9 @@ void tcpRecvThread::run () this->iiu.initiateAbortShutdown ( mgr, guard ); } else if ( stat.circuitState == swioLocalAbort ) { + epicsGuard < epicsMutex > guard ( this->iiu.mutex ); char name[64]; - this->iiu.hostName ( name, sizeof ( name ) ); + this->iiu.hostName ( guard, name, sizeof ( name ) ); char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); @@ -730,12 +732,15 @@ tcpiiu::tcpiiu ( // this must always be called by the udp thread when it holds // the callback lock. -void tcpiiu::start () +void tcpiiu::start ( + epicsGuard < epicsMutex > & guard ) { + guard.assertIdenticalMutex ( this->mutex ); this->recvThread.start (); } -void tcpiiu::initiateCleanShutdown ( epicsGuard < epicsMutex > & guard ) +void tcpiiu::initiateCleanShutdown ( + epicsGuard < epicsMutex > & guard ) { guard.assertIdenticalMutex ( this->mutex ); if ( this->state == iiucs_connected ) { @@ -804,7 +809,7 @@ void tcpiiu::unresponsiveCircuitNotify ( this->sendDog.cancel (); if ( this->connectedList.count() ) { char hostNameTmp[128]; - this->hostName ( hostNameTmp, sizeof ( hostNameTmp ) ); + this->hostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) ); { epicsGuardRelease < epicsMutex > guardRelease ( guard ); genLocalExcep ( cbGuard, guard, this->cacRef, @@ -906,8 +911,8 @@ void tcpiiu::initiateAbortShutdown ( int exception = ECA_DISCONN; if ( this->channelCount( guard ) ) { - this->hostName ( hostNameTmp, sizeof ( hostNameTmp ) ); - if ( this->connecting () ) { + this->hostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) ); + if ( this->connecting ( guard ) ) { exception = ECA_CONNSEQTMO; } exceptionNeeded = true; @@ -1026,9 +1031,9 @@ bool tcpiiu::setEchoRequestPending ( epicsGuard < epicsMutex > & guard ) // X aC } } -void tcpiiu::flushIfRecvProcessRequested () +void tcpiiu::flushIfRecvProcessRequested ( + epicsGuard < epicsMutex > & guard ) { - epicsGuard < epicsMutex > guard ( this->mutex ); if ( this->recvProcessPostponedFlush ) { this->flushRequest ( guard ); this->recvProcessPostponedFlush = false; @@ -1051,7 +1056,8 @@ bool tcpiiu::processIncoming ( this->oldMsgHeaderAvailable = this->recvQue.popOldMsgHeader ( this->curMsg ); if ( ! this->oldMsgHeaderAvailable ) { - this->flushIfRecvProcessRequested (); + epicsGuard < epicsMutex > guard ( this->mutex ); + this->flushIfRecvProcessRequested ( guard ); return true; } } @@ -1060,7 +1066,8 @@ bool tcpiiu::processIncoming ( sizeof ( this->curMsg.m_postsize ) + sizeof ( this->curMsg.m_count ); if ( this->recvQue.occupiedBytes () < annexSize ) { - this->flushIfRecvProcessRequested (); + epicsGuard < epicsMutex > guard ( this->mutex ); + this->flushIfRecvProcessRequested ( guard ); return true; } this->curMsg.m_postsize = this->recvQue.popUInt32 (); @@ -1105,7 +1112,8 @@ bool tcpiiu::processIncoming ( &this->pCurData[this->curDataBytes], this->curMsg.m_postsize - this->curDataBytes ); if ( this->curDataBytes < this->curMsg.m_postsize ) { - this->flushIfRecvProcessRequested (); + epicsGuard < epicsMutex > guard ( this->mutex ); + this->flushIfRecvProcessRequested ( guard ); return true; } } @@ -1126,7 +1134,8 @@ bool tcpiiu::processIncoming ( this->curDataBytes += this->recvQue.removeBytes ( this->curMsg.m_postsize - this->curDataBytes ); if ( this->curDataBytes < this->curMsg.m_postsize ) { - this->flushIfRecvProcessRequested (); + epicsGuard < epicsMutex > guard ( this->mutex ); + this->flushIfRecvProcessRequested ( guard ); return true; } } @@ -1272,7 +1281,7 @@ void tcpiiu::writeRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431 comQueSendMsgMinder minder ( this->sendQue, guard ); this->sendQue.insertRequestWithPayLoad ( CA_PROTO_WRITE, - type, nElem, chan.getSID(), chan.getCID(), pValue, + type, nElem, chan.getSID(guard), chan.getCID(guard), pValue, CA_V49 ( this->minorProtocolVersion ) ); minder.commit (); } @@ -1284,12 +1293,12 @@ void tcpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 43 { guard.assertIdenticalMutex ( this->mutex ); - if ( ! this->ca_v41_ok () ) { + if ( ! this->ca_v41_ok ( guard ) ) { throw cacChannel::unsupportedByService(); } comQueSendMsgMinder minder ( this->sendQue, guard ); this->sendQue.insertRequestWithPayLoad ( CA_PROTO_WRITE_NOTIFY, - type, nElem, chan.getSID(), io.getId(), pValue, + type, nElem, chan.getSID(guard), io.getId(), pValue, CA_V49 ( this->minorProtocolVersion ) ); minder.commit (); } @@ -1320,7 +1329,7 @@ void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431 CA_PROTO_READ_NOTIFY, 0u, static_cast < ca_uint16_t > ( dataType ), static_cast < ca_uint32_t > ( nElem ), - chan.getSID(), io.getId(), + chan.getSID(guard), io.getId(), CA_V49 ( this->minorProtocolVersion ) ); minder.commit (); } @@ -1333,13 +1342,13 @@ void tcpiiu::createChannelRequest ( const char *pName; unsigned nameLength; ca_uint32_t identity; - if ( this->ca_v44_ok () ) { - identity = chan.getCID (); - pName = chan.pName (); - nameLength = chan.nameLen (); + if ( this->ca_v44_ok ( guard ) ) { + identity = chan.getCID ( guard ); + pName = chan.pName ( guard ); + nameLength = chan.nameLen ( guard ); } else { - identity = chan.getSID (); + identity = chan.getSID ( guard ); pName = 0; nameLength = 0u; } @@ -1395,7 +1404,7 @@ void tcpiiu::subscriptionRequest ( if ( ! chan.isConnected ( guard ) ) { return; } - unsigned mask = subscr.getMask(); + unsigned mask = subscr.getMask(guard); if ( mask > 0xffff ) { throw cacChannel::badEventSelection (); } @@ -1407,7 +1416,7 @@ void tcpiiu::subscriptionRequest ( else { maxBytes = MAX_TCP; } - unsigned dataType = subscr.getType (); + unsigned dataType = subscr.getType ( guard ); // data type bounds checked when sunscription created arrayElementCount maxElem = ( maxBytes - dbr_size[dataType] ) / dbr_value_size[dataType]; if ( nElem > maxElem ) { @@ -1419,7 +1428,7 @@ void tcpiiu::subscriptionRequest ( CA_PROTO_EVENT_ADD, 16u, static_cast < ca_uint16_t > ( dataType ), static_cast < ca_uint32_t > ( nElem ), - chan.getSID(), subscr.getId(), + chan.getSID(guard), subscr.getId(), CA_V49 ( this->minorProtocolVersion ) ); // extension @@ -1451,7 +1460,7 @@ void tcpiiu::subscriptionUpdateRequest ( epicsGuard < epicsMutex > & guard, // X else { maxBytes = MAX_TCP; } - unsigned dataType = subscr.getType (); + unsigned dataType = subscr.getType ( guard ); // data type bounds checked when subscription constructed arrayElementCount maxElem = ( maxBytes - dbr_size[dataType] ) / dbr_value_size[dataType]; if ( nElem > maxElem ) { @@ -1463,7 +1472,7 @@ void tcpiiu::subscriptionUpdateRequest ( epicsGuard < epicsMutex > & guard, // X CA_PROTO_READ_NOTIFY, 0u, static_cast < ca_uint16_t > ( dataType ), static_cast < ca_uint32_t > ( nElem ), - chan.getSID (), subscr.getId (), + chan.getSID (guard), subscr.getId (), CA_V49 ( this->minorProtocolVersion ) ); minder.commit (); } @@ -1476,9 +1485,9 @@ void tcpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard, // X comQueSendMsgMinder minder ( this->sendQue, guard ); this->sendQue.insertRequestHeader ( CA_PROTO_EVENT_CANCEL, 0u, - static_cast < ca_uint16_t > ( subscr.getType () ), + static_cast < ca_uint16_t > ( subscr.getType ( guard ) ), static_cast < ca_uint16_t > ( subscr.getCount ( guard ) ), - chan.getSID(), subscr.getId(), + chan.getSID(guard), subscr.getId(), CA_V49 ( this->minorProtocolVersion ) ); minder.commit (); } @@ -1561,37 +1570,46 @@ bool tcpiiu::flushBlockThreshold ( epicsGuard < epicsMutex > & guard ) const { guard.assertIdenticalMutex ( this->mutex ); - return this->sendQue.flushBlockThreshold ( 0u ); } -osiSockAddr tcpiiu::getNetworkAddress () const +osiSockAddr tcpiiu::getNetworkAddress ( + epicsGuard < epicsMutex > & guard ) const { + guard.assertIdenticalMutex ( this->mutex ); return this->address(); } // not inline because its virtual -bool tcpiiu::ca_v42_ok () const +bool tcpiiu::ca_v42_ok ( + epicsGuard < epicsMutex > & guard ) const { + guard.assertIdenticalMutex ( this->mutex ); return CA_V42 ( this->minorProtocolVersion ); } -void tcpiiu::requestRecvProcessPostponedFlush () +void tcpiiu::requestRecvProcessPostponedFlush ( + epicsGuard < epicsMutex > & guard ) { + guard.assertIdenticalMutex ( this->mutex ); this->recvProcessPostponedFlush = true; } -void tcpiiu::hostName ( char *pBuf, unsigned bufLength ) const +void tcpiiu::hostName ( + epicsGuard < epicsMutex > & guard, + char *pBuf, unsigned bufLength ) const { + guard.assertIdenticalMutex ( this->mutex ); this->hostNameCacheInstance.hostName ( pBuf, bufLength ); } -// deprecated - please dont use - this is _not_ thread safe -const char * tcpiiu::pHostName () const +const char * tcpiiu::pHostName ( + epicsGuard < epicsMutex > & guard ) const { + guard.assertIdenticalMutex ( this->mutex ); static char nameBuf [128]; - this->hostName ( nameBuf, sizeof ( nameBuf ) ); - return nameBuf; // ouch !! + this->hostName ( guard, nameBuf, sizeof ( nameBuf ) ); + return nameBuf; } void tcpiiu::removeAllChannels ( @@ -1608,7 +1626,8 @@ void tcpiiu::removeAllChannels ( } while ( nciu * pChan = this->createRespPend.get () ) { - this->clearChannelRequest ( guard, pChan->getSID(), pChan->getCID() ); + this->clearChannelRequest ( guard, + pChan->getSID(guard), pChan->getCID(guard) ); discIIU.installDisconnectedChannel ( *pChan ); pChan->setServerAddressUnknown ( discIIU, guard ); } @@ -1774,7 +1793,8 @@ bool tcpiiu::bytesArePendingInOS () const #endif } -double tcpiiu::receiveWatchdogDelay () const +double tcpiiu::receiveWatchdogDelay ( + epicsGuard < epicsMutex > & ) const { return this->recvDog.delay (); } diff --git a/src/ca/udpiiu.cpp b/src/ca/udpiiu.cpp index abf8a43b9..984922aaf 100644 --- a/src/ca/udpiiu.cpp +++ b/src/ca/udpiiu.cpp @@ -1005,13 +1005,14 @@ void udpiiu::repeaterConfirmNotify () this->pRepeaterSubscribeTmr->confirmNotify (); } -void udpiiu::beaconAnomalyNotify ( const epicsTime & currentTime ) +void udpiiu::beaconAnomalyNotify ( + epicsGuard < epicsMutex > & cacGuard, const epicsTime & currentTime ) { epicsGuard guard ( this->mutex ); tsDLIter < nciu > chan = this->serverAddrRes.firstIter (); while ( chan.valid () ) { - chan->beaconAnomalyNotify (); + chan->beaconAnomalyNotify ( cacGuard ); chan++; } @@ -1145,108 +1146,128 @@ void udpiiu::uninstallChan ( chan.channelNode::listMember = channelNode::cs_none; } -void udpiiu::hostName ( char *pBuf, unsigned bufLength ) const +void udpiiu::hostName ( + epicsGuard < epicsMutex > & cacGuard, + char *pBuf, unsigned bufLength ) const { - netiiu::hostName ( pBuf, bufLength ); + netiiu::hostName ( cacGuard, pBuf, bufLength ); } -const char * udpiiu::pHostName () const +const char * udpiiu::pHostName ( + epicsGuard < epicsMutex > & cacGuard ) const { - return netiiu::pHostName (); + return netiiu::pHostName ( cacGuard ); } -bool udpiiu::ca_v42_ok () const +bool udpiiu::ca_v42_ok ( + epicsGuard < epicsMutex > & cacGuard ) const { - return netiiu::ca_v42_ok (); + return netiiu::ca_v42_ok ( cacGuard ); } -bool udpiiu::ca_v41_ok () const +bool udpiiu::ca_v41_ok ( + epicsGuard < epicsMutex > & cacGuard ) const { - return netiiu::ca_v41_ok (); + return netiiu::ca_v41_ok ( cacGuard ); } -void udpiiu::writeRequest ( epicsGuard < epicsMutex > & guard, - nciu & chan, unsigned type, arrayElementCount nElem, const void * pValue ) +void udpiiu::writeRequest ( + epicsGuard < epicsMutex > & guard, + nciu & chan, unsigned type, + arrayElementCount nElem, const void * pValue ) { guard.assertIdenticalMutex ( this->cacMutex ); netiiu::writeRequest ( guard, chan, type, nElem, pValue ); } -void udpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard, nciu & chan, - netWriteNotifyIO & io, unsigned type, arrayElementCount nElem, const void *pValue ) +void udpiiu::writeNotifyRequest ( + epicsGuard < epicsMutex > & guard, nciu & chan, + netWriteNotifyIO & io, unsigned type, + arrayElementCount nElem, const void *pValue ) { guard.assertIdenticalMutex ( this->cacMutex ); netiiu::writeNotifyRequest ( guard, chan, io, type, nElem, pValue ); } -void udpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, nciu & chan, - netReadNotifyIO & io, unsigned type, arrayElementCount nElem ) +void udpiiu::readNotifyRequest ( + epicsGuard < epicsMutex > & guard, nciu & chan, + netReadNotifyIO & io, unsigned type, arrayElementCount nElem ) { guard.assertIdenticalMutex ( this->cacMutex ); netiiu::readNotifyRequest ( guard, chan, io, type, nElem ); } -void udpiiu::clearChannelRequest ( epicsGuard < epicsMutex > & guard, - ca_uint32_t sid, ca_uint32_t cid ) +void udpiiu::clearChannelRequest ( + epicsGuard < epicsMutex > & guard, + ca_uint32_t sid, ca_uint32_t cid ) { guard.assertIdenticalMutex ( this->cacMutex ); netiiu::clearChannelRequest ( guard, sid, cid ); } -void udpiiu::subscriptionRequest ( epicsGuard < epicsMutex > & guard, nciu & chan, - netSubscription & subscr ) +void udpiiu::subscriptionRequest ( + epicsGuard < epicsMutex > & guard, nciu & chan, + netSubscription & subscr ) { guard.assertIdenticalMutex ( this->cacMutex ); netiiu::subscriptionRequest ( guard, chan, subscr ); } -void udpiiu::subscriptionUpdateRequest ( epicsGuard < epicsMutex > &, nciu &, - netSubscription & ) +void udpiiu::subscriptionUpdateRequest ( + epicsGuard < epicsMutex > &, nciu &, + netSubscription & ) { } -void udpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard, - nciu & chan, netSubscription & subscr ) +void udpiiu::subscriptionCancelRequest ( + epicsGuard < epicsMutex > & guard, + nciu & chan, netSubscription & subscr ) { guard.assertIdenticalMutex ( this->cacMutex ); netiiu::subscriptionCancelRequest ( guard, chan, subscr ); } -void udpiiu::flushRequest ( epicsGuard < epicsMutex > & guard ) +void udpiiu::flushRequest ( + epicsGuard < epicsMutex > & guard ) { netiiu::flushRequest ( guard ); } -bool udpiiu::flushBlockThreshold ( epicsGuard < epicsMutex > & guard ) const +bool udpiiu::flushBlockThreshold ( + epicsGuard < epicsMutex > & guard ) const { guard.assertIdenticalMutex ( this->cacMutex ); return netiiu::flushBlockThreshold ( guard ); } -void udpiiu::flushRequestIfAboveEarlyThreshold ( epicsGuard < epicsMutex > & guard ) +void udpiiu::flushRequestIfAboveEarlyThreshold ( + epicsGuard < epicsMutex > & guard ) { guard.assertIdenticalMutex ( this->cacMutex ); netiiu::flushRequestIfAboveEarlyThreshold ( guard ); } -void udpiiu::blockUntilSendBacklogIsReasonable - ( cacContextNotify & notify, epicsGuard < epicsMutex > & guard ) +void udpiiu::blockUntilSendBacklogIsReasonable ( + cacContextNotify & notify, epicsGuard < epicsMutex > & guard ) { guard.assertIdenticalMutex ( this->cacMutex ); netiiu::blockUntilSendBacklogIsReasonable ( notify, guard ); } -void udpiiu::requestRecvProcessPostponedFlush () +void udpiiu::requestRecvProcessPostponedFlush ( + epicsGuard < epicsMutex > & guard ) { - netiiu::requestRecvProcessPostponedFlush (); + netiiu::requestRecvProcessPostponedFlush ( guard ); } -osiSockAddr udpiiu::getNetworkAddress () const +osiSockAddr udpiiu::getNetworkAddress ( + epicsGuard < epicsMutex > & guard ) const { - return netiiu::getNetworkAddress (); + return netiiu::getNetworkAddress ( guard ); } -double udpiiu::receiveWatchdogDelay () const +double udpiiu::receiveWatchdogDelay ( + epicsGuard < epicsMutex > & guard ) const { return - DBL_MAX; } diff --git a/src/ca/udpiiu.h b/src/ca/udpiiu.h index 319ff6a19..14a1e3eaf 100644 --- a/src/ca/udpiiu.h +++ b/src/ca/udpiiu.h @@ -100,7 +100,8 @@ public: void show ( unsigned level ) const; bool wakeupMsg (); void repeaterConfirmNotify (); - void beaconAnomalyNotify ( const epicsTime & currentTime ); + void beaconAnomalyNotify ( + epicsGuard < epicsMutex > & guard, const epicsTime & currentTime ); void govExpireNotify ( const epicsTime & currentTime ); unsigned unresolvedChannelCount ( epicsGuard < udpMutex > & ) const; void uninstallChan ( @@ -158,50 +159,75 @@ private: static const pProtoStubUDP udpJumpTableCAC[]; // UDP protocol stubs - bool versionAction ( epicsGuard < epicsMutex > &, const caHdr &, + bool versionAction ( + epicsGuard < epicsMutex > &, const caHdr &, const osiSockAddr &, const epicsTime & ); - bool badUDPRespAction ( epicsGuard < epicsMutex > &, const caHdr &msg, + bool badUDPRespAction ( + epicsGuard < epicsMutex > &, const caHdr &msg, const osiSockAddr &netAddr, const epicsTime & ); - bool searchRespAction ( epicsGuard < epicsMutex > &, const caHdr &msg, + bool searchRespAction ( + epicsGuard < epicsMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool exceptionRespAction ( epicsGuard < epicsMutex > &, const caHdr &msg, + bool exceptionRespAction ( + epicsGuard < epicsMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool beaconAction ( epicsGuard < epicsMutex > &, const caHdr &msg, + bool beaconAction ( + epicsGuard < epicsMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool notHereRespAction ( epicsGuard < epicsMutex > &, const caHdr &msg, + bool notHereRespAction ( + epicsGuard < epicsMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool repeaterAckAction ( epicsGuard < epicsMutex > &, const caHdr &msg, + bool repeaterAckAction ( + epicsGuard < epicsMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); friend void udpRecvThread::run (); - void hostName ( char *pBuf, unsigned bufLength ) const; - const char * pHostName () const; // deprecated - please do not use - bool ca_v42_ok () const; - bool ca_v41_ok () const; - void writeRequest ( epicsGuard < epicsMutex > &, nciu &, unsigned type, - arrayElementCount nElem, const void *pValue ); - void writeNotifyRequest ( epicsGuard < epicsMutex > &, nciu &, netWriteNotifyIO &, - unsigned type, arrayElementCount nElem, const void *pValue ); - void readNotifyRequest ( epicsGuard < epicsMutex > &, nciu &, netReadNotifyIO &, - unsigned type, arrayElementCount nElem ); - void clearChannelRequest ( epicsGuard < epicsMutex > &, - ca_uint32_t sid, ca_uint32_t cid ); - void subscriptionRequest ( epicsGuard < epicsMutex > &, nciu &, - netSubscription & ); - void subscriptionUpdateRequest ( epicsGuard < epicsMutex > &, nciu &, - netSubscription & ); + void hostName ( + epicsGuard < epicsMutex > &, + char *pBuf, unsigned bufLength ) const; + const char * pHostName ( + epicsGuard < epicsMutex > & ) const; + bool ca_v42_ok ( + epicsGuard < epicsMutex > & ) const; + bool ca_v41_ok ( + epicsGuard < epicsMutex > & ) const; + void writeRequest ( + epicsGuard < epicsMutex > &, nciu &, unsigned type, + arrayElementCount nElem, const void *pValue ); + void writeNotifyRequest ( + epicsGuard < epicsMutex > &, nciu &, netWriteNotifyIO &, + unsigned type, arrayElementCount nElem, const void *pValue ); + void readNotifyRequest ( + epicsGuard < epicsMutex > &, nciu &, netReadNotifyIO &, + unsigned type, arrayElementCount nElem ); + void clearChannelRequest ( + epicsGuard < epicsMutex > &, + ca_uint32_t sid, ca_uint32_t cid ); + void subscriptionRequest ( + epicsGuard < epicsMutex > &, nciu &, + netSubscription & ); + void subscriptionUpdateRequest ( + epicsGuard < epicsMutex > &, nciu &, + netSubscription & ); bool pushVersionMsg (); - void subscriptionCancelRequest ( epicsGuard < epicsMutex > &, - nciu & chan, netSubscription & subscr ); - void flushRequest ( epicsGuard < epicsMutex > & ); - bool flushBlockThreshold ( epicsGuard < epicsMutex > & ) const; - void flushRequestIfAboveEarlyThreshold ( epicsGuard < epicsMutex > & ); + void subscriptionCancelRequest ( + epicsGuard < epicsMutex > &, + nciu & chan, netSubscription & subscr ); + void flushRequest ( + epicsGuard < epicsMutex > & ); + bool flushBlockThreshold ( + epicsGuard < epicsMutex > & ) const; + void flushRequestIfAboveEarlyThreshold ( + epicsGuard < epicsMutex > & ); void blockUntilSendBacklogIsReasonable ( cacContextNotify &, epicsGuard < epicsMutex > & ); - void requestRecvProcessPostponedFlush (); - osiSockAddr getNetworkAddress () const; - double receiveWatchdogDelay () const; + void requestRecvProcessPostponedFlush ( + epicsGuard < epicsMutex > & ); + osiSockAddr getNetworkAddress ( + epicsGuard < epicsMutex > & ) const; + double receiveWatchdogDelay ( + epicsGuard < epicsMutex > & ) const; udpiiu ( const udpiiu & ); udpiiu & operator = ( const udpiiu & ); diff --git a/src/ca/virtualCircuit.h b/src/ca/virtualCircuit.h index d8e364624..47ab4257b 100644 --- a/src/ca/virtualCircuit.h +++ b/src/ca/virtualCircuit.h @@ -99,7 +99,8 @@ public: const osiSockAddr & addrIn, comBufMemoryManager &, unsigned minorVersion, ipAddrToAsciiEngine & engineIn, const cacChannel::priLev & priorityIn ); ~tcpiiu (); - void start (); + void start ( + epicsGuard < epicsMutex > & ); void initiateCleanShutdown ( epicsGuard < epicsMutex > & ); void initiateAbortShutdown ( @@ -114,7 +115,8 @@ public: void receiveTimeoutNotify( callbackManager &, epicsGuard < epicsMutex > & ); - void beaconAnomalyNotify ( epicsGuard < epicsMutex > & ); + void beaconAnomalyNotify ( + epicsGuard < epicsMutex > & ); void beaconArrivalNotify ( epicsGuard < epicsMutex > &, const epicsTime & currentTime ); @@ -122,29 +124,46 @@ public: epicsGuard < epicsMutex > &, const epicsTime & currentTime ); - void flushRequest ( epicsGuard < epicsMutex > & ); - bool flushBlockThreshold ( epicsGuard < epicsMutex > & ) const; - void flushRequestIfAboveEarlyThreshold ( epicsGuard < epicsMutex > & ); + void flushRequest ( + epicsGuard < epicsMutex > & ); + bool flushBlockThreshold ( + epicsGuard < epicsMutex > & ) const; + void flushRequestIfAboveEarlyThreshold ( + epicsGuard < epicsMutex > & ); void blockUntilSendBacklogIsReasonable ( cacContextNotify &, epicsGuard < epicsMutex > & ); virtual void show ( unsigned level ) const; - bool setEchoRequestPending ( epicsGuard < epicsMutex > & ); - void requestRecvProcessPostponedFlush (); - void clearChannelRequest ( epicsGuard < epicsMutex > &, + bool setEchoRequestPending ( + epicsGuard < epicsMutex > & ); + void requestRecvProcessPostponedFlush ( + epicsGuard < epicsMutex > & ); + void clearChannelRequest ( + epicsGuard < epicsMutex > &, ca_uint32_t sid, ca_uint32_t cid ); - bool ca_v41_ok () const; - bool ca_v42_ok () const; - bool ca_v44_ok () const; - bool ca_v49_ok () const; + bool ca_v41_ok ( + epicsGuard < epicsMutex > & ) const; + bool ca_v42_ok ( + epicsGuard < epicsMutex > & ) const; + bool ca_v44_ok ( + epicsGuard < epicsMutex > & ) const; + bool ca_v49_ok ( + epicsGuard < epicsMutex > & ) const; - void hostName ( char *pBuf, unsigned bufLength ) const; - bool alive () const; - bool connecting () const; - osiSockAddr getNetworkAddress () const; - int printf ( epicsGuard < epicsMutex > & cbGuard, + void hostName ( + epicsGuard < epicsMutex > &, + char *pBuf, unsigned bufLength ) const; + bool alive ( + epicsGuard < epicsMutex > & ) const; + bool connecting ( + epicsGuard < epicsMutex > & ) const; + osiSockAddr getNetworkAddress ( + epicsGuard < epicsMutex > & ) const; + int printf ( + epicsGuard < epicsMutex > & cbGuard, const char *pformat, ... ); - unsigned channelCount ( epicsGuard < epicsMutex > & ); + unsigned channelCount ( + epicsGuard < epicsMutex > & ); void removeAllChannels ( epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard, udpiiu & ); @@ -153,7 +172,8 @@ public: unsigned sidIn, ca_uint16_t typeIn, arrayElementCount countIn ); void uninstallChan ( epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard, nciu & chan ); - void connectNotify ( epicsGuard < epicsMutex > &, nciu & chan ); + void connectNotify ( + epicsGuard < epicsMutex > &, nciu & chan ); void nameResolutionMsgEndNotify (); bool bytesArePendingInOS () const; @@ -220,36 +240,54 @@ private: unsigned nBytesInBuf, const epicsTime & currentTime ); void recvBytes ( void * pBuf, unsigned nBytesInBuf, statusWireIO & ); - const char * pHostName () const; - double receiveWatchdogDelay () const; + const char * pHostName ( + epicsGuard < epicsMutex > & ) const; + double receiveWatchdogDelay ( + epicsGuard < epicsMutex > & ) const; void unresponsiveCircuitNotify ( epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); void disconnectNotify (); // send protocol stubs - void echoRequest ( epicsGuard < epicsMutex > & ); - void versionMessage ( epicsGuard < epicsMutex > &, const cacChannel::priLev & priority ); - void disableFlowControlRequest (epicsGuard < epicsMutex > & ); - void enableFlowControlRequest (epicsGuard < epicsMutex > & ); - void hostNameSetRequest ( epicsGuard < epicsMutex > & ); - void userNameSetRequest ( epicsGuard < epicsMutex > & ); - void createChannelRequest ( nciu &, epicsGuard < epicsMutex > & ); - void writeRequest ( epicsGuard < epicsMutex > &, nciu &, + void echoRequest ( + epicsGuard < epicsMutex > & ); + void versionMessage ( + epicsGuard < epicsMutex > &, const cacChannel::priLev & priority ); + void disableFlowControlRequest ( + epicsGuard < epicsMutex > & ); + void enableFlowControlRequest ( + epicsGuard < epicsMutex > & ); + void hostNameSetRequest ( + epicsGuard < epicsMutex > & ); + void userNameSetRequest ( + epicsGuard < epicsMutex > & ); + void createChannelRequest ( + nciu &, epicsGuard < epicsMutex > & ); + void writeRequest ( + epicsGuard < epicsMutex > &, nciu &, unsigned type, arrayElementCount nElem, const void *pValue ); - void writeNotifyRequest ( epicsGuard < epicsMutex > &, nciu &, + void writeNotifyRequest ( + epicsGuard < epicsMutex > &, nciu &, netWriteNotifyIO &, unsigned type, arrayElementCount nElem, const void *pValue ); - void readNotifyRequest ( epicsGuard < epicsMutex > &, nciu &, - netReadNotifyIO &, unsigned type, arrayElementCount nElem ); - void subscriptionRequest ( epicsGuard < epicsMutex > &, + void readNotifyRequest ( + epicsGuard < epicsMutex > &, nciu &, + netReadNotifyIO &, unsigned type, + arrayElementCount nElem ); + void subscriptionRequest ( + epicsGuard < epicsMutex > &, nciu &, netSubscription & subscr ); - void subscriptionUpdateRequest ( epicsGuard < epicsMutex > &, + void subscriptionUpdateRequest ( + epicsGuard < epicsMutex > &, nciu & chan, netSubscription & subscr ); - void subscriptionCancelRequest ( epicsGuard < epicsMutex > &, + void subscriptionCancelRequest ( + epicsGuard < epicsMutex > &, nciu & chan, netSubscription & subscr ); - void flushIfRecvProcessRequested (); - bool flush ( epicsGuard < epicsMutex > & ); // only to be called by the send thread + void flushIfRecvProcessRequested ( + epicsGuard < epicsMutex > & ); + bool flush ( + epicsGuard < epicsMutex > & ); // only to be called by the send thread friend void tcpRecvThread::run (); friend void tcpRecvThread::connect (); @@ -275,33 +313,39 @@ inline void tcpiiu::operator delete ( void * pCadaver, } #endif -inline bool tcpiiu::ca_v41_ok () const +inline bool tcpiiu::ca_v41_ok ( + epicsGuard < epicsMutex > & ) const { return CA_V41 ( this->minorProtocolVersion ); } -inline bool tcpiiu::ca_v44_ok () const +inline bool tcpiiu::ca_v44_ok ( + epicsGuard < epicsMutex > & ) const { return CA_V44 ( this->minorProtocolVersion ); } -inline bool tcpiiu::ca_v49_ok () const +inline bool tcpiiu::ca_v49_ok ( + epicsGuard < epicsMutex > & ) const { return CA_V49 ( this->minorProtocolVersion ); } -inline bool tcpiiu::alive () const // X aCC 361 +inline bool tcpiiu::alive ( + epicsGuard < epicsMutex > & ) const // X aCC 361 { return ( this->state == iiucs_connecting || this->state == iiucs_connected ); } -inline bool tcpiiu::connecting () const +inline bool tcpiiu::connecting ( + epicsGuard < epicsMutex > & ) const { return ( this->state == iiucs_connecting ); } -inline void tcpiiu::beaconAnomalyNotify ( epicsGuard < epicsMutex > & guard ) +inline void tcpiiu::beaconAnomalyNotify ( + epicsGuard < epicsMutex > & guard ) { //guard.assertIdenticalMutex ( this->cacRef.mutexRef () ); this->recvDog.beaconAnomalyNotify ( guard ); diff --git a/src/db/dbChannelIO.cpp b/src/db/dbChannelIO.cpp index 22f165b4c..78b3e2100 100644 --- a/src/db/dbChannelIO.cpp +++ b/src/db/dbChannelIO.cpp @@ -139,14 +139,18 @@ void dbChannelIO::ioCancel ( } void dbChannelIO::ioShow ( + epicsGuard < epicsMutex > & guard, const ioid & id, unsigned level ) const { - epicsGuard < epicsMutex > guard ( this->mutex ); + guard.assertIdenticalMutex ( this->mutex ); this->serviceIO.ioShow ( guard, id, level ); } -void dbChannelIO::show ( unsigned level ) const +void dbChannelIO::show ( + epicsGuard < epicsMutex > & guard, unsigned level ) const { + guard.assertIdenticalMutex ( this->mutex ); + printf ("channel at %p attached to local database record %s\n", static_cast ( this ), this->addr.precord->name ); @@ -161,6 +165,30 @@ void dbChannelIO::show ( unsigned level ) const } } +unsigned long dbChannelIO::nativeElementCount ( + epicsGuard < epicsMutex > & guard ) const +{ + guard.assertIdenticalMutex ( this->mutex ); + if ( this->addr.no_elements >= 0u ) { + return static_cast < unsigned long > ( this->addr.no_elements ); + } + return 0u; +} + +const char *dbChannelIO::pName ( + epicsGuard < epicsMutex > & guard ) const +{ + guard.assertIdenticalMutex ( this->mutex ); + return addr.precord->name; +} + +short dbChannelIO::nativeType ( + epicsGuard < epicsMutex > & guard ) const +{ + guard.assertIdenticalMutex ( this->mutex ); + return this->addr.dbr_field_type; +} + void * dbChannelIO::operator new ( size_t size, tsFreeList < dbChannelIO, 256, epicsMutexNOOP > & freeList ) { diff --git a/src/db/dbChannelIO.h b/src/db/dbChannelIO.h index 06a41dec9..127b1e1e9 100644 --- a/src/db/dbChannelIO.h +++ b/src/db/dbChannelIO.h @@ -43,19 +43,25 @@ class dbChannelIO : public cacChannel, public dbContextPrivateListOfIO { public: - dbChannelIO ( epicsMutex &, cacChannelNotify &, + dbChannelIO ( + epicsMutex &, cacChannelNotify &, const dbAddr &, dbContext & ); - void destructor ( epicsGuard < epicsMutex > & ); + void destructor ( + epicsGuard < epicsMutex > & ); void destroy ( epicsGuard < epicsMutex > & callbackControlGuard, epicsGuard < epicsMutex > & mutualExclusionGuard ); - void callReadNotify ( epicsGuard < epicsMutex > &, - unsigned type, unsigned long count, - cacReadNotify & notify ); - void callStateNotify ( unsigned type, unsigned long count, - const struct db_field_log * pfl, cacStateNotify & notify ); - void show ( unsigned level ) const; - const char * pName () const; + void callReadNotify ( + epicsGuard < epicsMutex > &, + unsigned type, unsigned long count, + cacReadNotify & notify ); + void callStateNotify ( + unsigned type, unsigned long count, + const struct db_field_log * pfl, cacStateNotify & notify ); + void show ( + epicsGuard < epicsMutex > &, unsigned level ) const; + const char * pName ( + epicsGuard < epicsMutex > & ) const; void * operator new ( size_t size, tsFreeList < dbChannelIO, 256, epicsMutexNOOP > & ); epicsPlacementDeleteOperator (( void *, @@ -68,16 +74,20 @@ private: dbAddr addr; void initiateConnect ( epicsGuard < epicsMutex > & ); - ioStatus read ( epicsGuard < epicsMutex > &, + ioStatus read ( + epicsGuard < epicsMutex > &, unsigned type, unsigned long count, cacReadNotify &, ioid * ); - void write ( epicsGuard < epicsMutex > &, + void write ( + epicsGuard < epicsMutex > &, unsigned type, unsigned long count, - const void *pvalue ); - ioStatus write ( epicsGuard < epicsMutex > &, + const void * pvalue ); + ioStatus write ( + epicsGuard < epicsMutex > &, unsigned type, unsigned long count, - const void *pvalue, cacWriteNotify &, ioid * ); - void subscribe ( epicsGuard < epicsMutex > &, + const void * pvalue, cacWriteNotify &, ioid * ); + void subscribe ( + epicsGuard < epicsMutex > &, unsigned type, unsigned long count, unsigned mask, cacStateNotify ¬ify, ioid * ); void ioCancel ( @@ -85,34 +95,18 @@ private: epicsGuard < epicsMutex > & mutualExclusionGuard, const ioid & ); void ioShow ( + epicsGuard < epicsMutex > &, const ioid &, unsigned level ) const; - short nativeType () const; - unsigned long nativeElementCount () const; + short nativeType ( + epicsGuard < epicsMutex > & ) const; + unsigned long nativeElementCount ( + epicsGuard < epicsMutex > & ) const; dbChannelIO ( const dbChannelIO & ); dbChannelIO & operator = ( const dbChannelIO & ); void * operator new ( size_t size ); void operator delete ( void * ); }; - -inline unsigned long dbChannelIO::nativeElementCount () const -{ - if ( this->addr.no_elements >= 0u ) { - return static_cast < unsigned long > ( this->addr.no_elements ); - } - return 0u; -} - -inline const char *dbChannelIO::pName () const -{ - return addr.precord->name; -} - -inline short dbChannelIO::nativeType () const -{ - return this->addr.dbr_field_type; -} - inline void dbChannelIO::callReadNotify ( epicsGuard < epicsMutex > & guard, unsigned type, unsigned long count, cacReadNotify & notify ) diff --git a/src/db/dbSubscriptionIO.cpp b/src/db/dbSubscriptionIO.cpp index 038bda1ea..6c0203cf3 100644 --- a/src/db/dbSubscriptionIO.cpp +++ b/src/db/dbSubscriptionIO.cpp @@ -91,7 +91,7 @@ void dbSubscriptionIO::channelDeleteException ( { guard.assertIdenticalMutex ( this->mutex ); this->notify.exception ( guard, ECA_CHANDESTROY, - this->chan.pName(), this->type, this->count ); + this->chan.pName(guard), this->type, this->count ); } void * dbSubscriptionIO::operator new ( size_t ) // X aCC 361 diff --git a/src/libCom/osi/epicsMutex.cpp b/src/libCom/osi/epicsMutex.cpp index e7d263bf7..83d07d8a7 100644 --- a/src/libCom/osi/epicsMutex.cpp +++ b/src/libCom/osi/epicsMutex.cpp @@ -240,7 +240,8 @@ static epicsThreadPrivate < epicsDeadlockDetectMutex > static epicsThreadOnceId epicsDeadlockDetectMutexInit = EPICS_THREAD_ONCE_INIT; -static void epicsDeadlockDetectMutexInitFunc ( void * ) +extern "C" +void epicsDeadlockDetectMutexInitFunc ( void * ) { pCurrentMutexLevel = new epicsThreadPrivate < epicsDeadlockDetectMutex > (); } diff --git a/src/libCom/osi/epicsThread.cpp b/src/libCom/osi/epicsThread.cpp index 9bf401ca8..2d26edde7 100644 --- a/src/libCom/osi/epicsThread.cpp +++ b/src/libCom/osi/epicsThread.cpp @@ -93,15 +93,15 @@ void epicsThread::exitWait () bool epicsThread::exitWait ( double delay ) { { - epicsTime begin = epicsTime::getCurrent (); + epicsTime exitWaitBegin = epicsTime::getCurrent (); epicsGuard < epicsMutex > guard ( this->mutex ); double elapsed = 0.0; while ( ! this->terminated ) { epicsGuardRelease < epicsMutex > unguard ( guard ); this->event.wait ( delay - elapsed ); epicsTime current = epicsTime::getCurrent (); - double elapsed = current - begin; - if ( elapsed >= delay ) { + double exitWaitElapsed = current - exitWaitBegin; + if ( exitWaitElapsed >= delay ) { break; } }