From 77669d793dcad02ce4815105e2e628ff462aed1f Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Wed, 11 Feb 2009 00:50:28 +0000 Subject: [PATCH] fixed situations where local host name cache is repatedly created and destroyed --- src/ca/cac.cpp | 1 + src/ca/cac.h | 10 ++++++++- src/ca/cacChannel.cpp | 48 +++++++++++++++++++++++++++++++++++----- src/ca/cacIO.h | 1 - src/ca/localHostName.cpp | 2 +- src/ca/localHostName.h | 2 +- src/ca/tcpiiu.cpp | 6 ++--- src/ca/virtualCircuit.h | 1 - 8 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index ad83de174..802e5767b 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -126,6 +126,7 @@ cac::cac ( epicsMutex & mutualExclusionIn, epicsMutex & callbackControlIn, cacContextNotify & notifyIn ) : + _refLocalHostName ( localHostNameCache.getReference () ), programBeginTime ( epicsTime::getCurrent() ), connTMO ( CA_CONN_VERIFY_PERIOD ), mutex ( mutualExclusionIn ), diff --git a/src/ca/cac.h b/src/ca/cac.h index ed46fc242..9bb389015 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -36,6 +36,7 @@ #include "epicsTimer.h" #include "epicsEvent.h" #include "freeList.h" +#include "localHostName.h" #ifdef cach_restore_epicsExportSharedSymbols # define epicsExportSharedSymbols @@ -212,8 +213,10 @@ public: static unsigned highestPriorityLevelBelow ( unsigned priority ); void destroyIIU ( tcpiiu & iiu ); + const char * pLocalHostName (); + private: - localHostName hostNameCache; + epicsSingleton < localHostName > :: reference _refLocalHostName; chronIntIdResTable < nciu > chanTable; // // !!!! There is at this point no good reason @@ -434,5 +437,10 @@ inline nciu * cac::lookupChannel ( return this->chanTable.lookup ( idIn ); } +inline const char * cac :: pLocalHostName () +{ + return _refLocalHostName->pointer (); +} + #endif // ifdef cach diff --git a/src/ca/cacChannel.cpp b/src/ca/cacChannel.cpp index 284c54187..c1a52a002 100644 --- a/src/ca/cacChannel.cpp +++ b/src/ca/cacChannel.cpp @@ -32,6 +32,18 @@ #include "localHostName.h" #include "cacIO.h" +class CACChannelPrivate { +public: + CACChannelPrivate (); + unsigned getHostName ( char * pBuf, unsigned bufLength ); + const char * pHostName (); +private: + epicsSingleton < localHostName > :: reference + _refLocalHostName; +}; + +static epicsThreadOnceId cacChannelIdOnce = EPICS_THREAD_ONCE_INIT; + const cacChannel::priLev cacChannel::priorityMax = 99u; const cacChannel::priLev cacChannel::priorityMin = 0u; const cacChannel::priLev cacChannel::priorityDefault = priorityMin; @@ -80,15 +92,40 @@ bool cacChannel::connected ( return true; } +CACChannelPrivate :: + CACChannelPrivate() : + _refLocalHostName ( localHostNameCache.getReference () ) +{ +} + +inline unsigned CACChannelPrivate :: + getHostName ( char * pBuf, unsigned bufLength ) +{ + return _refLocalHostName->getName ( pBuf, bufLength ); +} + +inline const char * CACChannelPrivate :: + pHostName () +{ + return _refLocalHostName->pointer (); +} + +static CACChannelPrivate * pCACChannelPrivate = 0; + +// runs once only for each process +extern "C" void cacChannelSetup ( void * ) +{ + pCACChannelPrivate = new CACChannelPrivate (); +} + // the default is to assume that it is a locally hosted channel unsigned cacChannel::getHostName ( epicsGuard < epicsMutex > &, char * pBuf, unsigned bufLength ) const throw () { if ( bufLength ) { - epicsSingleton < localHostName >::reference - ref ( localHostNameAtLoadTime.getReference () ); - return ref->getName ( pBuf, bufLength ); + epicsThreadOnce ( & cacChannelIdOnce, cacChannelSetup, 0); + return pCACChannelPrivate->getHostName ( pBuf, bufLength ); } return 0u; } @@ -97,9 +134,8 @@ unsigned cacChannel::getHostName ( const char * cacChannel::pHostName ( epicsGuard < epicsMutex > & ) const throw () { - epicsSingleton < localHostName >::reference - ref ( localHostNameAtLoadTime.getReference () ); - return ref->pointer (); + epicsThreadOnce ( & cacChannelIdOnce, cacChannelSetup, 0); + return pCACChannelPrivate->pHostName (); } cacContext::~cacContext () {} diff --git a/src/ca/cacIO.h b/src/ca/cacIO.h index 9ea926a92..8086f1239 100644 --- a/src/ca/cacIO.h +++ b/src/ca/cacIO.h @@ -56,7 +56,6 @@ #include "epicsMutex.h" #include "epicsGuard.h" #include "epicsThread.h" -#include "epicsSingleton.h" #ifdef cacIOh_restore_epicsExportSharedSymbols # define epicsExportSharedSymbols diff --git a/src/ca/localHostName.cpp b/src/ca/localHostName.cpp index 5c2e3d6d8..b0b96bb47 100644 --- a/src/ca/localHostName.cpp +++ b/src/ca/localHostName.cpp @@ -23,7 +23,7 @@ #include "localHostName.h" -epicsSingleton < localHostName > localHostNameAtLoadTime; +epicsSingleton < localHostName > localHostNameCache; localHostName::localHostName () : attachedToSockLib ( osiSockAttach () != 0 ), length ( 0u ) diff --git a/src/ca/localHostName.h b/src/ca/localHostName.h index d608dbef9..f116b8140 100644 --- a/src/ca/localHostName.h +++ b/src/ca/localHostName.h @@ -48,7 +48,7 @@ private: char cache [128]; }; -extern epicsSingleton < localHostName > localHostNameAtLoadTime; +extern epicsSingleton < localHostName > localHostNameCache; inline unsigned localHostName::nameLength () const { diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp index bc023d857..4d8d8e787 100644 --- a/src/ca/tcpiiu.cpp +++ b/src/ca/tcpiiu.cpp @@ -1259,10 +1259,8 @@ void tcpiiu::hostNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 4 if ( ! CA_V41 ( this->minorProtocolVersion ) ) { return; } - - epicsSingleton < localHostName >::reference - ref ( localHostNameAtLoadTime.getReference () ); - const char * pName = ref->pointer (); + + const char * pName = this->cacRef.pLocalHostName (); unsigned size = strlen ( pName ) + 1u; unsigned postSize = CA_MESSAGE_ALIGN ( size ); assert ( postSize < 0xffff ); diff --git a/src/ca/virtualCircuit.h b/src/ca/virtualCircuit.h index b7cfbb3d1..b103c4a0c 100644 --- a/src/ca/virtualCircuit.h +++ b/src/ca/virtualCircuit.h @@ -51,7 +51,6 @@ struct caHdrLargeArray { ca_uint16_t m_cmmd; // operation to be performed }; -class hostNameCache; class ipAddrToAsciiEngine; class tcpRecvThread : private epicsThreadRunable {