From 4359938ed6fd4a10e42f7919ec3096bb1745a0eb Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Wed, 6 Aug 2003 17:42:55 +0000 Subject: [PATCH] added virtual circuit free list and fixed race condition in virtual circuit shutdown sequence --- src/ca/cac.cpp | 19 +++++++++++++++---- src/ca/cac.h | 5 ++++- src/ca/tcpiiu.cpp | 23 ++++++++++++++++------- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index 6e92d2a37..17863ed46 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -43,6 +43,7 @@ #include "bhe.h" #include "net_convert.h" #include "autoPtrDestroy.h" +#include "autoPtrFreeList.h" static const char *pVersionCAC = "@(#) " EPICS_VERSION_STRING @@ -269,10 +270,15 @@ cac::~cac () // this will block for oustanding sends to go out so dont // hold a lock while waiting // - while ( this->serverList.count() ) { - this->iiuUninstall.wait (); + { + epicsGuard < cacMutex > guard ( this->mutex ); + while ( this->serverList.count() ) { + epicsGuardRelease < cacMutex > unguard ( guard ); + this->iiuUninstall.wait (); + } } + if ( this->pudpiiu ) { delete this->pudpiiu; } @@ -566,7 +572,9 @@ bool cac::transferChanToVirtCircuit ( } else { try { - epics_auto_ptr < tcpiiu > pnewiiu ( new tcpiiu ( + autoPtrFreeList < tcpiiu, 32, epicsMutexNOOP > pnewiiu ( + this->freeListVirtualCircuit, + new ( this->freeListVirtualCircuit ) tcpiiu ( *this, this->cbMutex, this->connTMO, this->timerQueue, addr, this->comBufMemMgr, minorVersionNumber, this->ipToAEngine, pChan->getPriority() ) ); @@ -1528,8 +1536,9 @@ void cac::initiateAbortShutdown ( tcpiiu & iiu ) iiu.removeAllChannels ( cbGuard, guard, *this ); } -void cac::uninstallIIU ( epicsGuard < callbackMutex > & cbGuard, tcpiiu & iiu ) +void cac::destroyIIU ( tcpiiu & iiu ) { + epicsGuard < callbackMutex > cbGuard ( this->cbMutex ); epicsGuard < cacMutex > guard ( this->mutex ); if ( iiu.channelCount() ) { char hostNameTmp[64]; @@ -1550,6 +1559,8 @@ void cac::uninstallIIU ( epicsGuard < callbackMutex > & cbGuard, tcpiiu & iiu ) this->serverTable.remove ( iiu ); this->serverList.remove ( iiu ); + iiu.~tcpiiu (); + this->freeListVirtualCircuit.release ( & iiu ); // signal iiu uninstal event so that cac can properly shut down this->iiuUninstall.signal(); diff --git a/src/ca/cac.h b/src/ca/cac.h index c622ee9c4..4823a2184 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -189,7 +189,7 @@ public: static unsigned highestPriorityLevelBelow ( unsigned priority ); void initiateAbortShutdown ( tcpiiu & ); void disconnectNotify ( tcpiiu & ); - void uninstallIIU ( epicsGuard < callbackMutex > &, tcpiiu & iiu ); + void destroyIIU ( tcpiiu & iiu ); private: localHostName hostNameCache; @@ -213,6 +213,9 @@ private: resTable < bhe, inetAddrID > beaconTable; resTable < tcpiiu, caServerID > serverTable; tsDLList < tcpiiu > serverList; + tsFreeList + < class tcpiiu, 32, epicsMutexNOOP > + freeListVirtualCircuit; tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > freeListReadNotifyIO; diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp index 01471691a..0a9083f49 100644 --- a/src/ca/tcpiiu.cpp +++ b/src/ca/tcpiiu.cpp @@ -151,15 +151,9 @@ void tcpSendThread::run () } this->iiu.recvThread.exitWait (); - this->thread.exitWaitRelease (); - { - epicsGuard < callbackMutex > guard ( this->cbMutex ); - this->iiu.cacRef.uninstallIIU ( guard, this->iiu ); - } - - delete & this->iiu; + this->iiu.cacRef.destroyIIU ( this->iiu ); } unsigned tcpiiu::sendBytes ( const void *pBuf, @@ -1488,4 +1482,19 @@ void tcpSendThread::interruptSocketSend () } } +void tcpiiu::operator delete ( void * pCadaver ) +{ + // Visual C++ .net appears to require operator delete if + // placement operator delete is defined? I smell a ms rat + // because if I declare placement new and delete, but + // comment out the placement delete definition there are + // no undefined symbols. + errlogPrintf ( "%s:%d this compiler is confused about " + "placement delete - memory was probably leaked", + __FILE__, __LINE__ ); +} + + + +