added virtual circuit free list and fixed race condition in virtual circuit shutdown sequence

This commit is contained in:
Jeff Hill
2003-08-06 17:42:55 +00:00
parent 1fb594833b
commit 4359938ed6
3 changed files with 35 additions and 12 deletions

View File

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

View File

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

View File

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