epicsAutoMutex has a new name, fixed free lists, and use c++ thread class,

and fixed dll symbol exports
This commit is contained in:
Jeff Hill
2002-03-21 23:10:06 +00:00
parent e625e5dc5f
commit 28ef90cb1b
38 changed files with 617 additions and 852 deletions

View File

@@ -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, ... )

View File

@@ -28,6 +28,7 @@
*/
#define CAC_VERSION_GLOBAL
#define epicsExportSharedSymbols
#include "iocinf.h"
#include "oldAccess.h"
#include "autoPtrDestroy.h"

View File

@@ -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 ()

View File

@@ -14,7 +14,6 @@
#ifndef bheh
#define bheh
#include "shareLib.h"
#include <limits.h>
#include <float.h>
@@ -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 & );
};

View File

@@ -15,10 +15,13 @@
#include <new>
#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 <const void *> ( 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 &notifyIn )
{
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 &notifyIn )
{
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<baseNMIU> 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 &notifyIn )
{
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 ();

View File

@@ -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 <callbackMutex> * 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

View File

@@ -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 )
{

View File

@@ -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

View File

@@ -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 )

View File

@@ -86,6 +86,8 @@ of this distribution.
# undef epicsExportSharedSymbols
#endif
#include "shareLib.h"
#include "epicsTypes.h"
#include "epicsTime.h"

View File

@@ -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 ) :

View File

@@ -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 ) :

View File

@@ -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 );
}

View File

@@ -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

View File

@@ -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 );
}

View File

@@ -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

View File

@@ -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 ) );

View File

@@ -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 )

View File

@@ -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 &notify );
void show ( unsigned level ) const;
@@ -79,10 +79,10 @@ private:
unsigned mask, cacStateNotify &notify );
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 &notify );
void show ( unsigned level ) const;
void destroy ( class cacRecycle & );
@@ -107,10 +107,10 @@ private:
cacReadNotify &notify;
netReadNotifyIO ( nciu &chan, cacReadNotify &notify );
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 &notify );
void show ( unsigned level ) const;
void destroy ( class cacRecycle & );
@@ -135,10 +135,10 @@ private:
cacWriteNotify &notify;
netWriteNotifyIO ( nciu &chan, cacWriteNotify &notify );
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 &notify )
{
@@ -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 &notify )
{
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 &notify )
{
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 );
}

View File

@@ -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,

View File

@@ -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 > & )
{
}

View File

@@ -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 ) {

View File

@@ -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 )

View File

@@ -16,8 +16,8 @@
#include <stdio.h>
#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;
}

View File

@@ -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 );
}

View File

@@ -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 ()
{

View File

@@ -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 ) :

View File

@@ -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 ()

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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 ();

View File

@@ -30,6 +30,7 @@
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#define epicsExportSharedSymbols
#include "iocinf.h"
#include "syncGroup.h"
#include "oldAccess.h"

View File

@@ -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 );
}

View File

@@ -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 );
}

View File

@@ -29,10 +29,9 @@
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#define epicsExportSharedSymbols
#include "iocinf.h"
#include "oldAccess.h"
#define epicsExportSharedSymbols
#include "syncGroup.h"
/*

View File

@@ -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 <unsigned> ( 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 <epicsUInt16> ( 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 !!
}

View File

@@ -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 &currentTime )
{
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 &currentTime )
{
@@ -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 &currentTime )
{
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 &currentTime )
{
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 ) );

View File

@@ -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 &currenTime );
void recvMsg ( callbackMutex & );
void postMsg ( epicsGuard < callbackMutex > &,
const osiSockAddr & net_addr,
char *pInBuf, arrayElementCount blockSize,
const epicsTime &currenTime );
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;