imprved fix for mantis 316

This commit is contained in:
Jeff Hill
2008-09-26 22:12:15 +00:00
parent 37f4457c03
commit 32616ba5fa

View File

@@ -82,7 +82,7 @@ template class tsFreeList
extern "C" {
static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * );
static void ipAddrToAsciiEngineGlobalMutexDestruct ( void * );
static void ipAddrToAsciiEngineShutdownRequest ( void * );
}
// - this class executes the synchronous DNS query
@@ -111,6 +111,7 @@ private:
static epicsMutex * pGlobalMutex;
static ipAddrToAsciiEnginePrivate * pEngine;
static unsigned numberOfReferences;
static bool shutdownRequest;
ipAddrToAsciiTransaction & createTransaction ();
void release ();
void run ();
@@ -118,13 +119,14 @@ private:
ipAddrToAsciiEnginePrivate & operator = ( const ipAddrToAsciiEngine & );
friend class ipAddrToAsciiEngine;
friend class ipAddrToAsciiTransactionPrivate;
friend void ipAddrToAsciiEngineGlobalMutexDestruct ( void * );
friend void ipAddrToAsciiEngineShutdownRequest ( void * );
friend void ipAddrToAsciiEngineGlobalMutexConstruct ( void * );
};
epicsMutex * ipAddrToAsciiEnginePrivate :: pGlobalMutex = 0;
ipAddrToAsciiEnginePrivate * ipAddrToAsciiEnginePrivate :: pEngine = 0;
unsigned ipAddrToAsciiEnginePrivate :: numberOfReferences = 0u;
bool ipAddrToAsciiEnginePrivate :: shutdownRequest = false;
static epicsThreadOnceId ipAddrToAsciiEngineGlobalMutexOnceFlag = 0;
// the users are not required to supply a show routine
@@ -136,15 +138,19 @@ ipAddrToAsciiCallBack::~ipAddrToAsciiCallBack () {}
ipAddrToAsciiTransaction::~ipAddrToAsciiTransaction () {}
ipAddrToAsciiEngine::~ipAddrToAsciiEngine () {}
static void ipAddrToAsciiEngineGlobalMutexDestruct ( void * )
static void ipAddrToAsciiEngineShutdownRequest ( void * )
{
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
epicsGuard < epicsMutex > guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
ipAddrToAsciiEnginePrivate :: shutdownRequest = true;
if ( ipAddrToAsciiEnginePrivate::numberOfReferences == 0u ) {
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
}
}
static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * )
{
ipAddrToAsciiEnginePrivate :: pGlobalMutex = new epicsMutex ();
epicsAtExit ( ipAddrToAsciiEngineGlobalMutexDestruct, 0 );
epicsAtExit ( ipAddrToAsciiEngineShutdownRequest, 0 );
}
// for now its probably sufficent to allocate one
@@ -156,6 +162,16 @@ ipAddrToAsciiEngine & ipAddrToAsciiEngine::allocate ()
epicsThreadOnce (
& ipAddrToAsciiEngineGlobalMutexOnceFlag,
ipAddrToAsciiEngineGlobalMutexConstruct, 0 );
// since we must not own lock when checking this flag
// this diagnostic has imperfect detection, but never
// incorrect detection
if ( ipAddrToAsciiEnginePrivate :: shutdownRequest ) {
throw std :: runtime_error (
"ipAddrToAsciiEngine::allocate (): "
"attempts to create an "
"ipAddrToAsciiEngine while the exit "
"handlers are running are rejected");
}
epicsGuard < epicsMutex > guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
if ( ! ipAddrToAsciiEnginePrivate::pEngine ) {
ipAddrToAsciiEnginePrivate::pEngine = new ipAddrToAsciiEnginePrivate ();
@@ -190,15 +206,24 @@ ipAddrToAsciiEnginePrivate::~ipAddrToAsciiEnginePrivate ()
// leave our options open for the future
void ipAddrToAsciiEnginePrivate::release ()
{
bool deleteGlobalMutexCondDetected = false;
epicsThreadOnce (
& ipAddrToAsciiEngineGlobalMutexOnceFlag,
ipAddrToAsciiEngineGlobalMutexConstruct, 0 );
epicsGuard < epicsMutex > guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
assert ( ipAddrToAsciiEnginePrivate::numberOfReferences > 0u );
ipAddrToAsciiEnginePrivate::numberOfReferences--;
if ( ipAddrToAsciiEnginePrivate::numberOfReferences == 0u ) {
delete ipAddrToAsciiEnginePrivate::pEngine;
ipAddrToAsciiEnginePrivate::pEngine = 0;
{
epicsGuard < epicsMutex >
guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
assert ( ipAddrToAsciiEnginePrivate::numberOfReferences > 0u );
ipAddrToAsciiEnginePrivate::numberOfReferences--;
if ( ipAddrToAsciiEnginePrivate::numberOfReferences == 0u ) {
delete ipAddrToAsciiEnginePrivate::pEngine;
ipAddrToAsciiEnginePrivate::pEngine = 0;
deleteGlobalMutexCondDetected =
ipAddrToAsciiEnginePrivate::shutdownRequest;
}
}
if ( deleteGlobalMutexCondDetected ) {
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
}
}