diff --git a/src/ca/CASG.cpp b/src/ca/CASG.cpp index 1b0a65879..572af868f 100644 --- a/src/ca/CASG.cpp +++ b/src/ca/CASG.cpp @@ -29,28 +29,14 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "syncGroup.h" #include "oldAccess.h" #include "autoPtrDestroy.h" #include "cac.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsSLNode < CASG>; -template class tsFreeList < CASG, 128, 0 >; -template class tsFreeList < syncGroupWriteNotify, 128, 0 >; -template class tsFreeList < syncGroupReadNotify, 128, 0 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < struct CASG, 128 > CASG::freeList; -epicsMutex CASG::freeListMutex; +epicsSingleton < tsFreeList < struct CASG, 128 > > CASG::pFreeList; CASG::CASG ( oldCAC &cacIn ) : client ( cacIn ), magic ( CASG_MAGIC ) @@ -144,7 +130,7 @@ int CASG::block ( double timeout ) void CASG::reset () { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); this->destroyCompletedIO (); this->destroyPendingIO (); } @@ -186,7 +172,7 @@ void CASG::show ( unsigned level ) const ::printf ( "Sync Group: id=%u, magic=%u, opPend=%u\n", this->getId (), this->magic, this->ioPendingList.count () ); if ( level ) { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); ::printf ( "\tPending" ); tsDLIterConstBD < syncGroupNotify > notifyPending = this->ioPendingList.firstIter (); while ( notifyPending.valid () ) { @@ -206,7 +192,7 @@ bool CASG::ioComplete () { bool isCompleted; { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); this->destroyCompletedIO (); isCompleted = ( this->ioPendingList.count () == 0u ); } @@ -218,7 +204,7 @@ int CASG::put ( chid pChan, unsigned type, arrayElementCount count, const void * syncGroupWriteNotify * pNotify = 0; try { { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); pNotify = syncGroupWriteNotify::factory ( this->freeListWriteOP, *this, pChan ); if ( pNotify ) { @@ -283,7 +269,7 @@ int CASG::get ( chid pChan, unsigned type, arrayElementCount count, void *pValue syncGroupReadNotify * pNotify = 0; try { { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); pNotify = syncGroupReadNotify::factory ( this->freeListReadOP, *this, pChan, pValue ); if ( pNotify ) { @@ -340,7 +326,7 @@ int CASG::get ( chid pChan, unsigned type, arrayElementCount count, void *pValue void CASG::destroyPendingIO ( syncGroupNotify * pNotify ) { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); if ( pNotify ) { this->ioPendingList.remove ( *pNotify ); pNotify->destroy ( *this ); @@ -351,7 +337,7 @@ void CASG::completionNotify ( syncGroupNotify & notify ) { unsigned requestsIncomplete; { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); this->ioPendingList.remove ( notify ); this->ioCompletedList.add ( notify ); requestsIncomplete = this->ioPendingList.count (); @@ -373,14 +359,12 @@ void CASG::recycleSyncGroupReadNotify ( syncGroupReadNotify &io ) void * CASG::operator new (size_t size) { - epicsAutoMutex locker ( CASG::freeListMutex ); - return CASG::freeList.allocate ( size ); + return CASG::pFreeList->allocate ( size ); } void CASG::operator delete (void *pCadaver, size_t size) { - epicsAutoMutex locker ( CASG::freeListMutex ); - CASG::freeList.release ( pCadaver, size ); + CASG::pFreeList->release ( pCadaver, size ); } int CASG::printf ( const char *pformat, ... ) diff --git a/src/ca/access.cpp b/src/ca/access.cpp index ebd753d61..322ac967e 100644 --- a/src/ca/access.cpp +++ b/src/ca/access.cpp @@ -28,6 +28,7 @@ */ #define CAC_VERSION_GLOBAL +#define epicsExportSharedSymbols #include "iocinf.h" #include "oldAccess.h" #include "autoPtrDestroy.h" diff --git a/src/ca/bhe.cpp b/src/ca/bhe.cpp index cc3700c02..f53aa72f9 100644 --- a/src/ca/bhe.cpp +++ b/src/ca/bhe.cpp @@ -12,38 +12,21 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "virtualCircuit.h" - -#define epicsExportSharedSymbols #include "bhe.h" -#undef epicsExportSharedSymbols -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsDLNode < tcpiiu >; -template class tsFreeList < class bhe, 1024 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < class bhe, 1024 > bhe::freeList; -epicsMutex bhe::freeListMutex; +epicsSingleton < tsFreeList < class bhe, 1024 > > bhe::pFreeList; void * bhe::operator new ( size_t size ) { - epicsAutoMutex locker ( bhe::freeListMutex ); - return bhe::freeList.allocate ( size ); + return bhe::pFreeList->allocate ( size ); } void bhe::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( bhe::freeListMutex ); - bhe::freeList.release ( pCadaver, size ); + bhe::pFreeList->release ( pCadaver, size ); } bhe::~bhe () diff --git a/src/ca/bhe.h b/src/ca/bhe.h index 7ab3743ef..d8d81c8f6 100644 --- a/src/ca/bhe.h +++ b/src/ca/bhe.h @@ -14,7 +14,6 @@ #ifndef bheh #define bheh -#include "shareLib.h" #include #include @@ -24,16 +23,20 @@ # undef epicsExportSharedSymbols #endif +#include "shareLib.h" + #include "tsSLList.h" #include "tsDLList.h" #include "tsFreeList.h" +#include "epicsSingleton.h" #include "epicsTime.h" -#include "epicsMutex.h" #ifdef bhehEpicsExportSharedSymbols # define epicsExportSharedSymbols #endif +#include "shareLib.h" + #include "inetAddrID.h" class tcpiiu; @@ -59,8 +62,7 @@ private: double averagePeriod; unsigned lastBeaconNumber; void beaconAnomalyNotify (); - static tsFreeList < class bhe, 1024 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < class bhe, 1024 > > pFreeList; bhe ( const bhe & ); bhe & operator = ( const bhe & ); }; diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index 5865f60ac..b89c3f567 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -15,10 +15,13 @@ #include #include "epicsMemory.h" +#include "epicsMutex.h" +#include "epicsGuard.h" #include "osiProcess.h" #include "osiSigPipeIgnore.h" #include "envDefs.h" +#define epicsExportSharedSymbols #include "iocinf.h" #include "cac.h" #include "inetAddrID.h" @@ -29,37 +32,10 @@ #include "autoPtrRecycle.h" #include "searchTimer.h" #include "repeaterSubscribeTimer.h" - -#define epicsExportSharedSymbols +#include "msgForMultiplyDefinedPV.h" #include "udpiiu.h" #include "bhe.h" #include "net_convert.h" -#undef epicsExportSharedSymbols - -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsSLNode < nciu >; -template class resTable < nciu, chronIntId >; -template class chronIntIdResTable < nciu >; -template class tsSLNode < tcpiiu >; -template class resTable < tcpiiu, caServerID >; -template class tsSLNode < bhe >; -template class resTable < bhe, inetAddrID >; -template class tsSLNode < baseNMIU >; -template class resTable < baseNMIU, chronIntId >; -template class chronIntIdResTable < baseNMIU >; -template class resTable < CASG, chronIntId >; -template class chronIntIdResTable < CASG >; -template class tsFreeList < netReadNotifyIO, 1024, 0 >; -template class tsFreeList < netWriteNotifyIO, 1024, 0 >; -template class tsFreeList < netSubscription, 1024, 0 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif // TCP response dispatch table const cac::pProtoStubTCP cac::tcpJumpTableCAC [] = @@ -155,6 +131,7 @@ cac::cac ( cacNotify & notifyIn, bool enablePreemptiveCallbackIn ) : ipToAEngine ( "dnsQuery" ), programBeginTime ( epicsTime::getCurrent() ), connTMO ( CA_CONN_VERIFY_PERIOD ), + cbMutex ( ! enablePreemptiveCallbackIn ), timerQueue ( epicsTimerQueueActive::allocate ( false, lowestPriorityLevelAbove(epicsThreadGetPrioritySelf()) ) ), pUserName ( 0 ), @@ -163,14 +140,13 @@ cac::cac ( cacNotify & notifyIn, bool enablePreemptiveCallbackIn ) : pRepeaterSubscribeTmr ( 0 ), tcpSmallRecvBufFreeList ( 0 ), tcpLargeRecvBufFreeList ( 0 ), - pCallbackLocker ( 0 ), + pCallbackGuard ( 0 ), notify ( notifyIn ), initializingThreadsId ( epicsThreadGetIdSelf() ), initializingThreadsPriority ( epicsThreadGetPrioritySelf() ), maxRecvBytesTCP ( MAX_TCP ), pndRecvCnt ( 0u ), - readSeq ( 0u ), - recvThreadsPendingCount ( 0u ) + readSeq ( 0u ) { if ( ! osiSockAttach () ) { throwWithLocation ( caErrorCode (ECA_INTERNAL) ); @@ -240,7 +216,7 @@ cac::cac ( cacNotify & notifyIn, bool enablePreemptiveCallbackIn ) : } if ( ! enablePreemptiveCallbackIn ) { - this->pCallbackLocker = new callbackAutoMutex ( *this ); + this->pCallbackGuard = new epicsGuard < callbackMutex > ( this->cbMutex ); } } catch ( ... ) { @@ -264,7 +240,7 @@ cac::~cac () // (disconnect callbacks will occur if they still have connected // channels at this point) // - delete this->pCallbackLocker; + delete this->pCallbackGuard; // @@ -282,8 +258,8 @@ cac::~cac () // (take both locks here in the proper order to avoid deadlocks) // { - epicsAutoMutex autoMutexCB ( this->callbackMutex ); - epicsAutoMutex autoMutexCAC ( this->mutex ); + epicsGuard < callbackMutex > autoMutexCB ( this->cbMutex ); + epicsGuard < epicsMutex > autoMutexCAC ( this->mutex ); this->serverTable.traverse ( & tcpiiu::cleanShutdown ); } @@ -305,8 +281,8 @@ cac::~cac () if ( this->pudpiiu ) { while ( nciu *pChan = this->pudpiiu->firstChannel() ) { { - callbackAutoMutex autoMutexCB ( *this ); - this->pudpiiu->detachChannel ( autoMutexCB, *pChan ); + epicsGuard < callbackMutex > cbGuard ( this->cbMutex ); + this->pudpiiu->detachChannel ( cbGuard, *pChan ); } pChan->disconnect ( limboIIU ); limboIIU.attachChannel ( *pChan ); @@ -327,7 +303,7 @@ cac::~cac () // its his responsibility to clean them up. } -void cac::removeAllChan ( callbackAutoMutex & cbLocker, epicsAutoMutex & locker, +void cac::removeAllChan ( epicsGuard < callbackMutex > & cbLocker, epicsGuard < epicsMutex > & locker, netiiu & srcIIU, netiiu & dstIIU ) { // we are protected here because channel delete takes the callback mutex @@ -371,7 +347,7 @@ unsigned cac::highestPriorityLevelBelow ( unsigned priority ) // void cac::flushRequest () { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->flushRequestPrivate (); } @@ -383,13 +359,13 @@ void cac::flushRequestPrivate () unsigned cac::connectionCount () const { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); return this->serverTable.numEntriesInstalled (); } void cac::show ( unsigned level ) const { - epicsAutoMutex autoMutex2 ( this->mutex ); + epicsGuard < epicsMutex > autoMutex2 ( this->mutex ); ::printf ( "Channel Access Client Context at %p for user %s\n", static_cast ( this ), this->pUserName ); @@ -397,7 +373,7 @@ void cac::show ( unsigned level ) const this->serverTable.show ( level - 1u ); ::printf ( "\tconnection time out watchdog period %f\n", this->connTMO ); ::printf ( "\tpreemptive calback is %s\n", - this->pCallbackLocker ? "disabled" : "enabled" ); + this->pCallbackGuard ? "disabled" : "enabled" ); ::printf ( "list of installed services:\n" ); this->services.show ( level - 1u ); } @@ -453,7 +429,7 @@ void cac::show ( unsigned level ) const void cac::beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime, unsigned beaconNumber, unsigned protocolRevision ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); if ( ! this->pudpiiu ) { return; @@ -541,7 +517,7 @@ int cac::pendIO ( const double & timeout ) double remaining = timeout; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->flushRequestPrivate (); } @@ -551,8 +527,8 @@ int cac::pendIO ( const double & timeout ) break; } - if ( this->pCallbackLocker ) { - callbackAutoMutexRelease autoRelease ( *this->pCallbackLocker ); + if ( this->pCallbackGuard ) { + epicsGuardRelease < callbackMutex > cbRelease ( *this->pCallbackGuard ); this->ioDone.wait ( remaining ); } else { @@ -569,7 +545,7 @@ int cac::pendIO ( const double & timeout ) } { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->readSeq++; this->pndRecvCnt = 0u; if ( this->pudpiiu ) { @@ -582,8 +558,8 @@ int cac::pendIO ( const double & timeout ) int cac::blockForEventAndEnableCallbacks ( epicsEvent &event, double timeout ) { - if ( this->pCallbackLocker ) { - callbackAutoMutexRelease autoMutexRelease ( *this->pCallbackLocker ); + if ( this->pCallbackGuard ) { + epicsGuardRelease < callbackMutex > unguard ( *this->pCallbackGuard ); event.wait ( timeout ); } else { @@ -611,16 +587,14 @@ int cac::pendEvent ( const double & timeout ) epicsTime current = epicsTime::getCurrent (); { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->flushRequestPrivate (); } // process at least once if preemptive callback is disabled - if ( this->pCallbackLocker ) { - callbackAutoMutexRelease autoMutexRelease ( *this->pCallbackLocker ); - while ( this->recvThreadsPendingCount > 0 ) { - this->noRecvThreadsPending.wait (); - } + if ( this->pCallbackGuard ) { + epicsGuardRelease < callbackMutex > unguard ( *this->pCallbackGuard ); + this->cbMutex.waitUntilNoRecvThreadsPending (); } double elapsed = epicsTime::getCurrent() - current; @@ -634,8 +608,8 @@ int cac::pendEvent ( const double & timeout ) } if ( delay >= CAC_SIGNIFICANT_DELAY ) { - if ( this->pCallbackLocker ) { - callbackAutoMutexRelease autoMutexRelease ( *this->pCallbackLocker ); + if ( this->pCallbackGuard ) { + epicsGuardRelease < callbackMutex > unguard ( *this->pCallbackGuard ); epicsThreadSleep ( delay ); } else { @@ -648,19 +622,19 @@ int cac::pendEvent ( const double & timeout ) void cac::installCASG ( CASG &sg ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->sgTable.add ( sg ); } void cac::uninstallCASG ( CASG &sg ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->sgTable.remove ( sg ); } CASG * cac::lookupCASG ( unsigned id ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); CASG * psg = this->sgTable.lookup ( id ); if ( psg ) { if ( ! psg->verify () ) { @@ -712,7 +686,7 @@ cacChannel & cac::createChannel ( const char * pName, void cac::installNetworkChannel ( nciu & chan, netiiu * & piiu ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->chanTable.add ( chan ); this->pudpiiu->attachChannel ( chan ); piiu = this->pudpiiu; @@ -721,27 +695,40 @@ void cac::installNetworkChannel ( nciu & chan, netiiu * & piiu ) bool cac::setupUDP () { - epicsAutoMutex autoMutex ( this->mutex ); - if ( ! this->pudpiiu ) { - callbackAutoMutex cbMutex ( *this ); - this->pudpiiu = new udpiiu ( cbMutex, *this ); - if ( ! this->pudpiiu ) { - return false; + udpiiu *piiu = 0; + epicsGuard < callbackMutex > cbGuard ( this->cbMutex ); + { + epicsGuard < epicsMutex > guard ( this->mutex ); + if ( ! this->pudpiiu ) { + piiu = this->pudpiiu = new udpiiu ( this->cbMutex, *this ); + if ( ! this->pudpiiu ) { + return false; + } + } + } + if ( piiu ) { + piiu->start ( cbGuard ); } } if ( ! this->pSearchTmr ) { - this->pSearchTmr = new searchTimer ( *this->pudpiiu, this->timerQueue, this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); if ( ! this->pSearchTmr ) { - return false; + this->pSearchTmr = new searchTimer ( *this->pudpiiu, this->timerQueue, this->mutex ); + if ( ! this->pSearchTmr ) { + return false; + } } } if ( ! this->pRepeaterSubscribeTmr ) { - this->pRepeaterSubscribeTmr = new repeaterSubscribeTimer ( *this->pudpiiu, this->timerQueue ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); if ( ! this->pRepeaterSubscribeTmr ) { - return false; + this->pRepeaterSubscribeTmr = new repeaterSubscribeTimer ( *this->pudpiiu, this->timerQueue ); + if ( ! this->pRepeaterSubscribeTmr ) { + return false; + } } } @@ -756,7 +743,7 @@ void cac::repeaterSubscribeConfirmNotify () } bool cac::lookupChannelAndTransferToTCP ( - callbackAutoMutex & cbMutex, unsigned cid, unsigned sid, + epicsGuard < callbackMutex > & cbGuard, unsigned cid, unsigned sid, ca_uint16_t typeCode, arrayElementCount count, unsigned minorVersionNumber, const osiSockAddr & addr, const epicsTime & currentTime ) @@ -771,7 +758,7 @@ bool cac::lookupChannelAndTransferToTCP ( bool v41Ok, v42Ok; nciu *chan; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); /* * ignore search replies for deleted channels @@ -786,7 +773,17 @@ bool cac::lookupChannelAndTransferToTCP ( /* * Ignore duplicate search replies */ - if ( chan->getPIIU()->isVirtualCircuit( chan->pName(), addr ) ) { + osiSockAddr chanAddr = chan->getPIIU()->getNetworkAddress (); + if ( chanAddr.sa.sa_family != AF_UNSPEC ) { + if ( ! sockAddrAreIdentical ( &addr, &chanAddr ) ) { + char acc[64]; + chan->getPIIU()->hostName ( acc, sizeof ( acc ) ); + msgForMultiplyDefinedPV *pMsg = new msgForMultiplyDefinedPV ( + this->cbMutex, *this, chan->pName (), acc, addr ); + if ( pMsg ) { + this->ipAddrToAsciiAsynchronousRequestInstall ( *pMsg ); + } + } return true; } @@ -803,7 +800,7 @@ bool cac::lookupChannelAndTransferToTCP ( else { try { pnewiiu = piiu = new tcpiiu ( - *this, this->connTMO, this->timerQueue, + *this, this->cbMutex, this->connTMO, this->timerQueue, addr, minorVersionNumber, this->ipToAEngine, chan->getPriority() ); if ( ! piiu ) { @@ -831,7 +828,7 @@ bool cac::lookupChannelAndTransferToTCP ( } } - this->pudpiiu->detachChannel ( cbMutex, *chan ); + this->pudpiiu->detachChannel ( cbGuard, *chan ); chan->searchReplySetUp ( *piiu, sid, typeCode, count ); piiu->attachChannel ( *chan ); @@ -872,10 +869,7 @@ bool cac::lookupChannelAndTransferToTCP ( } if ( pnewiiu ) { - bool success = pnewiiu->start ( cbMutex ); - if ( ! success ) { - this->privateUninstallIIU ( cbMutex, *pnewiiu ); - } + pnewiiu->start ( cbGuard ); } if ( this->pSearchTmr ) { @@ -896,14 +890,14 @@ void cac::uninstallChannel ( nciu & chan ) // side effect IO requests w/o holding the callback lock so that // we do not dead lock { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > guard ( this->mutex ); // if the send backlog is too high send some frames before we get entagled // in the channel shutdown sequence below. There is special protection in // this routine that releases the callback lock if we are already holding it // when this is the tcp receive thread or if this is the main thread and // preemptive callback is disabled. - this->flushIfRequired ( *chan.getPIIU() ); + this->flushIfRequired ( guard, *chan.getPIIU() ); // unregister the channel if ( this->chanTable.remove ( chan ) != &chan ) { @@ -950,9 +944,9 @@ void cac::uninstallChannel ( nciu & chan ) // // If this is a callback thread then it already owns the // CB lock at this point. If this is the main thread then - // it is possible that this->pCallbackLocker already owns + // it is possible that this->pCallbackGuard already owns // the callback lock. Otherwise if this is a preemptive - // callback enabled app then this->pCallbackLocker + // callback enabled app then this->pCallbackGuard // isnt set and we must take the call back lock. // // We take the callback lock again here and rely on recursive @@ -960,11 +954,11 @@ void cac::uninstallChannel ( nciu & chan ) // differently in the future. // // bool alreadyLocked = epicsThreadPrivateGet ( caClientCallbackThreadId ) - // || this->pCallbackLocker; + // || this->pCallbackGuard; { // taking this mutex prior to deleting the IO and channel guarantees // that we will not delete a channel out from under a callback - callbackAutoMutex cbLocker ( *this ); + epicsGuard < callbackMutex > cbGuard ( this->cbMutex ); // destroy subsiderary IO now that it is safe to do so while ( baseNMIU *pIO = tmpList.get() ) { @@ -981,9 +975,9 @@ void cac::uninstallChannel ( nciu & chan ) // o clear channel request // o outstanding callbacks using this channel have completed // o chan destroy exception has been delivered - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); // this destroys the tcpiiu if its the last channel - chan.getPIIU()->detachChannel ( cbLocker, chan ); + chan.getPIIU()->detachChannel ( cbGuard, chan ); } } @@ -1002,7 +996,7 @@ int cac::printf ( const char *pformat, ... ) const } // lock must be applied before calling this cac private routine -void cac::flushIfRequired ( netiiu & iiu ) +void cac::flushIfRequired ( epicsGuard < epicsMutex > & guard, netiiu & iiu ) { if ( iiu.flushBlockThreshold() ) { iiu.flushRequest (); @@ -1016,12 +1010,12 @@ void cac::flushIfRequired ( netiiu & iiu ) // enable / disable of call back preemption must occur here // because the tcpiiu might disconnect while waiting and its // pointer to this cac might become invalid - if ( this->pCallbackLocker ) { + if ( this->pCallbackGuard ) { iiu.blockUntilSendBacklogIsReasonable - ( &this->callbackMutex, this->mutex ); + ( this->pCallbackGuard, guard ); } else { - iiu.blockUntilSendBacklogIsReasonable ( 0, this->mutex ); + iiu.blockUntilSendBacklogIsReasonable ( 0, guard ); } } } @@ -1032,8 +1026,8 @@ void cac::flushIfRequired ( netiiu & iiu ) void cac::writeRequest ( nciu &chan, unsigned type, unsigned nElem, const void *pValue ) { - epicsAutoMutex autoMutex ( this->mutex ); - this->flushIfRequired ( *chan.getPIIU() ); + epicsGuard < epicsMutex > guard ( this->mutex ); + this->flushIfRequired ( guard, *chan.getPIIU() ); chan.getPIIU()->writeRequest ( chan, type, nElem, pValue ); } @@ -1041,13 +1035,13 @@ cacChannel::ioid cac::writeNotifyRequest ( nciu &chan, unsigned type, // X aCC 361 unsigned nElem, const void *pValue, cacWriteNotify ¬ifyIn ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > guard ( this->mutex ); autoPtrRecycle < netWriteNotifyIO > pIO ( this->ioTable, chan.cacPrivateListOfIO::eventq, *this, netWriteNotifyIO::factory ( this->freeListWriteNotifyIO, chan, notifyIn ) ); if ( pIO.get() ) { this->ioTable.add ( *pIO ); chan.cacPrivateListOfIO::eventq.add ( *pIO ); - this->flushIfRequired ( *chan.getPIIU() ); + this->flushIfRequired ( guard, *chan.getPIIU() ); chan.getPIIU()->writeNotifyRequest ( chan, *pIO, type, nElem, pValue ); return pIO.release()->getId (); @@ -1061,14 +1055,14 @@ cacChannel::ioid cac::readNotifyRequest ( nciu &chan, unsigned type, // X aCC 361 unsigned nElem, cacReadNotify ¬ifyIn ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > guard ( this->mutex ); autoPtrRecycle < netReadNotifyIO > pIO ( this->ioTable, chan.cacPrivateListOfIO::eventq, *this, netReadNotifyIO::factory ( this->freeListReadNotifyIO, chan, notifyIn ) ); if ( pIO.get() ) { this->ioTable.add ( *pIO ); chan.cacPrivateListOfIO::eventq.add ( *pIO ); - this->flushIfRequired ( *chan.getPIIU() ); + this->flushIfRequired ( guard, *chan.getPIIU() ); chan.getPIIU()->readNotifyRequest ( chan, *pIO, type, nElem ); return pIO.release()->getId (); } @@ -1085,14 +1079,14 @@ void cac::ioCancel ( nciu &chan, const cacChannel::ioid &id ) // but do _not_ hold the callback lock here because this could result // in deadlock { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > guard ( this->mutex ); pmiu = this->ioTable.remove ( id ); if ( ! pmiu ) { return; } class netSubscription *pSubscr = pmiu->isSubscription (); if ( pSubscr ) { - this->flushIfRequired ( *chan.getPIIU() ); + this->flushIfRequired ( guard, *chan.getPIIU() ); if ( chan.connected() ) { chan.getPIIU()->subscriptionCancelRequest ( chan, *pSubscr ); } @@ -1108,24 +1102,24 @@ void cac::ioCancel ( nciu &chan, const cacChannel::ioid &id ) // If this is a callback thread then it already owns the // CB lock at this point. If this is the main thread then we // are not in pendEvent, pendIO, SG block, etc and - // this->pCallbackLocker protects. Otherwise if this id - // the users auxillary thread then this->pCallbackLocker + // this->pCallbackGuard protects. Otherwise if this id + // the users auxillary thread then this->pCallbackGuard // isnt set and we must take the call back lock. bool alreadyLocked = ( epicsThreadPrivateGet ( caClientCallbackThreadId ) - || this->pCallbackLocker ); + || this->pCallbackGuard ); if ( ! alreadyLocked ) { - epicsAutoMutex autoMutex ( this->callbackMutex ); + epicsGuard < callbackMutex > autoMutex ( this->cbMutex ); } // now it is safe to destroy the IO object { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pmiu->destroy ( *this ); } } void cac::ioShow ( const cacChannel::ioid &id, unsigned level ) const { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); baseNMIU * pmiu = this->ioTable.lookup ( id ); if ( pmiu ) { pmiu->show ( level ); @@ -1138,7 +1132,7 @@ void cac::ioCompletionNotify ( unsigned id, unsigned type, baseNMIU * pmiu; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pmiu = this->ioTable.lookup ( id ); if ( ! pmiu ) { return; @@ -1158,7 +1152,7 @@ void cac::ioExceptionNotify ( unsigned id, int status, const char *pContext ) { baseNMIU * pmiu; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pmiu = this->ioTable.lookup ( id ); } @@ -1182,7 +1176,7 @@ void cac::ioExceptionNotify ( unsigned id, int status, baseNMIU * pmiu; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pmiu = this->ioTable.lookup ( id ); if ( ! pmiu ) { return; @@ -1200,7 +1194,7 @@ void cac::ioExceptionNotify ( unsigned id, int status, void cac::ioCompletionNotifyAndDestroy ( unsigned id ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); baseNMIU * pmiu = this->ioTable.remove ( id ); if ( ! pmiu ) { return; @@ -1215,7 +1209,7 @@ void cac::ioCompletionNotifyAndDestroy ( unsigned id ) // it is in use here. // { - epicsAutoMutexRelease autoMutexRelease ( autoMutex ); + epicsGuardRelease < epicsMutex > autoMutexRelease ( autoMutex ); pmiu->completion (); } @@ -1225,7 +1219,7 @@ void cac::ioCompletionNotifyAndDestroy ( unsigned id ) void cac::ioCompletionNotifyAndDestroy ( unsigned id, unsigned type, arrayElementCount count, const void *pData ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); baseNMIU * pmiu = this->ioTable.remove ( id ); if ( ! pmiu ) { return; @@ -1239,7 +1233,7 @@ void cac::ioCompletionNotifyAndDestroy ( unsigned id, // it is in use here. // { - epicsAutoMutexRelease autoMutexRelease ( autoMutex ); + epicsGuardRelease < epicsMutex > autoMutexRelease ( autoMutex ); pmiu->completion ( type, count, pData ); } @@ -1249,7 +1243,7 @@ void cac::ioCompletionNotifyAndDestroy ( unsigned id, void cac::ioExceptionNotifyAndDestroy ( unsigned id, int status, const char *pContext ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); baseNMIU * pmiu = this->ioTable.remove ( id ); if ( ! pmiu ) { return; @@ -1263,7 +1257,7 @@ void cac::ioExceptionNotifyAndDestroy ( unsigned id, int status, // it is in use here. // { - epicsAutoMutexRelease autoMutexRelease ( autoMutex ); + epicsGuardRelease < epicsMutex > autoMutexRelease ( autoMutex ); pmiu->exception ( status, pContext ); } @@ -1273,7 +1267,7 @@ void cac::ioExceptionNotifyAndDestroy ( unsigned id, int status, void cac::ioExceptionNotifyAndDestroy ( unsigned id, int status, const char *pContext, unsigned type, arrayElementCount count ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); baseNMIU * pmiu = this->ioTable.remove ( id ); if ( ! pmiu ) { return; @@ -1288,7 +1282,7 @@ void cac::ioExceptionNotifyAndDestroy ( unsigned id, int status, // { - epicsAutoMutexRelease autoMutexRelease ( autoMutex ); + epicsGuardRelease < epicsMutex > autoMutexRelease ( autoMutex ); pmiu->exception ( status, pContext, type, count ); } @@ -1320,7 +1314,7 @@ void cac::connectAllIO ( nciu & chan ) // cancel IO operations and monitor subscriptions // -- callback lock and cac lock must be applied here -void cac::disconnectAllIO ( epicsAutoMutex &locker, nciu & chan, bool enableCallbacks ) +void cac::disconnectAllIO ( epicsGuard < epicsMutex > &locker, nciu & chan, bool enableCallbacks ) { tsDLIterBD pNetIO = chan.cacPrivateListOfIO::eventq.firstIter(); while ( pNetIO.valid() ) { @@ -1334,7 +1328,7 @@ void cac::disconnectAllIO ( epicsAutoMutex &locker, nciu & chan, bool enableCall if ( enableCallbacks ) { char buf[128]; sprintf ( buf, "host = %100s", chan.pHostName() ); - epicsAutoMutexRelease unlocker ( locker ); + epicsGuardRelease < epicsMutex > unlocker ( locker ); pNetIO->exception ( ECA_DISCONN, buf ); } if ( ! pNetIO->isSubscription() ) { @@ -1364,7 +1358,7 @@ cac::subscriptionRequest ( nciu &chan, unsigned type, // X aCC 361 arrayElementCount nElem, unsigned mask, cacStateNotify ¬ifyIn ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > guard ( this->mutex ); autoPtrRecycle < netSubscription > pIO ( this->ioTable, chan.cacPrivateListOfIO::eventq, *this, netSubscription::factory ( this->freeListSubscription, @@ -1373,7 +1367,7 @@ cac::subscriptionRequest ( nciu &chan, unsigned type, // X aCC 361 this->ioTable.add ( *pIO ); chan.cacPrivateListOfIO::eventq.add ( *pIO ); if ( chan.connected () ) { - this->flushIfRequired ( *chan.getPIIU() ); + this->flushIfRequired ( guard, *chan.getPIIU() ); chan.getPIIU()->subscriptionRequest ( chan, *pIO ); } cacChannel::ioid id = pIO->getId (); @@ -1385,19 +1379,19 @@ cac::subscriptionRequest ( nciu &chan, unsigned type, // X aCC 361 } } -bool cac::noopAction ( callbackAutoMutex &, tcpiiu &, +bool cac::noopAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void * /* pMsgBdy */ ) { return true; } -bool cac::echoRespAction ( callbackAutoMutex &, tcpiiu &, +bool cac::echoRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void * /* pMsgBdy */ ) { return true; } -bool cac::writeNotifyRespAction ( callbackAutoMutex &, tcpiiu &, +bool cac::writeNotifyRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &hdr, void * /* pMsgBdy */ ) { int caStatus = hdr.m_cid; @@ -1411,10 +1405,9 @@ bool cac::writeNotifyRespAction ( callbackAutoMutex &, tcpiiu &, return true; } -bool cac::readNotifyRespAction ( callbackAutoMutex &, tcpiiu &iiu, +bool cac::readNotifyRespAction ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, void *pMsgBdy ) { - /* * the channel id field is abused for * read notify status starting with CA V4.1 @@ -1452,7 +1445,7 @@ bool cac::readNotifyRespAction ( callbackAutoMutex &, tcpiiu &iiu, return true; } -bool cac::eventRespAction (callbackAutoMutex &, tcpiiu &iiu, +bool cac::eventRespAction (epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, void *pMsgBdy ) { int caStatus; @@ -1501,7 +1494,7 @@ bool cac::eventRespAction (callbackAutoMutex &, tcpiiu &iiu, return true; } -bool cac::readRespAction ( callbackAutoMutex &, tcpiiu &, +bool cac::readRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &hdr, void *pMsgBdy ) { this->ioCompletionNotifyAndDestroy ( hdr.m_available, @@ -1509,13 +1502,13 @@ bool cac::readRespAction ( callbackAutoMutex &, tcpiiu &, return true; } -bool cac::clearChannelRespAction ( callbackAutoMutex &, tcpiiu &, +bool cac::clearChannelRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void * /* pMsgBdy */ ) { return true; // currently a noop } -bool cac::defaultExcep ( callbackAutoMutex &, tcpiiu &iiu, +bool cac::defaultExcep ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &, const char *pCtx, unsigned status ) { @@ -1527,7 +1520,7 @@ bool cac::defaultExcep ( callbackAutoMutex &, tcpiiu &iiu, return true; } -bool cac::eventAddExcep ( callbackAutoMutex &, tcpiiu & /* iiu */, +bool cac::eventAddExcep ( epicsGuard < callbackMutex > &, tcpiiu & /* iiu */, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ) { @@ -1536,7 +1529,7 @@ bool cac::eventAddExcep ( callbackAutoMutex &, tcpiiu & /* iiu */, return true; } -bool cac::readExcep ( callbackAutoMutex &, tcpiiu &, +bool cac::readExcep ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ) { @@ -1545,7 +1538,7 @@ bool cac::readExcep ( callbackAutoMutex &, tcpiiu &, return true; } -bool cac::writeExcep ( callbackAutoMutex &, tcpiiu &, +bool cac::writeExcep ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ) { @@ -1557,7 +1550,7 @@ bool cac::writeExcep ( callbackAutoMutex &, tcpiiu &, return true; } -bool cac::readNotifyExcep ( callbackAutoMutex &, tcpiiu &, +bool cac::readNotifyExcep ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ) { @@ -1566,7 +1559,7 @@ bool cac::readNotifyExcep ( callbackAutoMutex &, tcpiiu &, return true; } -bool cac::writeNotifyExcep ( callbackAutoMutex &, tcpiiu &, +bool cac::writeNotifyExcep ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ) { @@ -1575,7 +1568,7 @@ bool cac::writeNotifyExcep ( callbackAutoMutex &, tcpiiu &, return true; } -bool cac::exceptionRespAction ( callbackAutoMutex & cbMutex, tcpiiu & iiu, +bool cac::exceptionRespAction ( epicsGuard < callbackMutex > & cbMutex, tcpiiu & iiu, const caHdrLargeArray & hdr, void * pMsgBdy ) { const caHdr * pReq = reinterpret_cast < const caHdr * > ( pMsgBdy ); @@ -1615,12 +1608,12 @@ bool cac::exceptionRespAction ( callbackAutoMutex & cbMutex, tcpiiu & iiu, return ( this->*pStub ) ( cbMutex, iiu, req, pCtx, hdr.m_available ); } -bool cac::accessRightsRespAction ( callbackAutoMutex &, tcpiiu &, +bool cac::accessRightsRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &hdr, void * /* pMsgBdy */ ) { nciu * pChan; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pChan = this->chanTable.lookup ( hdr.m_cid ); if ( pChan ) { unsigned ar = hdr.m_available; @@ -1643,13 +1636,13 @@ bool cac::accessRightsRespAction ( callbackAutoMutex &, tcpiiu &, return true; } -bool cac::claimCIURespAction ( callbackAutoMutex &, tcpiiu & iiu, +bool cac::claimCIURespAction ( epicsGuard < callbackMutex > &, tcpiiu & iiu, const caHdrLargeArray & hdr, void * /*pMsgBdy */ ) { nciu * pChan; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pChan = this->chanTable.lookup ( hdr.m_cid ); if ( pChan ) { unsigned sidTmp; @@ -1677,10 +1670,10 @@ bool cac::claimCIURespAction ( callbackAutoMutex &, tcpiiu & iiu, } bool cac::verifyAndDisconnectChan ( - callbackAutoMutex & cbMutex, tcpiiu & /* iiu */, + epicsGuard < callbackMutex > & cbMutex, tcpiiu & /* iiu */, const caHdrLargeArray & hdr, void * /* pMsgBdy */ ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); nciu * pChan = this->chanTable.lookup ( hdr.m_cid ); if ( ! pChan ) { return true; @@ -1692,8 +1685,8 @@ bool cac::verifyAndDisconnectChan ( return true; } -void cac::disconnectChannelPrivate ( callbackAutoMutex & cbLocker, - epicsAutoMutex & locker, +void cac::disconnectChannelPrivate ( epicsGuard < callbackMutex > & cbLocker, + epicsGuard < epicsMutex > & locker, nciu & chan, netiiu & dstIIU ) { this->disconnectAllIO ( locker, chan, true ); @@ -1701,7 +1694,7 @@ void cac::disconnectChannelPrivate ( callbackAutoMutex & cbLocker, chan.disconnect ( limboIIU ); limboIIU.attachChannel ( chan ); { - epicsAutoMutexRelease autoMutexRelease ( locker ); + epicsGuardRelease < epicsMutex > autoMutexRelease ( locker ); chan.connectStateNotify (); chan.accessRightsNotify (); } @@ -1710,7 +1703,7 @@ void cac::disconnectChannelPrivate ( callbackAutoMutex & cbLocker, dstIIU.attachChannel ( chan ); } -bool cac::badTCPRespAction ( callbackAutoMutex &, tcpiiu & iiu, +bool cac::badTCPRespAction ( epicsGuard < callbackMutex > &, tcpiiu & iiu, const caHdrLargeArray & hdr, void * /* pMsgBdy */ ) { char hostName[64]; @@ -1720,7 +1713,7 @@ bool cac::badTCPRespAction ( callbackAutoMutex &, tcpiiu & iiu, return false; } -bool cac::executeResponse ( callbackAutoMutex & cbLocker, tcpiiu & iiu, +bool cac::executeResponse ( epicsGuard < callbackMutex > & cbLocker, tcpiiu & iiu, caHdrLargeArray & hdr, char * pMshBody ) { // execute the response message @@ -1794,7 +1787,7 @@ void cac::vSignal ( int ca_status, const char *pfilenm, void cac::incrementOutstandingIO () { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); if ( this->pndRecvCnt < UINT_MAX ) { this->pndRecvCnt++; } @@ -1808,7 +1801,7 @@ void cac::decrementOutstandingIO () bool signalNeeded; { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); if ( this->pndRecvCnt > 0u ) { this->pndRecvCnt--; if ( this->pndRecvCnt == 0u ) { @@ -1833,7 +1826,7 @@ void cac::decrementOutstandingIO ( unsigned sequenceNo ) bool signalNeeded; { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); if ( this->readSeq == sequenceNo ) { if ( this->pndRecvCnt > 0u ) { this->pndRecvCnt--; @@ -1866,12 +1859,12 @@ void cac::selfTest () const this->beaconTable.verify (); } -void cac::notifyNewFD ( callbackAutoMutex &, SOCKET sock ) const +void cac::notifyNewFD ( epicsGuard < callbackMutex > &, SOCKET sock ) const { this->notify.fdWasCreated ( sock ); } -void cac::notifyDestroyFD ( callbackAutoMutex &, SOCKET sock ) const +void cac::notifyDestroyFD ( epicsGuard < callbackMutex > &, SOCKET sock ) const { this->notify.fdWasDestroyed ( sock ); } @@ -1883,25 +1876,25 @@ void cac::tcpCircuitShutdown ( tcpiiu & iiu, bool discardPendingMessages ) // applications, and therefore the callback lock below // will not block { - epicsAutoMutex autoMutexCAC ( this->mutex ); + epicsGuard < epicsMutex > autoMutexCAC ( this->mutex ); if ( this->pudpiiu ) { this->pudpiiu->wakeupMsg (); } } - callbackAutoMutex autoMutexCB ( *this ); - epicsAutoMutex autoMutexCAC ( this->mutex ); - iiu.shutdown ( autoMutexCB, discardPendingMessages ); + epicsGuard < callbackMutex > cbGuard ( this->cbMutex ); + epicsGuard < epicsMutex > guard ( this->mutex ); + iiu.shutdown ( cbGuard, discardPendingMessages ); } void cac::uninstallIIU ( tcpiiu & iiu ) { - callbackAutoMutex cbLocker ( *this ); - this->privateUninstallIIU ( cbLocker, iiu ); + epicsGuard < callbackMutex > cbGuard ( this->cbMutex ); + this->privateUninstallIIU ( cbGuard, iiu ); } -void cac::privateUninstallIIU ( callbackAutoMutex & cbMutex, tcpiiu & iiu ) +void cac::privateUninstallIIU ( epicsGuard < callbackMutex > & cbMutex, tcpiiu & iiu ) { - epicsAutoMutex autoMutexCAC ( this->mutex ); + epicsGuard < epicsMutex > autoMutexCAC ( this->mutex ); if ( iiu.channelCount() ) { char hostNameTmp[64]; iiu.hostName ( hostNameTmp, sizeof ( hostNameTmp ) ); @@ -1931,45 +1924,9 @@ void cac::privateUninstallIIU ( callbackAutoMutex & cbMutex, tcpiiu & iiu ) this->iiuUninstall.signal(); } -void cac::preemptiveCallbackLock () -{ - // the count must be incremented prior to taking the lock - { - epicsAutoMutex autoMutex ( this->mutex ); - assert ( this->recvThreadsPendingCount < UINT_MAX ); - this->recvThreadsPendingCount++; - } - this->callbackMutex.lock (); -} - -void cac::preemptiveCallbackUnlock () -{ - this->callbackMutex.unlock (); - bool signalRequired; - { - epicsAutoMutex autoMutex ( this->mutex ); - assert ( this->recvThreadsPendingCount > 0 ); - this->recvThreadsPendingCount--; - if ( this->pCallbackLocker ) { - if ( this->recvThreadsPendingCount == 0u ) { - signalRequired = true; - } - else { - signalRequired = false; - } - } - else { - signalRequired = false; - } - } - if ( signalRequired ) { - this->noRecvThreadsPending.signal (); - } -} - double cac::beaconPeriod ( const nciu & chan ) const { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); const netiiu * pIIU = chan.getConstPIIU (); if ( pIIU ) { osiSockAddr addr = pIIU->getNetworkAddress (); diff --git a/src/ca/cac.h b/src/ca/cac.h index d48439356..cda795e90 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -18,18 +18,28 @@ #ifndef cach #define cach +#ifdef epicsExportSharedSymbols +#define cach_restore_epicsExportSharedSymbols +#undef epicsExportSharedSymbols +#endif + +#include "shareLib.h" + #include "ipAddrToAsciiAsynchronous.h" #include "epicsTimer.h" #include "epicsEvent.h" #include "freeList.h" -#include "nciu.h" - +#ifdef cach_restore_epicsExportSharedSymbols #define epicsExportSharedSymbols +#endif + +#include "shareLib.h" + +#include "nciu.h" #include "bhe.h" #include "cacIO.h" #include "netIO.h" -#undef epicsExportSharedSymbols class netWriteNotifyIO; class netReadNotifyIO; @@ -52,6 +62,23 @@ struct caHdrLargeArray; extern epicsThreadPrivateId caClientCallbackThreadId; +class callbackMutex { +public: + callbackMutex ( bool threadsMayBeBlockingForRecvThreadsToFinish ); + ~callbackMutex (); + void lock (); + void unlock (); + void waitUntilNoRecvThreadsPending (); +private: + epicsMutex countMutex; + epicsMutex primaryMutex; + epicsEvent noRecvThreadsPending; + unsigned recvThreadsPendingCount; + bool threadsMayBeBlockingForRecvThreadsToFinish; + //callbackMutex ( callbackMutex & ); + //callbackMutex & operator = ( callbackMutex & ); +}; + class cac : private cacRecycle { public: @@ -74,7 +101,7 @@ public: void flushRequest (); int pendIO ( const double &timeout ); int pendEvent ( const double &timeout ); - bool executeResponse ( class callbackAutoMutex &, tcpiiu &, + bool executeResponse ( epicsGuard < callbackMutex > &, tcpiiu &, caHdrLargeArray &, char *pMsgBody ); void ioCancel ( nciu &chan, const cacChannel::ioid &id ); void ioShow ( const cacChannel::ioid &id, unsigned level ) const; @@ -82,7 +109,7 @@ public: // channel routines void installNetworkChannel ( nciu &, netiiu *&piiu ); bool lookupChannelAndTransferToTCP ( - class callbackAutoMutex & cbMutex, + epicsGuard < callbackMutex > &, unsigned cid, unsigned sid, ca_uint16_t typeCode, arrayElementCount count, unsigned minorVersionNumber, const osiSockAddr &, @@ -138,8 +165,8 @@ public: epicsMutex & mutexRef (); void attachToClientCtx (); void selfTest () const; - void notifyNewFD ( class callbackAutoMutex &, SOCKET ) const; - void notifyDestroyFD ( class callbackAutoMutex &, SOCKET ) const; + void notifyNewFD ( epicsGuard < callbackMutex > &, SOCKET ) const; + void notifyDestroyFD ( epicsGuard < callbackMutex > &, SOCKET ) const; void uninstallIIU ( tcpiiu &iiu ); bool preemptiveCallbakIsEnabled () const; double beaconPeriod ( const nciu & chan ) const; @@ -161,23 +188,22 @@ private: resTable < tcpiiu, caServerID > serverTable; tsFreeList - < class netReadNotifyIO, 1024 > + < class netReadNotifyIO, 1024, epicsMutexNOOP > freeListReadNotifyIO; tsFreeList - < class netWriteNotifyIO, 1024 > + < class netWriteNotifyIO, 1024, epicsMutexNOOP > freeListWriteNotifyIO; tsFreeList - < class netSubscription, 1024 > + < class netSubscription, 1024, epicsMutexNOOP > freeListSubscription; epicsTime programBeginTime; double connTMO; // **** lock hierarchy **** // callback lock must always be acquired before // the primary mutex if both locks are needed + callbackMutex cbMutex; mutable epicsMutex mutex; - epicsMutex callbackMutex; epicsEvent ioDone; - epicsEvent noRecvThreadsPending; epicsEvent iiuUninstall; epicsTimerQueueActive & timerQueue; char * pUserName; @@ -187,32 +213,30 @@ private: * pRepeaterSubscribeTmr; void * tcpSmallRecvBufFreeList; void * tcpLargeRecvBufFreeList; - class callbackAutoMutex * pCallbackLocker; + epicsGuard * pCallbackGuard; cacNotify & notify; epicsThreadId initializingThreadsId; unsigned initializingThreadsPriority; unsigned maxRecvBytesTCP; unsigned pndRecvCnt; unsigned readSeq; - unsigned recvThreadsPendingCount; - void privateUninstallIIU ( class callbackAutoMutex &, tcpiiu &iiu ); + void privateUninstallIIU ( epicsGuard < callbackMutex > &, tcpiiu &iiu ); void flushRequestPrivate (); void run (); bool setupUDP (); void connectAllIO ( nciu &chan ); - void disconnectAllIO ( epicsAutoMutex &locker, nciu &chan, bool enableCallbacks ); - void flushIfRequired ( netiiu & ); + void disconnectAllIO ( epicsGuard < epicsMutex > & locker, nciu & chan, bool enableCallbacks ); + void flushIfRequired ( epicsGuard < epicsMutex > &, netiiu & ); void recycleReadNotifyIO ( netReadNotifyIO &io ); void recycleWriteNotifyIO ( netWriteNotifyIO &io ); void recycleSubscription ( netSubscription &io ); - void preemptiveCallbackLock (); - void preemptiveCallbackUnlock (); + void removeAllChan ( - callbackAutoMutex & cbLocker, epicsAutoMutex &locker, + epicsGuard < callbackMutex > & cbLocker, epicsGuard < epicsMutex > &locker, netiiu & srcIIU, netiiu & dstIIU ); void disconnectChannelPrivate ( - class callbackAutoMutex &, epicsAutoMutex &, + epicsGuard < callbackMutex > &, epicsGuard < epicsMutex > &, nciu & chan, netiiu & dstIIU ); void ioCompletionNotify ( unsigned id, unsigned type, @@ -231,82 +255,58 @@ private: int status, const char *pContext, unsigned type, arrayElementCount count ); // recv protocol stubs - bool noopAction ( callbackAutoMutex &, tcpiiu &, + bool noopAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool echoRespAction ( callbackAutoMutex &, tcpiiu &, + bool echoRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool writeNotifyRespAction ( callbackAutoMutex &, tcpiiu &, + bool writeNotifyRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool readNotifyRespAction ( callbackAutoMutex &, tcpiiu &, + bool readNotifyRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool eventRespAction ( callbackAutoMutex &, tcpiiu &, + bool eventRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool readRespAction ( callbackAutoMutex &, tcpiiu &, + bool readRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool clearChannelRespAction ( callbackAutoMutex &, tcpiiu &, + bool clearChannelRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool exceptionRespAction ( callbackAutoMutex &, tcpiiu &, + bool exceptionRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool accessRightsRespAction ( callbackAutoMutex &, tcpiiu &, + bool accessRightsRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool claimCIURespAction ( callbackAutoMutex &, tcpiiu &, + bool claimCIURespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool verifyAndDisconnectChan ( callbackAutoMutex &, tcpiiu &, + bool verifyAndDisconnectChan ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); - bool badTCPRespAction ( callbackAutoMutex &, tcpiiu &, + bool badTCPRespAction ( epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); typedef bool ( cac::*pProtoStubTCP ) ( - callbackAutoMutex &, tcpiiu &, + epicsGuard < callbackMutex > &, tcpiiu &, const caHdrLargeArray &, void *pMsgBdy ); static const pProtoStubTCP tcpJumpTableCAC []; - bool defaultExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, + bool defaultExcep ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool eventAddExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, + bool eventAddExcep ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool readExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, + bool readExcep ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool writeExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, + bool writeExcep ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool clearChanExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, + bool clearChanExcep ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool readNotifyExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, + bool readNotifyExcep ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); - bool writeNotifyExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, + bool writeNotifyExcep ( epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); typedef bool ( cac::*pExcepProtoStubTCP ) ( - callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr, + epicsGuard < callbackMutex > &, tcpiiu &iiu, const caHdrLargeArray &hdr, const char *pCtx, unsigned status ); static const pExcepProtoStubTCP tcpExcepJumpTableCAC []; - friend class callbackAutoMutex; - friend class callbackAutoMutexRelease; - cac ( const cac & ); cac & operator = ( const cac & ); }; -class callbackAutoMutex { -public: - callbackAutoMutex ( cac & ctxIn ); - ~callbackAutoMutex (); -private: - cac & ctx; - callbackAutoMutex ( const callbackAutoMutex & ); - callbackAutoMutex & operator = ( const callbackAutoMutex & ); - friend class callbackAutoMutexRelease; -}; - -class callbackAutoMutexRelease { -public: - callbackAutoMutexRelease ( callbackAutoMutex & autoMutexIn ); - ~callbackAutoMutexRelease (); -private: - callbackAutoMutex & autoMutex; - callbackAutoMutexRelease ( const callbackAutoMutexRelease & ); - callbackAutoMutexRelease & operator = ( const callbackAutoMutexRelease & ); -}; - inline const char * cac::userNamePointer () const { return this->pUserName; @@ -384,29 +384,7 @@ inline bool cac::ioComplete () const inline bool cac::preemptiveCallbakIsEnabled () const { - return ! this->pCallbackLocker; -} - -inline callbackAutoMutex::callbackAutoMutex ( cac & ctxIn ) : - ctx ( ctxIn ) -{ - this->ctx.preemptiveCallbackLock (); -} - -inline callbackAutoMutex::~callbackAutoMutex () -{ - this->ctx.preemptiveCallbackUnlock (); -} - -inline callbackAutoMutexRelease::callbackAutoMutexRelease ( callbackAutoMutex & autoMutexIn ) : - autoMutex ( autoMutexIn ) -{ - this->autoMutex.ctx.preemptiveCallbackUnlock (); -} - -inline callbackAutoMutexRelease::~callbackAutoMutexRelease () -{ - this->autoMutex.ctx.preemptiveCallbackLock (); + return ! this->pCallbackGuard; } #endif // ifdef cach diff --git a/src/ca/comBuf.cpp b/src/ca/comBuf.cpp index 33a516952..6c54ee375 100644 --- a/src/ca/comBuf.cpp +++ b/src/ca/comBuf.cpp @@ -19,19 +19,7 @@ #include "iocinf.h" #include "comBuf.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < class comBuf, 0x20 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < class comBuf, 0x20 > comBuf::freeList; -epicsMutex comBuf::freeListMutex; +epicsSingleton < tsFreeList < class comBuf, 0x20 > > comBuf::pFreeList; bool comBuf::flushToWire ( wireSendAdapter &wire ) { diff --git a/src/ca/comBuf.h b/src/ca/comBuf.h index 67b8ceb4a..60a78c5ee 100644 --- a/src/ca/comBuf.h +++ b/src/ca/comBuf.h @@ -23,6 +23,7 @@ #include "epicsAssert.h" #include "epicsTypes.h" #include "tsFreeList.h" +#include "epicsSingleton.h" #include "tsDLList.h" #include "osiWireFormat.h" @@ -91,8 +92,7 @@ private: epicsUInt8 buf [ comBufSize ]; unsigned unoccupiedElem ( unsigned elemSize, unsigned nElem ); unsigned occupiedElem ( unsigned elemSize, unsigned nElem ); - static tsFreeList < class comBuf, 0x20 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < class comBuf, 0x20 > > pFreeList; }; inline comBuf::comBuf () : commitIndex ( 0u ), @@ -118,14 +118,12 @@ inline void comBuf::clear () inline void * comBuf::operator new ( size_t size, const std::nothrow_t & ) { - epicsAutoMutex locker ( comBuf::freeListMutex ); - return comBuf::freeList.allocate ( size ); + return comBuf::pFreeList->allocate ( size ); } - + inline void comBuf::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( comBuf::freeListMutex ); - comBuf::freeList.release ( pCadaver, size ); + comBuf::pFreeList->release ( pCadaver, size ); } inline unsigned comBuf::unoccupiedBytes () const diff --git a/src/ca/comQueSend.cpp b/src/ca/comQueSend.cpp index cf4e1f9ef..be0949c23 100644 --- a/src/ca/comQueSend.cpp +++ b/src/ca/comQueSend.cpp @@ -59,12 +59,10 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "virtualCircuit.h" - -#define epicsExportSharedSymbols #include "db_access.h" // for dbr_short_t etc -#undef epicsExportSharedSymbols comQueSend::comQueSend ( wireSendAdapter & wireIn ) : wire ( wireIn ), nBytesPending ( 0u ) diff --git a/src/ca/db_access.h b/src/ca/db_access.h index 51c863d51..de3831769 100644 --- a/src/ca/db_access.h +++ b/src/ca/db_access.h @@ -86,6 +86,8 @@ of this distribution. # undef epicsExportSharedSymbols #endif +#include "shareLib.h" + #include "epicsTypes.h" #include "epicsTime.h" diff --git a/src/ca/getCallback.cpp b/src/ca/getCallback.cpp index d2653a72b..fba722c00 100644 --- a/src/ca/getCallback.cpp +++ b/src/ca/getCallback.cpp @@ -15,22 +15,11 @@ * 505 665 1831 */ +#define epicsExportSharedSymbols #include "iocinf.h" #include "oldAccess.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < class getCallback, 1024 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < class getCallback, 1024 > getCallback::freeList; -epicsMutex getCallback::freeListMutex; +epicsSingleton < tsFreeList < class getCallback, 1024 > > getCallback::pFreeList; getCallback::getCallback ( oldChannelNotify &chanIn, caEventCallBackFunc *pFuncIn, void *pPrivateIn ) : diff --git a/src/ca/getCopy.cpp b/src/ca/getCopy.cpp index 3f6bcd90b..583d0a10a 100644 --- a/src/ca/getCopy.cpp +++ b/src/ca/getCopy.cpp @@ -17,23 +17,12 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "oldAccess.h" #include "cac.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < class getCopy, 1024 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < class getCopy, 1024 > getCopy::freeList; -epicsMutex getCopy::freeListMutex; +epicsSingleton < tsFreeList < class getCopy, 1024 > > getCopy::pFreeList; getCopy::getCopy ( oldCAC &cacCtxIn, oldChannelNotify &chanIn, unsigned typeIn, arrayElementCount countIn, void *pValueIn ) : diff --git a/src/ca/hostNameCache.cpp b/src/ca/hostNameCache.cpp index a841f6933..b3f3acc81 100644 --- a/src/ca/hostNameCache.cpp +++ b/src/ca/hostNameCache.cpp @@ -21,19 +21,7 @@ #include "iocinf.h" #include "hostNameCache.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < hostNameCache, 16 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < hostNameCache, 16 > hostNameCache::freeList; -epicsMutex hostNameCache::freeListMutex; +epicsSingleton < tsFreeList < hostNameCache, 16 > > hostNameCache::pFreeList; hostNameCache::hostNameCache ( const osiSockAddr &addr, ipAddrToAsciiEngine &engine ) : ipAddrToAsciiAsynchronous ( addr ), @@ -73,10 +61,10 @@ void hostNameCache::hostName ( char *pBuf, unsigned bufSize ) const void * hostNameCache::operator new ( size_t size ) { - return hostNameCache::freeList.allocate ( size ); + return hostNameCache::pFreeList->allocate ( size ); } void hostNameCache::operator delete ( void *pCadaver, size_t size ) { - hostNameCache::freeList.release ( pCadaver, size ); + hostNameCache::pFreeList->release ( pCadaver, size ); } diff --git a/src/ca/hostNameCache.h b/src/ca/hostNameCache.h index dc39b0ecc..71293c14f 100644 --- a/src/ca/hostNameCache.h +++ b/src/ca/hostNameCache.h @@ -20,6 +20,7 @@ #include "ipAddrToAsciiAsynchronous.h" #include "tsFreeList.h" +#include "epicsSingleton.h" class hostNameCache : public ipAddrToAsciiAsynchronous { public: @@ -33,8 +34,7 @@ public: private: bool ioComplete; char hostNameBuf [128]; - static tsFreeList < class hostNameCache, 16 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < class hostNameCache, 16 > > pFreeList; }; #endif // #ifndef hostNameCacheh diff --git a/src/ca/msgForMultiplyDefinedPV.cpp b/src/ca/msgForMultiplyDefinedPV.cpp index 4ededc3f8..47ad593c5 100644 --- a/src/ca/msgForMultiplyDefinedPV.cpp +++ b/src/ca/msgForMultiplyDefinedPV.cpp @@ -25,25 +25,14 @@ #include "caerr.h" // for ECA_DBLCHNL #undef epicsExportSharedSymbols -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < class msgForMultiplyDefinedPV, 16 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < class msgForMultiplyDefinedPV, 16 > - msgForMultiplyDefinedPV::freeList; -epicsMutex msgForMultiplyDefinedPV::freeListMutex; +epicsSingleton < tsFreeList < class msgForMultiplyDefinedPV, 16 > > + msgForMultiplyDefinedPV::pFreeList; msgForMultiplyDefinedPV::msgForMultiplyDefinedPV ( - cac &cacRefIn, const char *pChannelName, const char *pAcc, - const osiSockAddr &rej ) : - ipAddrToAsciiAsynchronous ( rej ), cacRef ( cacRefIn ) + callbackMutex & mutexIn, cac & cacRefIn, + const char * pChannelName, const char * pAcc, const osiSockAddr &rej ) : + ipAddrToAsciiAsynchronous ( rej ), cacRef ( cacRefIn ), + mutex ( mutexIn ) { strncpy ( this->acc, pAcc, sizeof ( this->acc ) ); this->acc[ sizeof ( this->acc ) - 1 ] = '\0'; @@ -51,11 +40,11 @@ msgForMultiplyDefinedPV::msgForMultiplyDefinedPV ( this->channel[ sizeof ( this->channel ) - 1 ] = '\0'; } -void msgForMultiplyDefinedPV::ioCompletionNotify ( const char *pHostNameRej ) +void msgForMultiplyDefinedPV::ioCompletionNotify ( const char * pHostNameRej ) { char buf[256]; sprintf ( buf, "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s", this->channel, this->acc, pHostNameRej ); - callbackAutoMutex autoMutex ( this->cacRef ); + epicsGuard < callbackMutex > guard ( this->mutex ); genLocalExcep ( this->cacRef, ECA_DBLCHNL, buf ); } diff --git a/src/ca/msgForMultiplyDefinedPV.h b/src/ca/msgForMultiplyDefinedPV.h index 7899ee2a7..d5f9e5f9b 100644 --- a/src/ca/msgForMultiplyDefinedPV.h +++ b/src/ca/msgForMultiplyDefinedPV.h @@ -20,15 +20,17 @@ #include "ipAddrToAsciiAsynchronous.h" #include "tsFreeList.h" +#include "epicsSingleton.h" #include "epicsMutex.h" class cac; +class callbackMutex; class msgForMultiplyDefinedPV : public ipAddrToAsciiAsynchronous { public: - msgForMultiplyDefinedPV ( - cac &cacRefIn, const char *pChannelName, const char *pAcc, - const osiSockAddr &rej ); + msgForMultiplyDefinedPV ( callbackMutex &, + cac & cacRefIn, const char * pChannelName, const char * pAcc, + const osiSockAddr & rej ); msgForMultiplyDefinedPV ( const osiSockAddr &addr, ipAddrToAsciiEngine &engine ); void * operator new ( size_t size ); void operator delete ( void *pCadaver, size_t size ); @@ -36,23 +38,21 @@ private: void ioCompletionNotify ( const char *pHostName ); char acc[64]; char channel[64]; - cac &cacRef; - static tsFreeList < class msgForMultiplyDefinedPV, 16 > freeList; - static epicsMutex freeListMutex; + cac & cacRef; + callbackMutex & mutex; + static epicsSingleton < tsFreeList < class msgForMultiplyDefinedPV, 16 > > pFreeList; msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & ); msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & ); }; inline void * msgForMultiplyDefinedPV::operator new ( size_t size ) { - epicsAutoMutex locker ( msgForMultiplyDefinedPV::freeListMutex ); - return msgForMultiplyDefinedPV::freeList.allocate ( size ); + return msgForMultiplyDefinedPV::pFreeList->allocate ( size ); } inline void msgForMultiplyDefinedPV::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( msgForMultiplyDefinedPV::freeListMutex ); - msgForMultiplyDefinedPV::freeList.release ( pCadaver, size ); + msgForMultiplyDefinedPV::pFreeList->release ( pCadaver, size ); } #endif // ifdef msgForMultiplyDefinedPVh diff --git a/src/ca/nciu.cpp b/src/ca/nciu.cpp index a7491453f..816879eaa 100644 --- a/src/ca/nciu.cpp +++ b/src/ca/nciu.cpp @@ -23,30 +23,15 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "cac.h" #include "osiWireFormat.h" - -#define epicsExportSharedSymbols #include "udpiiu.h" #include "cadef.h" #include "db_access.h" // for INVALID_DB_REQ -#undef epicsExportSharedSymbols -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < nciu, 1024, 0 >; -template class tsDLNode < baseNMIU >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < class nciu, 1024 > nciu::freeList; -epicsMutex nciu::freeListMutex; +epicsSingleton < tsFreeList < class nciu, 1024 > > nciu::pFreeList; nciu::nciu ( cac & cacIn, netiiu & iiuIn, cacChannelNotify & chanIn, const char *pNameIn, cacChannel::priLev pri ) : @@ -338,26 +323,26 @@ void nciu::initiateConnect () void nciu::hostName ( char *pBuf, unsigned bufLength ) const { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); this->piiu->hostName ( pBuf, bufLength ); } // deprecated - please do not use, this is _not_ thread safe const char * nciu::pHostName () const { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); return this->piiu->pHostName (); // ouch ! } bool nciu::ca_v42_ok () const { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); return this->piiu->ca_v42_ok (); } short nciu::nativeType () const { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); short type; if ( this->f_connected ) { if ( this->typeCode < SHRT_MAX ) { @@ -375,7 +360,7 @@ short nciu::nativeType () const arrayElementCount nciu::nativeElementCount () const { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); arrayElementCount countOut; if ( this->f_connected ) { countOut = this->count; @@ -388,14 +373,14 @@ arrayElementCount nciu::nativeElementCount () const caAccessRights nciu::accessRights () const { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); caAccessRights tmp = this->accessRightState; return tmp; } unsigned nciu::searchAttempts () const { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); return this->retry; } @@ -406,7 +391,7 @@ double nciu::beaconPeriod () const void nciu::notifyStateChangeFirstConnectInCountOfOutstandingIO () { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); // test is performed via a callback so that locking is correct if ( ! this->f_connectTimeOutSeen && ! this->f_previousConn ) { if ( this->notify ().includeFirstConnectInCountOfOutstandingIO () ) { @@ -426,7 +411,7 @@ void nciu::notifyStateChangeFirstConnectInCountOfOutstandingIO () void nciu::show ( unsigned level ) const { - epicsAutoMutex locker ( this->cacCtx.mutexRef() ); + epicsGuard < epicsMutex > locker ( this->cacCtx.mutexRef() ); if ( this->f_connected ) { char hostNameTmp [256]; this->hostName ( hostNameTmp, sizeof ( hostNameTmp ) ); diff --git a/src/ca/nciu.h b/src/ca/nciu.h index 5ed225f5d..2af6f6439 100644 --- a/src/ca/nciu.h +++ b/src/ca/nciu.h @@ -17,17 +17,29 @@ #ifndef nciuh #define nciuh +#ifdef epicsExportSharedSymbols +#define nciuh_restore_epicsExportSharedSymbols +#undef epicsExportSharedSymbols +#endif + +#include "shareLib.h" + #include "resourceLib.h" #include "tsDLList.h" #include "tsFreeList.h" #include "epicsMutex.h" +#include "epicsSingleton.h" + +#ifdef nciuh_restore_epicsExportSharedSymbols +#define epicsExportSharedSymbols +#endif + +#include "shareLib.h" #define CA_MINOR_PROTOCOL_REVISION 10 #include "caProto.h" -#define epicsExportSharedSymbols #include "cacIO.h" -#undef epicsExportSharedSymbols class cac; class netiiu; @@ -118,22 +130,19 @@ private: void hostName ( char *pBuf, unsigned bufLength ) const; void notifyStateChangeFirstConnectInCountOfOutstandingIO (); static void stringVerify ( const char *pStr, const unsigned count ); - static tsFreeList < class nciu, 1024 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < class nciu, 1024 > > pFreeList; nciu ( const nciu & ); nciu & operator = ( const nciu & ); }; inline void * nciu::operator new ( size_t size ) { - epicsAutoMutex locker ( nciu::freeListMutex ); - return nciu::freeList.allocate ( size ); + return nciu::pFreeList->allocate ( size ); } inline void nciu::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( nciu::freeListMutex ); - nciu::freeList.release ( pCadaver, size ); + nciu::pFreeList->release ( pCadaver, size ); } inline bool nciu::identifierEquivelence ( unsigned idToMatch ) diff --git a/src/ca/netIO.h b/src/ca/netIO.h index 0de14b0fd..5fbb63ae5 100644 --- a/src/ca/netIO.h +++ b/src/ca/netIO.h @@ -52,7 +52,7 @@ private: class netSubscription : public baseNMIU { public: static netSubscription * factory ( - tsFreeList < class netSubscription, 1024 > &, + tsFreeList < class netSubscription, 1024, epicsMutexNOOP > &, nciu &chan, unsigned type, arrayElementCount count, unsigned mask, cacStateNotify ¬ify ); void show ( unsigned level ) const; @@ -79,10 +79,10 @@ private: unsigned mask, cacStateNotify ¬ify ); class netSubscription * isSubscription (); void * operator new ( size_t, - tsFreeList < class netSubscription, 1024 > & ); + tsFreeList < class netSubscription, 1024, epicsMutexNOOP > & ); # if ! defined ( NO_PLACEMENT_DELETE ) void operator delete ( void *, size_t, - tsFreeList < class netSubscription, 1024 > & ); + tsFreeList < class netSubscription, 1024, epicsMutexNOOP > & ); # endif netSubscription ( const netSubscription & ); netSubscription & operator = ( const netSubscription & ); @@ -91,7 +91,7 @@ private: class netReadNotifyIO : public baseNMIU { public: static netReadNotifyIO * factory ( - tsFreeList < class netReadNotifyIO, 1024 > &, + tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > &, nciu &chan, cacReadNotify ¬ify ); void show ( unsigned level ) const; void destroy ( class cacRecycle & ); @@ -107,10 +107,10 @@ private: cacReadNotify ¬ify; netReadNotifyIO ( nciu &chan, cacReadNotify ¬ify ); void * operator new ( size_t, - tsFreeList < class netReadNotifyIO, 1024 > & ); + tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & ); # if ! defined ( NO_PLACEMENT_DELETE ) void operator delete ( void *, size_t, - tsFreeList < class netReadNotifyIO, 1024 > & ); + tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & ); # endif netReadNotifyIO ( const netReadNotifyIO & ); netReadNotifyIO & operator = ( const netReadNotifyIO & ); @@ -119,7 +119,7 @@ private: class netWriteNotifyIO : public baseNMIU { public: static netWriteNotifyIO * factory ( - tsFreeList < class netWriteNotifyIO, 1024 > &, + tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > &, nciu &chan, cacWriteNotify ¬ify ); void show ( unsigned level ) const; void destroy ( class cacRecycle & ); @@ -135,10 +135,10 @@ private: cacWriteNotify ¬ify; netWriteNotifyIO ( nciu &chan, cacWriteNotify ¬ify ); void * operator new ( size_t, - tsFreeList < class netWriteNotifyIO, 1024 > & ); + tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & ); # if ! defined ( NO_PLACEMENT_DELETE ) void operator delete ( void *, size_t, - tsFreeList < class netWriteNotifyIO, 1024 > & ); + tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & ); # endif netWriteNotifyIO ( const netWriteNotifyIO & ); netWriteNotifyIO & operator = ( const netWriteNotifyIO & ); @@ -155,7 +155,7 @@ inline class nciu & baseNMIU::channel () const } inline void * netSubscription::operator new ( size_t size, - tsFreeList < class netSubscription, 1024 > &freeList ) + tsFreeList < class netSubscription, 1024, epicsMutexNOOP > &freeList ) { return freeList.allocate ( size ); } @@ -167,15 +167,14 @@ inline void * netSubscription::operator new ( size_t size, // a future version of netSubscription::netSubscription() #if ! defined ( NO_PLACEMENT_DELETE ) inline void netSubscription::operator delete ( void *pCadaver, size_t size, - tsFreeList < class netSubscription, 1024 > &freeList ) + tsFreeList < class netSubscription, 1024, epicsMutexNOOP > &freeList ) { freeList.release ( pCadaver, size ); } -#error #endif inline netSubscription * netSubscription::factory ( - tsFreeList < class netSubscription, 1024 > &freeList, + tsFreeList < class netSubscription, 1024, epicsMutexNOOP > &freeList, nciu &chan, unsigned type, arrayElementCount count, unsigned mask, cacStateNotify ¬ify ) { @@ -205,14 +204,14 @@ inline unsigned netSubscription::getMask () const } inline netReadNotifyIO * netReadNotifyIO::factory ( - tsFreeList < class netReadNotifyIO, 1024 > &freeList, + tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > &freeList, nciu &chan, cacReadNotify ¬ify ) { return new ( freeList ) netReadNotifyIO ( chan, notify ); } inline void * netReadNotifyIO::operator new ( size_t size, - tsFreeList < class netReadNotifyIO, 1024 > &freeList ) + tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > &freeList ) { return freeList.allocate ( size ); } @@ -224,20 +223,20 @@ inline void * netReadNotifyIO::operator new ( size_t size, // a future version of netReadNotifyIO::netReadNotifyIO() #if ! defined ( NO_PLACEMENT_DELETE ) inline void netReadNotifyIO::operator delete ( void *pCadaver, size_t size, - tsFreeList < class netReadNotifyIO, 1024 > &freeList ) { + tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > &freeList ) { freeList.release ( pCadaver, size ); } #endif inline netWriteNotifyIO * netWriteNotifyIO::factory ( - tsFreeList < class netWriteNotifyIO, 1024 > &freeList, + tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > &freeList, nciu &chan, cacWriteNotify ¬ify ) { return new ( freeList ) netWriteNotifyIO ( chan, notify ); } inline void * netWriteNotifyIO::operator new ( size_t size, - tsFreeList < class netWriteNotifyIO, 1024 > &freeList ) + tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > &freeList ) { return freeList.allocate ( size ); } @@ -249,7 +248,7 @@ inline void * netWriteNotifyIO::operator new ( size_t size, // a future version of netWriteNotifyIO::netWriteNotifyIO() #if ! defined ( NO_PLACEMENT_DELETE ) inline void netWriteNotifyIO::operator delete ( void *pCadaver, size_t size, - tsFreeList < class netWriteNotifyIO, 1024 > &freeList ) + tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > &freeList ) { freeList.release ( pCadaver, size ); } diff --git a/src/ca/netSubscription.cpp b/src/ca/netSubscription.cpp index fffebe6d0..ca9e9e1d9 100644 --- a/src/ca/netSubscription.cpp +++ b/src/ca/netSubscription.cpp @@ -12,13 +12,11 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "nciu.h" #include "cac.h" - -#define epicsExportSharedSymbols #include "db_access.h" // for dbf_type_to_text -#undef epicsExportSharedSymbols netSubscription::netSubscription ( nciu &chan, unsigned typeIn, arrayElementCount countIn, diff --git a/src/ca/netiiu.cpp b/src/ca/netiiu.cpp index 81b759640..d75f62ea5 100644 --- a/src/ca/netiiu.cpp +++ b/src/ca/netiiu.cpp @@ -19,17 +19,6 @@ #include "cac.h" #include "netiiu.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsDLNode < nciu >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - netiiu::netiiu ( cac *pClientCtxIn ) : pClientCtx ( pClientCtxIn ) { } @@ -102,12 +91,7 @@ bool netiiu::pushDatagramMsg ( const caHdr &, const void *, ca_uint16_t ) return false; } -bool netiiu::isVirtualCircuit ( const char *, const osiSockAddr & ) const -{ - return false; -} - -void netiiu::lastChannelDetachNotify ( class callbackAutoMutex & /* cbLocker */ ) +void netiiu::lastChannelDetachNotify ( class epicsGuard < class callbackMutex > & /* cbLocker */ ) { } @@ -175,7 +159,8 @@ void netiiu::flushRequestIfAboveEarlyThreshold () { } -void netiiu::blockUntilSendBacklogIsReasonable ( epicsMutex *, epicsMutex & ) +void netiiu::blockUntilSendBacklogIsReasonable + ( epicsGuard < callbackMutex > *, epicsGuard < epicsMutex > & ) { } diff --git a/src/ca/netiiu.h b/src/ca/netiiu.h index f4d42f9bf..363d9bf7c 100644 --- a/src/ca/netiiu.h +++ b/src/ca/netiiu.h @@ -38,12 +38,11 @@ public: bool searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThisChannel ); void resetChannelRetryCounts (); void attachChannel ( nciu &chan ); - void detachChannel ( class callbackAutoMutex & cbLocker, nciu &chan ); + void detachChannel ( epicsGuard < class callbackMutex > & cbLocker, nciu &chan ); nciu * firstChannel (); int printf ( const char *pformat, ... ); virtual void hostName (char *pBuf, unsigned bufLength) const; virtual const char * pHostName () const; // deprecated - please do not use - virtual bool isVirtualCircuit ( const char *pChannelName, const osiSockAddr &addr ) const; virtual bool ca_v42_ok () const; virtual bool pushDatagramMsg ( const caHdr &hdr, const void *pExt, ca_uint16_t extsize); virtual void writeRequest ( nciu &, unsigned type, unsigned nElem, const void *pValue ); @@ -56,7 +55,8 @@ public: virtual void flushRequest (); virtual bool flushBlockThreshold () const; virtual void flushRequestIfAboveEarlyThreshold (); - virtual void blockUntilSendBacklogIsReasonable ( epicsMutex *, epicsMutex & ); + virtual void blockUntilSendBacklogIsReasonable + ( epicsGuard < callbackMutex > *, epicsGuard < epicsMutex > & ); virtual void requestRecvProcessPostponedFlush (); virtual osiSockAddr getNetworkAddress () const; protected: @@ -64,7 +64,7 @@ protected: private: tsDLList < nciu > channelList; cac *pClientCtx; - virtual void lastChannelDetachNotify ( class callbackAutoMutex & cbLocker ); + virtual void lastChannelDetachNotify ( epicsGuard < class callbackMutex > & cbLocker ); netiiu ( const netiiu & ); netiiu & operator = ( const netiiu & ); }; @@ -97,7 +97,7 @@ inline void netiiu::attachChannel ( class nciu &chan ) // cac lock must also be applied when calling this inline void netiiu::detachChannel ( - class callbackAutoMutex & cbLocker, class nciu & chan ) + epicsGuard < callbackMutex > & cbLocker, class nciu & chan ) { this->channelList.remove ( chan ); if ( this->channelList.count () == 0u ) { diff --git a/src/ca/oldAccess.h b/src/ca/oldAccess.h index c5651c20b..cf2b7945a 100644 --- a/src/ca/oldAccess.h +++ b/src/ca/oldAccess.h @@ -18,14 +18,24 @@ #ifndef oldAccessh #define oldAccessh +#ifdef epicsExportSharedSymbols +# define oldAccessh_restore_epicsExportSharedSymbols +#undef epicsExportSharedSymbols +#endif + +#include "shareLib.h" + #include "tsFreeList.h" -#include "cac.h" +#ifdef oldAccessh_restore_epicsExportSharedSymbols +# define epicsExportSharedSymbols +#endif -#define epicsExportSharedSymbols +#include "shareLib.h" + +#include "cac.h" #include "cacIO.h" #include "cadef.h" -#undef epicsExportSharedSymbols struct oldChannelNotify : public cacChannelNotify { public: @@ -87,8 +97,7 @@ private: void writeException ( int status, const char *pContext, unsigned type, arrayElementCount count ); bool includeFirstConnectInCountOfOutstandingIO () const; - static tsFreeList < struct oldChannelNotify, 1024 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < struct oldChannelNotify, 1024 > > pFreeList; oldChannelNotify ( const oldChannelNotify & ); oldChannelNotify & operator = ( const oldChannelNotify & ); }; @@ -115,8 +124,7 @@ private: unsigned type, arrayElementCount count, const void *pData); void exception ( int status, const char *pContext, unsigned type, arrayElementCount count ); - static tsFreeList < class getCopy, 1024 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < class getCopy, 1024 > > pFreeList; getCopy ( const getCopy & ); getCopy & operator = ( const getCopy & ); }; @@ -138,8 +146,7 @@ private: unsigned type, arrayElementCount count, const void *pData); void exception ( int status, const char *pContext, unsigned type, arrayElementCount count ); - static tsFreeList < class getCallback, 1024 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < class getCallback, 1024 > > pFreeList; getCallback ( const getCallback & ); getCallback & operator = ( const getCallback & ); }; @@ -160,8 +167,7 @@ private: void completion (); void exception ( int status, const char *pContext, unsigned type, arrayElementCount count ); - static tsFreeList < class putCallback, 1024 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < class putCallback, 1024 > > pFreeList; putCallback ( const putCallback & ); putCallback & operator = ( const putCallback & ); }; @@ -187,8 +193,7 @@ private: unsigned type, arrayElementCount count, const void *pData ); void exception ( int status, const char *pContext, unsigned type, arrayElementCount count ); - static tsFreeList < struct oldSubscription, 1024 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < struct oldSubscription, 1024 > > pFreeList; oldSubscription ( const oldSubscription & ); oldSubscription & operator = ( const oldSubscription & ); }; @@ -379,14 +384,12 @@ inline void oldSubscription::destroy () inline void * oldSubscription::operator new ( size_t size ) { - epicsAutoMutex locker ( oldSubscription::freeListMutex ); - return oldSubscription::freeList.allocate ( size ); + return oldSubscription::pFreeList->allocate ( size ); } inline void oldSubscription::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( oldSubscription::freeListMutex ); - oldSubscription::freeList.release ( pCadaver, size ); + oldSubscription::pFreeList->release ( pCadaver, size ); } inline oldChannelNotify & oldSubscription::channel () const @@ -396,14 +399,12 @@ inline oldChannelNotify & oldSubscription::channel () const inline void * getCopy::operator new ( size_t size ) { - epicsAutoMutex locker ( getCopy::freeListMutex ); - return getCopy::freeList.allocate ( size ); + return getCopy::pFreeList->allocate ( size ); } inline void getCopy::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( getCopy::freeListMutex ); - getCopy::freeList.release ( pCadaver, size ); + getCopy::pFreeList->release ( pCadaver, size ); } inline void putCallback::destroy () @@ -413,14 +414,12 @@ inline void putCallback::destroy () inline void * putCallback::operator new ( size_t size ) { - epicsAutoMutex locker ( putCallback::freeListMutex ); - return putCallback::freeList.allocate ( size ); + return putCallback::pFreeList->allocate ( size ); } inline void putCallback::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( putCallback::freeListMutex ); - putCallback::freeList.release ( pCadaver, size ); + putCallback::pFreeList->release ( pCadaver, size ); } inline void getCallback::destroy () @@ -430,14 +429,12 @@ inline void getCallback::destroy () inline void * getCallback::operator new ( size_t size ) { - epicsAutoMutex locker ( getCallback::freeListMutex ); - return getCallback::freeList.allocate ( size ); + return getCallback::pFreeList->allocate ( size ); } inline void getCallback::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( getCallback::freeListMutex ); - getCallback::freeList.release ( pCadaver, size ); + getCallback::pFreeList->release ( pCadaver, size ); } inline void oldCAC::registerService ( cacService &service ) diff --git a/src/ca/oldCAC.cpp b/src/ca/oldCAC.cpp index eac397f04..7df81b441 100644 --- a/src/ca/oldCAC.cpp +++ b/src/ca/oldCAC.cpp @@ -16,8 +16,8 @@ #include +#define epicsExportSharedSymbols #include "iocinf.h" - #include "oldAccess.h" extern epicsThreadPrivateId caClientContextId; @@ -39,7 +39,7 @@ oldCAC::~oldCAC () void oldCAC::changeExceptionEvent ( caExceptionHandler *pfunc, void *arg ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->ca_exception_func = pfunc; this->ca_exception_arg = arg; // should block here until releated callback in progress completes @@ -47,7 +47,7 @@ void oldCAC::changeExceptionEvent ( caExceptionHandler *pfunc, void *arg ) void oldCAC::replaceErrLogHandler ( caPrintfFunc *ca_printf_func ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); if ( ca_printf_func ) { this->pVPrintfFunc = ca_printf_func; } @@ -59,7 +59,7 @@ void oldCAC::replaceErrLogHandler ( caPrintfFunc *ca_printf_func ) void oldCAC::registerForFileDescriptorCallBack ( CAFDHANDLER *pFunc, void *pArg ) { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); this->fdRegFunc = pFunc; this->fdRegArg = pArg; // should block here until releated callback in progress completes @@ -83,7 +83,7 @@ int oldCAC::vPrintf ( const char *pformat, va_list args ) const // X aCC 361 { caPrintfFunc *pFunc; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pFunc = this->pVPrintfFunc; } if ( pFunc ) { @@ -101,7 +101,7 @@ void oldCAC::exception ( int stat, const char *pCtx, caExceptionHandler *pFunc; void *pArg; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pFunc = this->ca_exception_func; pArg = this->ca_exception_arg; } @@ -133,7 +133,7 @@ void oldCAC::exception ( int status, const char *pContext, caExceptionHandler *pFunc; void *pArg; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pFunc = this->ca_exception_func; pArg = this->ca_exception_arg; } @@ -166,7 +166,7 @@ void oldCAC::fdWasCreated ( int fd ) CAFDHANDLER *pFunc; void *pArg; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pFunc = this->fdRegFunc; pArg = this->fdRegArg; } @@ -180,7 +180,7 @@ void oldCAC::fdWasDestroyed ( int fd ) CAFDHANDLER *pFunc; void *pArg; { - epicsAutoMutex autoMutex ( this->mutex ); + epicsGuard < epicsMutex > autoMutex ( this->mutex ); pFunc = this->fdRegFunc; pArg = this->fdRegArg; } diff --git a/src/ca/oldChannelNotify.cpp b/src/ca/oldChannelNotify.cpp index 9936428c7..33c034f30 100644 --- a/src/ca/oldChannelNotify.cpp +++ b/src/ca/oldChannelNotify.cpp @@ -16,23 +16,12 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "oldAccess.h" #include "cac.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < struct oldChannelNotify, 1024 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < struct oldChannelNotify, 1024 > oldChannelNotify::freeList; -epicsMutex oldChannelNotify::freeListMutex; +epicsSingleton < tsFreeList < struct oldChannelNotify, 1024 > > oldChannelNotify::pFreeList; extern "C" void cacNoopConnHandler ( struct connection_handler_args ) { @@ -144,12 +133,10 @@ bool oldChannelNotify::includeFirstConnectInCountOfOutstandingIO () const void * oldChannelNotify::operator new ( size_t size ) { - epicsAutoMutex locker ( oldChannelNotify::freeListMutex ); - return oldChannelNotify::freeList.allocate ( size ); + return oldChannelNotify::pFreeList->allocate ( size ); } void oldChannelNotify::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( oldChannelNotify::freeListMutex ); - oldChannelNotify::freeList.release ( pCadaver, size ); + oldChannelNotify::pFreeList->release ( pCadaver, size ); } diff --git a/src/ca/oldSubscription.cpp b/src/ca/oldSubscription.cpp index daf854564..8e8a9e0c0 100644 --- a/src/ca/oldSubscription.cpp +++ b/src/ca/oldSubscription.cpp @@ -10,22 +10,11 @@ * Author: Jeff Hill */ +#define epicsExportSharedSymbols #include "iocinf.h" #include "oldAccess.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < struct oldSubscription, 1024 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < struct oldSubscription, 1024 > oldSubscription::freeList; -epicsMutex oldSubscription::freeListMutex; +epicsSingleton < tsFreeList < struct oldSubscription, 1024 > > oldSubscription::pFreeList; oldSubscription::~oldSubscription () { diff --git a/src/ca/putCallback.cpp b/src/ca/putCallback.cpp index 28118d239..77b009a56 100644 --- a/src/ca/putCallback.cpp +++ b/src/ca/putCallback.cpp @@ -15,22 +15,11 @@ * 505 665 1831 */ +#define epicsExportSharedSymbols #include "iocinf.h" #include "oldAccess.h" -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < class putCallback, 1024 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < class putCallback, 1024 > putCallback::freeList; -epicsMutex putCallback::freeListMutex; +epicsSingleton < tsFreeList < class putCallback, 1024 > > putCallback::pFreeList; putCallback::putCallback ( oldChannelNotify &chanIn, caEventCallBackFunc *pFuncIn, void *pPrivateIn ) : diff --git a/src/ca/repeater.cpp b/src/ca/repeater.cpp index 506b63f4f..c8f300f03 100644 --- a/src/ca/repeater.cpp +++ b/src/ca/repeater.cpp @@ -91,8 +91,7 @@ private: osiSockAddr from; SOCKET sock; unsigned short port () const; - static tsFreeList < class repeaterClient, 0x20 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < class repeaterClient, 0x20 > > pFreeList; }; /* @@ -101,19 +100,7 @@ private: */ static tsDLList < repeaterClient > client_list; -#if defined ( _MSC_VER ) -# pragma warning ( push ) -# pragma warning ( disable: 4660 ) -#endif - -template class tsFreeList < repeaterClient, 0x20 >; - -#if defined ( _MSC_VER ) -# pragma warning ( pop ) -#endif - -tsFreeList < repeaterClient, 0x20 > repeaterClient::freeList; -epicsMutex repeaterClient::freeListMutex; +epicsSingleton < tsFreeList < repeaterClient, 0x20 > > repeaterClient::pFreeList; static char buf [MAX_UDP_RECV]; @@ -267,14 +254,12 @@ repeaterClient::~repeaterClient () inline void * repeaterClient::operator new ( size_t size ) { - epicsAutoMutex locker ( repeaterClient::freeListMutex ); - return repeaterClient::freeList.allocate ( size ); + return repeaterClient::pFreeList->allocate ( size ); } inline void repeaterClient::operator delete ( void *pCadaver, size_t size ) { - epicsAutoMutex locker ( repeaterClient::freeListMutex ); - repeaterClient::freeList.release ( pCadaver, size ); + repeaterClient::pFreeList->release ( pCadaver, size ); } inline void repeaterClient::destroy () diff --git a/src/ca/searchTimer.cpp b/src/ca/searchTimer.cpp index 663c10460..a36e4ae03 100644 --- a/src/ca/searchTimer.cpp +++ b/src/ca/searchTimer.cpp @@ -68,7 +68,7 @@ void searchTimer::resetPeriod ( double delayToNextTry ) bool start; { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); // upper bound double newPeriod = this->roundTripDelayEstimate * 2.0; @@ -157,7 +157,7 @@ void searchTimer::notifySearchResponse ( unsigned short retrySeqNoIn, bool reschedualNeeded; { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); if ( this->retrySeqAtPassBegin <= retrySeqNoIn ) { if ( this->searchResponses < UINT_MAX ) { @@ -204,7 +204,7 @@ void searchTimer::notifySearchResponse ( unsigned short retrySeqNoIn, // epicsTimerNotify::expireStatus searchTimer::expire ( const epicsTime & currentTime ) // X aCC 361 { - epicsAutoMutex locker ( this->mutex ); + epicsGuard < epicsMutex > locker ( this->mutex ); unsigned nFrameSent = 0u; unsigned nChanSent = 0u; diff --git a/src/ca/searchTimer.h b/src/ca/searchTimer.h index 2ef6e4e92..6e46c1c1f 100644 --- a/src/ca/searchTimer.h +++ b/src/ca/searchTimer.h @@ -19,13 +19,12 @@ #define searchTimerh #include "epicsTimer.h" -#include "epicsMutex.h" class udpiiu; class searchTimer : private epicsTimerNotify { public: - searchTimer ( udpiiu &, epicsTimerQueue &, epicsMutex & ); + searchTimer ( udpiiu &, epicsTimerQueue &, class epicsMutex & ); virtual ~searchTimer (); void notifySearchResponse ( unsigned short retrySeqNo, const epicsTime & currentTime ); void resetPeriod ( double delayToNextTry ); @@ -34,9 +33,9 @@ private: epicsTime timeAtLastRetry; double period; /* period between tries */ double roundTripDelayEstimate; - epicsTimer &timer; - epicsMutex &mutex; - udpiiu &iiu; + epicsTimer & timer; + class epicsMutex & mutex; + udpiiu & iiu; unsigned framesPerTry; /* # of UDP frames per search try */ unsigned framesPerTryCongestThresh; /* one half N tries w congest */ unsigned minRetry; /* min retry number so far */ diff --git a/src/ca/syncGroup.h b/src/ca/syncGroup.h index 3c22f8c53..a5cb2bf72 100644 --- a/src/ca/syncGroup.h +++ b/src/ca/syncGroup.h @@ -17,15 +17,27 @@ #ifndef syncGrouph #define syncGrouph +#ifdef epicsExportSharedSymbols +#define syncGrouph_restore_epicsExportSharedSymbols +#undef epicsExportSharedSymbols +#endif + +#include "shareLib.h" + #include "tsDLList.h" #include "tsFreeList.h" +#include "epicsSingleton.h" #include "resourceLib.h" #include "epicsEvent.h" +#ifdef syncGrouph_restore_epicsExportSharedSymbols #define epicsExportSharedSymbols +#endif + +#include "shareLib.h" + #include "cadef.h" #include "cacIO.h" -#undef epicsExportSharedSymbols static const unsigned CASG_MAGIC = 0xFAB4CAFE; @@ -58,7 +70,7 @@ protected: class syncGroupReadNotify : public syncGroupNotify, public cacReadNotify { public: static syncGroupReadNotify * factory ( - tsFreeList < class syncGroupReadNotify, 128 > &, + tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &, struct CASG &, chid, void *pValueIn ); void begin ( unsigned type, arrayElementCount count ); void destroy ( casgRecycle & ); @@ -69,10 +81,10 @@ private: void *pValue; syncGroupReadNotify ( struct CASG &sgIn, chid, void *pValueIn ); void * operator new ( size_t, - tsFreeList < class syncGroupReadNotify, 128 > & ); + tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & ); # if ! defined ( NO_PLACEMENT_DELETE ) void operator delete ( void *, size_t, - tsFreeList < class syncGroupReadNotify, 128 > & ); + tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & ); # endif void completion ( unsigned type, arrayElementCount count, const void *pData ); @@ -85,7 +97,7 @@ private: class syncGroupWriteNotify : public syncGroupNotify, public cacWriteNotify { public: static syncGroupWriteNotify * factory ( - tsFreeList < class syncGroupWriteNotify, 128 > &, + tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &, struct CASG &, chid ); void begin ( unsigned type, arrayElementCount count, const void * pValueIn ); @@ -97,10 +109,10 @@ private: void *pValue; syncGroupWriteNotify ( struct CASG &, chid ); void * operator new ( size_t, - tsFreeList < class syncGroupWriteNotify, 128 > & ); + tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & ); # if ! defined ( NO_PLACEMENT_DELETE ) void operator delete ( void *, size_t, - tsFreeList < class syncGroupWriteNotify, 128 > & ); + tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & ); # endif void completion (); void exception ( int status, const char *pContext, @@ -140,12 +152,11 @@ private: epicsEvent sem; oldCAC & client; unsigned magic; - tsFreeList < class syncGroupReadNotify, 128 > freeListReadOP; - tsFreeList < class syncGroupWriteNotify, 128 > freeListWriteOP; + tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > freeListReadOP; + tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > freeListWriteOP; void recycleSyncGroupWriteNotify ( syncGroupWriteNotify &io ); void recycleSyncGroupReadNotify ( syncGroupReadNotify &io ); - static tsFreeList < struct CASG, 128 > freeList; - static epicsMutex freeListMutex; + static epicsSingleton < tsFreeList < struct CASG, 128 > > pFreeList; void destroyPendingIO ( syncGroupNotify * ); void destroyCompletedIO (); diff --git a/src/ca/syncGroupNotify.cpp b/src/ca/syncGroupNotify.cpp index ea754be32..dd7cc9eef 100644 --- a/src/ca/syncGroupNotify.cpp +++ b/src/ca/syncGroupNotify.cpp @@ -30,6 +30,7 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "syncGroup.h" #include "oldAccess.h" diff --git a/src/ca/syncGroupReadNotify.cpp b/src/ca/syncGroupReadNotify.cpp index fdcdda089..4d8d6e46d 100644 --- a/src/ca/syncGroupReadNotify.cpp +++ b/src/ca/syncGroupReadNotify.cpp @@ -30,6 +30,7 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "syncGroup.h" #include "oldAccess.h" @@ -46,7 +47,7 @@ void syncGroupReadNotify::begin ( unsigned type, arrayElementCount count ) } syncGroupReadNotify * syncGroupReadNotify::factory ( - tsFreeList < class syncGroupReadNotify, 128 > &freeList, + tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &freeList, struct CASG &sg, chid chan, void *pValueIn ) { return new ( freeList ) syncGroupReadNotify ( sg, chan, pValueIn); @@ -60,6 +61,9 @@ void syncGroupReadNotify::destroy ( casgRecycle &recycle ) syncGroupReadNotify::~syncGroupReadNotify () { + if ( this->idIsValid ) { + this->chan->ioCancel ( this-> id ); + } } void syncGroupReadNotify::completion ( @@ -99,14 +103,14 @@ void syncGroupReadNotify::show ( unsigned level ) const } void * syncGroupReadNotify::operator new ( size_t size, - tsFreeList < class syncGroupReadNotify, 128 > & freeList ) + tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & freeList ) { return freeList.allocate ( size ); } #if ! defined ( NO_PLACEMENT_DELETE ) void syncGroupReadNotify::operator delete ( void *pCadaver, size_t size, - tsFreeList < class syncGroupReadNotify, 128 > &freeList ) + tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &freeList ) { freeList.release ( pCadaver, size ); } diff --git a/src/ca/syncGroupWriteNotify.cpp b/src/ca/syncGroupWriteNotify.cpp index a7938ca5e..92c721d28 100644 --- a/src/ca/syncGroupWriteNotify.cpp +++ b/src/ca/syncGroupWriteNotify.cpp @@ -30,6 +30,7 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "syncGroup.h" #include "oldAccess.h" @@ -47,7 +48,7 @@ void syncGroupWriteNotify::begin ( unsigned type, } syncGroupWriteNotify * syncGroupWriteNotify::factory ( - tsFreeList < class syncGroupWriteNotify, 128 > &freeList, + tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &freeList, struct CASG &sg, chid chan ) { return new ( freeList ) syncGroupWriteNotify ( sg, chan ); @@ -61,6 +62,9 @@ void syncGroupWriteNotify::destroy ( casgRecycle & recycle ) syncGroupWriteNotify::~syncGroupWriteNotify () { + if ( this->idIsValid ) { + this->chan->ioCancel ( this-> id ); + } } void syncGroupWriteNotify::completion () @@ -94,14 +98,14 @@ void syncGroupWriteNotify::show ( unsigned level ) const } void * syncGroupWriteNotify::operator new ( size_t size, - tsFreeList < class syncGroupWriteNotify, 128 > & freeList ) + tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & freeList ) { return freeList.allocate ( size ); } #if ! defined ( NO_PLACEMENT_DELETE ) void syncGroupWriteNotify::operator delete ( void *pCadaver, size_t size, - tsFreeList < class syncGroupWriteNotify, 128 > &freeList ) + tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &freeList ) { freeList.release ( pCadaver, size ); } diff --git a/src/ca/syncgrp.cpp b/src/ca/syncgrp.cpp index 0a8b5c15f..56622bad9 100644 --- a/src/ca/syncgrp.cpp +++ b/src/ca/syncgrp.cpp @@ -29,10 +29,9 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "iocinf.h" #include "oldAccess.h" - -#define epicsExportSharedSymbols #include "syncGroup.h" /* diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp index 774cefcc6..db81b6a1b 100644 --- a/src/ca/tcpiiu.cpp +++ b/src/ca/tcpiiu.cpp @@ -12,19 +12,16 @@ */ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#define epicsExportSharedSymbols #include "localHostName.h" #include "iocinf.h" #include "virtualCircuit.h" #include "inetAddrID.h" #include "cac.h" #include "netiiu.h" -#include "msgForMultiplyDefinedPV.h" #include "hostNameCache.h" - -#define epicsExportSharedSymbols #include "net_convert.h" #include "bhe.h" -#undef epicsExportSharedSymbols // nill message alignment pad bytes static const char nillBytes [] = @@ -33,67 +30,75 @@ static const char nillBytes [] = 0, 0, 0, 0 }; -// -// cacSendThreadTCP () -// -// care is taken to not hold the lock while sending a message -// -extern "C" void cacSendThreadTCP ( void *pParam ) +tcpSendThread::tcpSendThread ( class tcpiiu & iiuIn, + const char * pName, unsigned stackSize, unsigned priority ) : + iiu ( iiuIn ), thread ( *this, pName, stackSize, priority ) { - tcpiiu *piiu = ( tcpiiu * ) pParam; +} +tcpSendThread::~tcpSendThread () +{ +} + +void tcpSendThread::start () +{ + this->thread.start (); +} + +void tcpSendThread::run () +{ try { while ( true ) { bool flowControlLaborNeeded; bool echoLaborNeeded; - piiu->sendThreadFlushEvent.wait (); + this->iiu.sendThreadFlushEvent.wait (); - if ( piiu->state != iiu_connected ) { + if ( this->iiu.state != iiu_connected ) { break; } { - epicsAutoMutex autoMutex ( piiu->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > autoMutex ( this->iiu.pCAC()->mutexRef() ); flowControlLaborNeeded = - piiu->busyStateDetected != piiu->flowControlActive; - echoLaborNeeded = piiu->echoRequestPending; - piiu->echoRequestPending = false; + this->iiu.busyStateDetected != this->iiu.flowControlActive; + echoLaborNeeded = this->iiu.echoRequestPending; + this->iiu.echoRequestPending = false; } if ( flowControlLaborNeeded ) { - if ( piiu->flowControlActive ) { - piiu->disableFlowControlRequest (); - piiu->flowControlActive = false; + if ( this->iiu.flowControlActive ) { + this->iiu.disableFlowControlRequest (); + this->iiu.flowControlActive = false; debugPrintf ( ( "fc off\n" ) ); } else { - piiu->enableFlowControlRequest (); - piiu->flowControlActive = true; + this->iiu.enableFlowControlRequest (); + this->iiu.flowControlActive = true; debugPrintf ( ( "fc on\n" ) ); } } if ( echoLaborNeeded ) { - if ( CA_V43 ( piiu->minorProtocolVersion ) ) { - piiu->echoRequest (); + if ( CA_V43 ( this->iiu.minorProtocolVersion ) ) { + this->iiu.echoRequest (); } else { - piiu->versionMessage ( piiu->priority() ); + this->iiu.versionMessage ( this->iiu.priority() ); } } - if ( ! piiu->flush () ) { + if ( ! this->iiu.flush () ) { break; } } } catch ( ... ) { - piiu->printf ("cac: tcp send thread received an exception - disconnecting\n"); - piiu->forcedShutdown (); + this->iiu.printf ("cac: tcp send thread received an exception - disconnecting\n"); + this->iiu.forcedShutdown (); } - piiu->sendThreadExitEvent.signal (); + this->iiu.sendThreadExitEvent.signal (); } unsigned tcpiiu::sendBytes ( const void *pBuf, @@ -205,39 +210,40 @@ unsigned tcpiiu::recvBytes ( void *pBuf, unsigned nBytesInBuf ) return static_cast ( status ); } -/* - * cacRecvThreadTCP () - */ -extern "C" void cacRecvThreadTCP ( void *pParam ) +tcpRecvThread::tcpRecvThread ( class tcpiiu & iiuIn, class callbackMutex & cbMutexIn, + const char * pName, unsigned int stackSize, unsigned int priority ) : + thread ( *this, pName, stackSize, priority ), + iiu ( iiuIn ), cbMutex ( cbMutexIn ) {} + +tcpRecvThread::~tcpRecvThread () { - tcpiiu *piiu = ( tcpiiu * ) pParam; +} - piiu->pCAC()->attachToClientCtx (); +void tcpRecvThread::start () +{ + this->thread.start (); +} - epicsThreadPrivateSet ( caClientCallbackThreadId, piiu ); +void tcpRecvThread::run () +{ + this->iiu.pCAC()->attachToClientCtx (); - piiu->connect (); + epicsThreadPrivateSet ( caClientCallbackThreadId, &this->iiu ); - piiu->versionMessage ( piiu->priority() ); + this->iiu.connect (); - if ( piiu->state == iiu_connected ) { - unsigned priorityOfSend = cac::lowestPriorityLevelAbove - ( piiu->pCAC()->getInitializingThreadsPriority() ); - priorityOfSend = cac::lowestPriorityLevelAbove ( priorityOfSend ); - epicsThreadId tid = epicsThreadCreate ( "CAC-TCP-send", priorityOfSend, - epicsThreadGetStackSize ( epicsThreadStackMedium ), cacSendThreadTCP, piiu ); - if ( ! tid ) { - piiu->sendThreadExitEvent.signal (); - piiu->cleanShutdown (); - } + this->iiu.versionMessage ( this->iiu.priority() ); + + if ( this->iiu.state == iiu_connected ) { + this->iiu.sendThread.start (); } else { - piiu->sendThreadExitEvent.signal (); - piiu->cleanShutdown (); + this->iiu.sendThreadExitEvent.signal (); + this->iiu.cleanShutdown (); } comBuf * pComBuf = new ( std::nothrow ) comBuf; - while ( piiu->state == iiu_connected ) { + while ( this->iiu.state == iiu_connected ) { if ( ! pComBuf ) { // no way to be informed when memory is available epicsThreadSleep ( 0.5 ); @@ -253,19 +259,19 @@ extern "C" void cacRecvThreadTCP ( void *pParam ) // appear to impact performance. // unsigned nBytesIn; - if ( piiu->pCAC()->preemptiveCallbakIsEnabled() ) { - nBytesIn = pComBuf->fillFromWire ( *piiu ); + if ( this->iiu.pCAC()->preemptiveCallbakIsEnabled() ) { + nBytesIn = pComBuf->fillFromWire ( this->iiu ); if ( nBytesIn == 0u ) { break; } } else { char buf; - ::recv ( piiu->sock, &buf, 1, MSG_PEEK ); + ::recv ( this->iiu.sock, &buf, 1, MSG_PEEK ); nBytesIn = 0u; // make gnu hoppy } - if ( piiu->state != iiu_connected ) { + if ( this->iiu.state != iiu_connected ) { break; } @@ -274,15 +280,15 @@ extern "C" void cacRecvThreadTCP ( void *pParam ) // because cancel is blocking for the completion // of the recvDog expire which takes the lock // - it take also the callback lock - piiu->recvDog.messageArrivalNotify (); + this->iiu.recvDog.messageArrivalNotify (); // only one recv thread at a time may call callbacks // - pendEvent() blocks until threads waiting for // this lock get a chance to run - callbackAutoMutex cbLocker ( *piiu->pCAC() ); + epicsGuard < callbackMutex > guard ( this->cbMutex ); - if ( ! piiu->pCAC()->preemptiveCallbakIsEnabled() ) { - nBytesIn = pComBuf->fillFromWire ( *piiu ); + if ( ! this->iiu.pCAC()->preemptiveCallbakIsEnabled() ) { + nBytesIn = pComBuf->fillFromWire ( this->iiu ); if ( nBytesIn == 0u ) { // outer loop checks to see if state is connected // ( properly set by fillFromWire() ) @@ -295,27 +301,27 @@ extern "C" void cacRecvThreadTCP ( void *pParam ) while ( contiguousFrameCount++ < 50 ) { if ( nBytesIn == pComBuf->capacityBytes () ) { - if ( piiu->contigRecvMsgCount >= + if ( this->iiu.contigRecvMsgCount >= contiguousMsgCountWhichTriggersFlowControl ) { - piiu->busyStateDetected = true; + this->iiu.busyStateDetected = true; } else { - piiu->contigRecvMsgCount++; + this->iiu.contigRecvMsgCount++; } } else { - piiu->contigRecvMsgCount = 0u; - piiu->busyStateDetected = false; + this->iiu.contigRecvMsgCount = 0u; + this->iiu.busyStateDetected = false; } - piiu->unacknowledgedSendBytes = 0u; + this->iiu.unacknowledgedSendBytes = 0u; - piiu->recvQue.pushLastComBufReceived ( *pComBuf ); + this->iiu.recvQue.pushLastComBufReceived ( *pComBuf ); pComBuf = 0; // execute receive labor - bool noProtocolViolation = piiu->processIncoming ( cbLocker ); + bool noProtocolViolation = this->iiu.processIncoming ( guard ); if ( ! noProtocolViolation ) { - piiu->state = iiu_disconnected; + this->iiu.state = iiu_disconnected; break; } @@ -329,12 +335,12 @@ extern "C" void cacRecvThreadTCP ( void *pParam ) { int status; osiSockIoctl_t bytesPending = 0; - status = socket_ioctl ( piiu->sock, // X aCC 392 + status = socket_ioctl ( this->iiu.sock, // X aCC 392 FIONREAD, & bytesPending ); if ( status || bytesPending == 0u ) { break; } - nBytesIn = pComBuf->fillFromWire ( *piiu ); + nBytesIn = pComBuf->fillFromWire ( this->iiu ); if ( nBytesIn == 0u ) { // outer loop checks to see if state is connected // ( properly set by fillFromWire() ) @@ -348,22 +354,32 @@ extern "C" void cacRecvThreadTCP ( void *pParam ) pComBuf->destroy (); } - piiu->stopThreads (); + this->iiu.stopThreads (); - piiu->pCAC()->uninstallIIU ( *piiu ); + // arrange for delete through the timer thread + this->iiu.killTimer.start (); } // // tcpiiu::tcpiiu () // -tcpiiu::tcpiiu ( cac & cac, double connectionTimeout, +tcpiiu::tcpiiu ( cac & cac, callbackMutex & cbMutex, double connectionTimeout, epicsTimerQueue & timerQueue, const osiSockAddr & addrIn, unsigned minorVersion, ipAddrToAsciiEngine & engineIn, const cacChannel::priLev & priorityIn ) : - netiiu ( &cac ), + netiiu ( & cac ), caServerID ( addrIn.ia, priorityIn ), + recvThread ( *this, cbMutex, "CAC-TCP-recv", + epicsThreadGetStackSize ( epicsThreadStackBig ), + cac::highestPriorityLevelBelow ( cac.getInitializingThreadsPriority() ) ), + sendThread ( *this, "CAC-TCP-send", + epicsThreadGetStackSize ( epicsThreadStackMedium ), + cac::lowestPriorityLevelAbove ( + cac::lowestPriorityLevelAbove ( + this->pCAC()->getInitializingThreadsPriority() ) ) ), recvDog ( *this, connectionTimeout, timerQueue ), sendDog ( *this, connectionTimeout, timerQueue ), + killTimer ( cac, *this, timerQueue ), sendQue ( *this ), curDataMax ( MAX_TCP ), curDataBytes ( 0ul ), @@ -468,25 +484,10 @@ tcpiiu::tcpiiu ( cac & cac, double connectionTimeout, // this must always be called by the udp thread when it holds // the callback lock. -bool tcpiiu::start ( callbackAutoMutex & cbGuard ) +void tcpiiu::start ( epicsGuard < callbackMutex > & cbGuard ) { - // this is done here after we release the priamry - // lock so that we will hold the callback lock but - // not the primary lock when the fd is registered - // with the user + this->recvThread.start (); this->pCAC()->notifyNewFD ( cbGuard, this->sock ); - - unsigned priorityOfRecv = cac::highestPriorityLevelBelow - ( this->pCAC()->getInitializingThreadsPriority() ); - - epicsThreadId tid = epicsThreadCreate ( "CAC-TCP-recv", priorityOfRecv, - epicsThreadGetStackSize ( epicsThreadStackBig ), - cacRecvThreadTCP, this ); - if ( tid == 0 ) { - this->printf ("CA: unable to create CA client receive thread\n"); - return false; - } - return true; } /* @@ -507,7 +508,7 @@ void tcpiiu::connect () this->sendDog.cancel (); - epicsAutoMutex autoMutex ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > autoMutex ( this->pCAC()->mutexRef() ); if ( this->state == iiu_connecting ) { // put the iiu into the connected state @@ -559,7 +560,7 @@ void tcpiiu::forcedShutdown () // caller must hold callback mutex and also primary cac mutex // when calling this routine // -void tcpiiu::shutdown ( class callbackAutoMutex & cbLocker, bool discardPendingMessages ) +void tcpiiu::shutdown ( epicsGuard < callbackMutex > & cbLocker, bool discardPendingMessages ) { if ( ! this->sockCloseCompleted ) { this->pCAC()->notifyDestroyFD ( cbLocker, this->sock ); @@ -671,50 +672,9 @@ tcpiiu::~tcpiiu () } } -bool tcpiiu::isVirtualCircuit ( const char *pChannelName, const osiSockAddr &addrIn ) const -{ - osiSockAddr addrTmp = this->address (); - - if ( addrTmp.sa.sa_family == AF_UNSPEC ) { - return false; - } - - bool match; - - if ( addrTmp.sa.sa_family != addrIn.sa.sa_family ) { - match = false; - } - else if ( addrTmp.sa.sa_family != AF_INET ) { - match = false; - } - else if ( addrTmp.ia.sin_addr.s_addr != addrIn.ia.sin_addr.s_addr ) { - match = false; - } - else if ( addrTmp.ia.sin_port != addrIn.ia.sin_port ) { - match = false; - } - else { - match = true; - } - - if ( ! match ) { - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); - char acc[64]; - this->pHostNameCache->hostName ( acc, sizeof ( acc ) ); - assert ( this->pCAC () ); - msgForMultiplyDefinedPV *pMsg = new msgForMultiplyDefinedPV ( - *this->pCAC (), pChannelName, acc, addrIn ); - if ( pMsg ) { - this->pCAC ()->ipAddrToAsciiAsynchronousRequestInstall ( *pMsg ); - } - } - - return true; -} - void tcpiiu::show ( unsigned level ) const { - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > locker ( this->pCAC()->mutexRef() ); char buf[256]; this->pHostNameCache->hostName ( buf, sizeof ( buf ) ); ::printf ( "Virtual circuit to \"%s\" at version V%u.%u state %u\n", @@ -743,7 +703,7 @@ void tcpiiu::show ( unsigned level ) const bool tcpiiu::setEchoRequestPending () // X aCC 361 { { - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > locker ( this->pCAC()->mutexRef() ); this->echoRequestPending = true; } this->flushRequest (); @@ -760,7 +720,7 @@ bool tcpiiu::setEchoRequestPending () // X aCC 361 // // tcpiiu::processIncoming() // -bool tcpiiu::processIncoming ( callbackAutoMutex & cbLocker ) +bool tcpiiu::processIncoming ( epicsGuard < callbackMutex > & guard ) { while ( true ) { @@ -835,7 +795,7 @@ bool tcpiiu::processIncoming ( callbackAutoMutex & cbLocker ) return true; } } - bool msgOK = this->pCAC()->executeResponse ( cbLocker, *this, + bool msgOK = this->pCAC()->executeResponse ( guard, *this, this->curMsg, this->pCurData ); if ( ! msgOK ) { return false; @@ -911,7 +871,7 @@ void tcpiiu::hostNameSetRequest () this->flushRequest (); } - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > locker ( this->pCAC()->mutexRef() ); this->sendQue.beginMsg (); this->sendQue.pushUInt16 ( CA_PROTO_HOST_NAME ); // cmd @@ -943,7 +903,7 @@ void tcpiiu::userNameSetRequest () this->flushRequest (); } - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > locker ( this->pCAC()->mutexRef() ); this->sendQue.beginMsg (); this->sendQue.pushUInt16 ( CA_PROTO_CLIENT_NAME ); // cmd this->sendQue.pushUInt16 ( static_cast ( postSize ) ); // postsize @@ -962,7 +922,7 @@ void tcpiiu::disableFlowControlRequest () this->flushRequest (); } - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > locker ( this->pCAC()->mutexRef() ); this->sendQue.beginMsg (); this->sendQue.pushUInt16 ( CA_PROTO_EVENTS_ON ); // cmd this->sendQue.pushUInt16 ( 0u ); // postsize @@ -979,7 +939,7 @@ void tcpiiu::enableFlowControlRequest () this->flushRequest (); } - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > locker ( this->pCAC()->mutexRef() ); this->sendQue.beginMsg (); this->sendQue.pushUInt16 ( CA_PROTO_EVENTS_OFF ); // cmd this->sendQue.pushUInt16 ( 0u ); // postsize @@ -998,7 +958,7 @@ void tcpiiu::versionMessage ( const cacChannel::priLev & priority ) this->flushRequest (); } - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > locker ( this->pCAC()->mutexRef() ); this->sendQue.beginMsg (); this->sendQue.pushUInt16 ( CA_PROTO_VERSION ); // cmd this->sendQue.pushUInt16 ( 0u ); // postsize ( old possize field ) @@ -1015,7 +975,7 @@ void tcpiiu::echoRequest () this->flushRequest (); } - epicsAutoMutex locker ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > locker ( this->pCAC()->mutexRef() ); this->sendQue.beginMsg (); this->sendQue.pushUInt16 ( CA_PROTO_ECHO ); // cmd this->sendQue.pushUInt16 ( 0u ); // postsize @@ -1243,7 +1203,7 @@ void tcpiiu::subscriptionCancelRequest ( nciu & chan, netSubscription & subscr ) // caller must hold both the callback mutex and // also the cac primary mutex // -void tcpiiu::lastChannelDetachNotify ( class callbackAutoMutex & cbLocker ) +void tcpiiu::lastChannelDetachNotify ( epicsGuard < callbackMutex > & cbLocker ) { this->shutdown ( cbLocker, false ); } @@ -1254,7 +1214,7 @@ bool tcpiiu::flush () comBuf * pBuf; { - epicsAutoMutex autoMutex ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > autoMutex ( this->pCAC()->mutexRef() ); pBuf = this->sendQue.popNextComBufToSend (); if ( pBuf ) { this->unacknowledgedSendBytes += pBuf->occupiedBytes (); @@ -1284,7 +1244,7 @@ bool tcpiiu::flush () pBuf->destroy (); if ( ! success ) { - epicsAutoMutex autoMutex ( this->pCAC()->mutexRef() ); + epicsGuard < epicsMutex > autoMutex ( this->pCAC()->mutexRef() ); while ( ( pBuf = this->sendQue.popNextComBufToSend () ) ) { pBuf->destroy (); } @@ -1294,19 +1254,19 @@ bool tcpiiu::flush () return false; } } - return false; // to make compiler happy... + return false; // happy compiler } // ~tcpiiu() will not return while this->blockingForFlush is greater than zero void tcpiiu::blockUntilSendBacklogIsReasonable ( - epicsAutoMutex *pCallbackLocker, epicsAutoMutex & primaryLocker ) + epicsGuard < callbackMutex > *pCallbackLocker, epicsGuard < epicsMutex > & primaryLocker ) { assert ( this->blockingForFlush < UINT_MAX ); this->blockingForFlush++; while ( this->sendQue.flushBlockThreshold(0u) && this->state == iiu_connected ) { - epicsAutoMutexRelease autoRelease ( primaryLocker ); + epicsGuardRelease < epicsMutex > autoRelease ( primaryLocker ); if ( pCallbackLocker ) { - epicsAutoMutexRelease autoReleaseCallback ( *pCallbackLocker ); + epicsGuardRelease < callbackMutex > autoReleaseCallback ( *pCallbackLocker ); this->flushBlockEvent.wait (); } else { @@ -1362,7 +1322,3 @@ const char * tcpiiu::pHostName () const return nameBuf; // ouch !! } - - - - diff --git a/src/ca/udpiiu.cpp b/src/ca/udpiiu.cpp index fb8ee2648..64c4d8c6e 100644 --- a/src/ca/udpiiu.cpp +++ b/src/ca/udpiiu.cpp @@ -52,8 +52,14 @@ const udpiiu::pProtoStubUDP udpiiu::udpJumpTableCAC [] = // // udpiiu::udpiiu () // -udpiiu::udpiiu ( callbackAutoMutex &cbLocker, cac & cac ) : - netiiu ( &cac ), shutdownCmd ( false ), +udpiiu::udpiiu ( callbackMutex & cbMutex, cac & cac ) : + netiiu ( &cac ), + recvThread ( *this, cbMutex, + "CAC-UDP", + epicsThreadGetStackSize ( epicsThreadStackMedium ), + cac::lowestPriorityLevelAbove + ( this->pCAC()->getInitializingThreadsPriority () ) ), + shutdownCmd ( false ), sockCloseCompleted ( false ) { static const unsigned short PORT_ANY = 0u; @@ -157,23 +163,13 @@ udpiiu::udpiiu ( callbackAutoMutex &cbLocker, cac & cac ) : genLocalExcep ( *this->pCAC (), ECA_NOSEARCHADDR, NULL ); } - { - unsigned priorityOfRecv = cac::lowestPriorityLevelAbove - ( this->pCAC ()->getInitializingThreadsPriority() ); - - this->recvThreadId = epicsThreadCreate ( "CAC-UDP", priorityOfRecv, - epicsThreadGetStackSize (epicsThreadStackMedium), cacRecvThreadUDP, this ); - if ( this->recvThreadId == 0 ) { - this->printf ("CA: unable to create UDP receive thread\n"); - epicsEventDestroy (this->recvThreadExitSignal); - socket_close (this->sock); - throw std::bad_alloc (); - } - } - caStartRepeaterIfNotInstalled ( this->repeaterPort ); +} - this->pCAC ()->notifyNewFD ( cbLocker, this->sock ); +void udpiiu::start ( epicsGuard < callbackMutex > & cbGuard ) +{ + this->recvThread.start (); + this->pCAC()->notifyNewFD ( cbGuard, this->sock ); } /* @@ -196,7 +192,7 @@ udpiiu::~udpiiu () // // udpiiu::recvMsg () // -void udpiiu::recvMsg () +void udpiiu::recvMsg ( callbackMutex & cbMutex ) { osiSockAddr src; int status; @@ -217,7 +213,7 @@ void udpiiu::recvMsg () } { - callbackAutoMutex autoMutex ( *this->pCAC() ); + epicsGuard < callbackMutex > guard ( cbMutex ); if ( ! this->pCAC()->preemptiveCallbakIsEnabled() ) { osiSocklen_t src_size = sizeof ( src ); @@ -257,24 +253,34 @@ void udpiiu::recvMsg () SOCKERRSTR (errnoCpy) ); } else if ( status > 0 ) { - this->postMsg ( autoMutex, src, this->recvBuf, + this->postMsg ( guard, src, this->recvBuf, (arrayElementCount) status, epicsTime::getCurrent() ); } } return; } -/* - * cacRecvThreadUDP () - */ -extern "C" void cacRecvThreadUDP ( void *pParam ) +udpRecvThread::udpRecvThread ( udpiiu & iiuIn, callbackMutex & cbMutexIn, + const char * pName, unsigned stackSize, unsigned priority ) : + iiu ( iiuIn ), cbMutex ( cbMutexIn ), + thread ( *this, pName, stackSize, priority ) {} + +udpRecvThread::~udpRecvThread () { - udpiiu *piiu = (udpiiu *) pParam; - epicsThreadPrivateSet ( caClientCallbackThreadId, pParam ); +} + +void udpRecvThread::start () +{ + this->thread.start (); +} + +void udpRecvThread::run () +{ + epicsThreadPrivateSet ( caClientCallbackThreadId, &this->iiu ); do { - piiu->recvMsg (); - } while ( ! piiu->shutdownCmd ); - epicsEventSignal ( piiu->recvThreadExitSignal ); + this->iiu.recvMsg ( this->cbMutex ); + } while ( ! this->iiu.shutdownCmd ); + epicsEventSignal ( this->iiu.recvThreadExitSignal ); } /* @@ -492,7 +498,7 @@ void udpiiu::shutdown () epicsEventMustWait ( this->recvThreadExitSignal ); } -bool udpiiu::badUDPRespAction ( callbackAutoMutex &, const caHdr &msg, +bool udpiiu::badUDPRespAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &netAddr, const epicsTime ¤tTime ) { char buf[64]; @@ -504,13 +510,13 @@ bool udpiiu::badUDPRespAction ( callbackAutoMutex &, const caHdr &msg, return false; } -bool udpiiu::noopAction ( callbackAutoMutex &, +bool udpiiu::noopAction ( epicsGuard < callbackMutex > &, const caHdr &, const osiSockAddr &, const epicsTime & ) { return true; } -bool udpiiu::searchRespAction ( callbackAutoMutex & cbLocker, +bool udpiiu::searchRespAction ( epicsGuard < callbackMutex > & cbLocker, const caHdr &msg, // X aCC 361 const osiSockAddr &addr, const epicsTime ¤tTime ) { @@ -574,7 +580,7 @@ bool udpiiu::searchRespAction ( callbackAutoMutex & cbLocker, } } -bool udpiiu::beaconAction ( callbackAutoMutex &, const caHdr &msg, +bool udpiiu::beaconAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime ¤tTime ) { struct sockaddr_in ina; @@ -618,20 +624,20 @@ bool udpiiu::beaconAction ( callbackAutoMutex &, const caHdr &msg, return true; } -bool udpiiu::repeaterAckAction ( callbackAutoMutex &, const caHdr &, +bool udpiiu::repeaterAckAction ( epicsGuard < callbackMutex > &, const caHdr &, const osiSockAddr &, const epicsTime &) { this->pCAC ()->repeaterSubscribeConfirmNotify (); return true; } -bool udpiiu::notHereRespAction ( callbackAutoMutex &, const caHdr &, +bool udpiiu::notHereRespAction ( epicsGuard < callbackMutex > &, const caHdr &, const osiSockAddr &, const epicsTime & ) { return true; } -bool udpiiu::exceptionRespAction ( callbackAutoMutex &, const caHdr &msg, +bool udpiiu::exceptionRespAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime ¤tTime ) { const caHdr &reqMsg = * ( &msg + 1 ); @@ -653,7 +659,7 @@ bool udpiiu::exceptionRespAction ( callbackAutoMutex &, const caHdr &msg, return true; } -void udpiiu::postMsg ( callbackAutoMutex & cbLocker, +void udpiiu::postMsg ( epicsGuard < callbackMutex > & guard, const osiSockAddr & net_addr, char * pInBuf, arrayElementCount blockSize, const epicsTime & currentTime ) @@ -717,7 +723,7 @@ void udpiiu::postMsg ( callbackAutoMutex & cbLocker, else { pStub = &udpiiu::badUDPRespAction; } - bool success = ( this->*pStub ) ( cbLocker, *pCurMsg, net_addr, currentTime ); + bool success = ( this->*pStub ) ( guard, *pCurMsg, net_addr, currentTime ); if ( ! success ) { char buf[256]; sockAddrToDottedIP ( &net_addr.sa, buf, sizeof ( buf ) ); diff --git a/src/ca/udpiiu.h b/src/ca/udpiiu.h index 05187d7ed..5d244b6ef 100644 --- a/src/ca/udpiiu.h +++ b/src/ca/udpiiu.h @@ -23,6 +23,8 @@ # undef epicsExportSharedSymbols #endif +#include "shareLib.h" + # include "osiSock.h" # include "epicsThread.h" @@ -30,6 +32,8 @@ # define epicsExportSharedSymbols #endif +#include "shareLib.h" + #include "netiiu.h" extern "C" void cacRecvThreadUDP ( void *pParam ); @@ -40,16 +44,33 @@ extern "C" epicsShareFunc void caRepeaterThread ( void *pDummy ); epicsShareFunc void ca_repeater ( void ); class epicsTime; +class callbackMutex; + +class udpRecvThread : + public epicsThreadRunable { +public: + udpRecvThread ( class udpiiu & iiuIn, callbackMutex & cbMutexIn, + const char * pName, unsigned stackSize, unsigned priority ); + virtual ~udpRecvThread (); + void start (); +private: + class udpiiu & iiu; + callbackMutex & cbMutex; + epicsThread thread; + void run(); +}; class udpiiu : public netiiu { public: - udpiiu ( callbackAutoMutex &, class cac & ); + udpiiu ( callbackMutex &, class cac & ); + void start ( epicsGuard < callbackMutex > & ); virtual ~udpiiu (); void shutdown (); - void recvMsg (); - void postMsg ( callbackAutoMutex &, const osiSockAddr & net_addr, - char *pInBuf, arrayElementCount blockSize, - const epicsTime ¤Time ); + void recvMsg ( callbackMutex & ); + void postMsg ( epicsGuard < callbackMutex > &, + const osiSockAddr & net_addr, + char *pInBuf, arrayElementCount blockSize, + const epicsTime ¤Time ); void repeaterRegistrationMessage ( unsigned attemptNumber ); void datagramFlush (); unsigned getPort () const; @@ -63,8 +84,8 @@ public: private: char xmitBuf [MAX_UDP_SEND]; char recvBuf [MAX_UDP_RECV]; + udpRecvThread recvThread; ELLLIST dest; - epicsThreadId recvThreadId; epicsEventId recvThreadExitSignal; unsigned nBytesInXmitBuf; SOCKET sock; @@ -77,39 +98,34 @@ private: bool pushDatagramMsg ( const caHdr &msg, const void *pExt, ca_uint16_t extsize ); typedef bool ( udpiiu::*pProtoStubUDP ) ( - callbackAutoMutex &, const caHdr &, + epicsGuard < callbackMutex > &, const caHdr &, const osiSockAddr &, const epicsTime & ); // UDP protocol dispatch table static const pProtoStubUDP udpJumpTableCAC[]; // UDP protocol stubs - bool noopAction ( callbackAutoMutex &, const caHdr &, + bool noopAction ( epicsGuard < callbackMutex > &, const caHdr &, const osiSockAddr &, const epicsTime & ); - bool badUDPRespAction ( callbackAutoMutex &, const caHdr &msg, + bool badUDPRespAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &netAddr, const epicsTime & ); - bool searchRespAction ( callbackAutoMutex &, const caHdr &msg, + bool searchRespAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool exceptionRespAction ( callbackAutoMutex &, const caHdr &msg, + bool exceptionRespAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool beaconAction ( callbackAutoMutex &, const caHdr &msg, + bool beaconAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool notHereRespAction ( callbackAutoMutex &, const caHdr &msg, + bool notHereRespAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - bool repeaterAckAction ( callbackAutoMutex &, const caHdr &msg, + bool repeaterAckAction ( epicsGuard < callbackMutex > &, const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); - friend void cacRecvThreadUDP ( void *pParam ); + friend void udpRecvThread::run (); udpiiu ( const udpiiu & ); udpiiu & operator = ( const udpiiu & ); }; -inline bool udpiiu::isCurrentThread () const -{ - return ( this->recvThreadId == epicsThreadGetIdSelf () ); -} - inline unsigned udpiiu::getPort () const { return this->localPort;