diff --git a/src/cas/build/Makefile b/src/cas/build/Makefile index e71bb8a34..bdde7fcda 100644 --- a/src/cas/build/Makefile +++ b/src/cas/build/Makefile @@ -60,6 +60,7 @@ LIBSRCS += pvAttachReturn.cc LIBSRCS += caNetAddr.cc LIBSRCS += beaconTimer.cc LIBSRCS += beaconAnomalyGovernor.cc +LIBSRCS += clientBufMemoryManager.cpp LIBSRCS += caServerOS.cc LIBSRCS += casIntfOS.cc diff --git a/src/cas/generic/caServerI.cc b/src/cas/generic/caServerI.cc index 256b2d467..92094af11 100644 --- a/src/cas/generic/caServerI.cc +++ b/src/cas/generic/caServerI.cc @@ -15,6 +15,8 @@ * 505 665 1831 */ +#include + #include "epicsGuard.h" #include "epicsVersion.h" @@ -108,7 +110,7 @@ void caServerI::removeClient (casStrmClient *pClient) // void caServerI::connectCB ( casIntfOS & intf ) { - casStreamOS * pClient = intf.newStreamClient ( *this ); + casStreamOS * pClient = intf.newStreamClient ( *this, this->clientBufMemMgr ); if ( pClient ) { pClient->sendVersion (); pClient->flush (); @@ -142,19 +144,15 @@ void serverToolDebugFunc (const char *pFile, unsigned line, const char *pComment // // caServerI::attachInterface() // -caStatus caServerI::attachInterface (const caNetAddr &addr, bool autoBeaconAddr, - bool addConfigBeaconAddr) -{ - casIntfOS *pIntf; - - pIntf = new casIntfOS (*this, addr, autoBeaconAddr, addConfigBeaconAddr); - if (pIntf==NULL) { - return S_cas_noMemory; - } +caStatus caServerI::attachInterface ( const caNetAddr & addrIn, + bool autoBeaconAddr, bool addConfigBeaconAddr) +{ + casIntfOS * pIntf = new casIntfOS ( *this, this->clientBufMemMgr, + addrIn, autoBeaconAddr, addConfigBeaconAddr ); { epicsGuard < epicsMutex > locker ( this->mutex ); - this->intfList.add (*pIntf); + this->intfList.add ( *pIntf ); } return S_cas_success; diff --git a/src/cas/generic/casBufferFactory.cpp b/src/cas/generic/casBufferFactory.cpp index 4b8f0ff69..f64c4b754 100644 --- a/src/cas/generic/casBufferFactory.cpp +++ b/src/cas/generic/casBufferFactory.cpp @@ -22,8 +22,6 @@ #include "server.h" -epicsSingleton < casBufferFactory > pGlobalBufferFactoryCAS; - casBufferFactory::casBufferFactory () : smallBufFreeList ( 0 ), largeBufFreeList ( 0 ), largeBufferSizePriv ( 0u ) { diff --git a/src/cas/generic/casClient.cc b/src/cas/generic/casClient.cc index 6582472c1..e452be303 100644 --- a/src/cas/generic/casClient.cc +++ b/src/cas/generic/casClient.cc @@ -37,9 +37,13 @@ casClient::pCASMsgHandler casClient::msgHandlers[CA_PROTO_LAST_CMMD+1u]; // // casClient::casClient() // -casClient::casClient ( caServerI &serverInternal, bufSizeT ioSizeMinIn ) : - casCoreClient ( serverInternal ), in ( *this, ioSizeMinIn ), out ( *this ), - minor_version_number ( 0 ), incommingBytesToDrain ( 0 ) +casClient::casClient ( caServerI & serverInternal, + clientBufMemoryManager & mgrIn, bufSizeT ioSizeMinIn ) : + casCoreClient ( serverInternal ), + in ( *this, mgrIn, ioSizeMinIn ), + out ( *this, mgrIn ), + minor_version_number ( 0 ), + incommingBytesToDrain ( 0 ) { // // static member init diff --git a/src/cas/generic/casDGClient.cc b/src/cas/generic/casDGClient.cc index 448c65bb9..083a9e246 100644 --- a/src/cas/generic/casDGClient.cc +++ b/src/cas/generic/casDGClient.cc @@ -31,8 +31,8 @@ // // casDGClient::casDGClient() // -casDGClient::casDGClient ( caServerI & serverIn ) : - casClient ( serverIn, MAX_UDP_RECV + sizeof ( cadg ) ), +casDGClient::casDGClient ( caServerI & serverIn, clientBufMemoryManager & mgrIn ) : + casClient ( serverIn, mgrIn, MAX_UDP_RECV + sizeof ( cadg ) ), seqNoOfReq ( 0 ) { } diff --git a/src/cas/generic/casStrmClient.cc b/src/cas/generic/casStrmClient.cc index 3d7bb9a29..e809be057 100644 --- a/src/cas/generic/casStrmClient.cc +++ b/src/cas/generic/casStrmClient.cc @@ -29,13 +29,13 @@ typedef unsigned long arrayElementCount; #include "inBufIL.h" // inBuf inline functions #include "outBufIL.h" // outBuf inline functions -static const caHdr nill_msg = {0u,0u,0u,0u,0u,0u}; +static const caHdr nill_msg = { 0u,0u,0u,0u,0u,0u }; // // casStrmClient::casStrmClient() // -casStrmClient::casStrmClient ( caServerI &serverInternal ) : - casClient ( serverInternal, 1 ) +casStrmClient::casStrmClient ( caServerI & cas, clientBufMemoryManager & memMgr ) : + casClient ( cas, memMgr, 1 ) { this->pHostName = new char [1u]; *this->pHostName = '\0'; @@ -1973,3 +1973,5 @@ void casStrmClient::flush () this->out.flush (); } + + diff --git a/src/cas/generic/clientBufMemoryManager.cpp b/src/cas/generic/clientBufMemoryManager.cpp new file mode 100644 index 000000000..4b39ca94a --- /dev/null +++ b/src/cas/generic/clientBufMemoryManager.cpp @@ -0,0 +1,56 @@ + +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * $Id$ + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + */ + +#include "server.h" + +bufSizeT clientBufMemoryManager::maxSize () const +{ + return bufferFactory.largeBufferSize (); +} + +casBufferParm clientBufMemoryManager::allocate ( bufSizeT newMinSize ) +{ + casBufferParm parm; + if ( newMinSize <= bufferFactory.smallBufferSize () ) { + parm.pBuf = bufferFactory.newSmallBuffer (); + parm.bufSize = bufferFactory.smallBufferSize (); + } + else if ( newMinSize <= bufferFactory.largeBufferSize () ) { + parm.pBuf = bufferFactory.newLargeBuffer (); + parm.bufSize = bufferFactory.largeBufferSize (); + } + else { + parm.pBuf = static_cast < char * > ( ::operator new ( newMinSize ) ); + parm.bufSize = newMinSize; + } + return parm; +} + +void clientBufMemoryManager::release ( char * pBuf, bufSizeT bufSize ) +{ + if ( bufSize == bufferFactory.smallBufferSize () ) { + bufferFactory.destroySmallBuffer ( pBuf ); + } + else if ( bufSize == bufferFactory.largeBufferSize () ) { + bufferFactory.destroyLargeBuffer ( pBuf ); + } + else { + ::operator delete ( pBuf ); + } +} + diff --git a/src/cas/generic/inBuf.cc b/src/cas/generic/inBuf.cc index 0c6e12e29..83f8b3b2e 100644 --- a/src/cas/generic/inBuf.cc +++ b/src/cas/generic/inBuf.cc @@ -21,21 +21,18 @@ // // inBuf::inBuf() // -inBuf::inBuf ( inBufClient &clientIn, bufSizeT ioMinSizeIn ) : - client ( clientIn ), pBuf ( 0 ), bufSize ( 0u ), bytesInBuffer ( 0u ), nextReadIndex ( 0u ), - ioMinSize ( ioMinSizeIn ), ctxRecursCount ( 0u ) +inBuf::inBuf ( inBufClient & clientIn, clientBufMemoryManager & memMgrIn, + bufSizeT ioMinSizeIn ) : + client ( clientIn ), memMgr ( memMgrIn ), pBuf ( 0 ), + bufSize ( 0u ), bytesInBuffer ( 0u ), nextReadIndex ( 0u ), + ioMinSize ( ioMinSizeIn ), ctxRecursCount ( 0u ) { if ( this->ioMinSize == 0 ) { this->ioMinSize = 1; } - if ( this->ioMinSize <= pGlobalBufferFactoryCAS->smallBufferSize () ) { - this->pBuf = pGlobalBufferFactoryCAS->newSmallBuffer (); - this->bufSize = pGlobalBufferFactoryCAS->smallBufferSize (); - } - else { - this->pBuf = new char [ this->ioMinSize ]; - this->bufSize = this->ioMinSize; - } + casBufferParm bufParm = this->memMgr.allocate ( this->ioMinSize ); + this->pBuf = bufParm.pBuf; + this->bufSize = bufParm.bufSize; } // @@ -45,15 +42,7 @@ inBuf::inBuf ( inBufClient &clientIn, bufSizeT ioMinSizeIn ) : inBuf::~inBuf () { assert ( this->ctxRecursCount == 0 ); - if ( this->bufSize == pGlobalBufferFactoryCAS->smallBufferSize () ) { - pGlobalBufferFactoryCAS->destroySmallBuffer ( this->pBuf ); - } - else if ( this->bufSize == pGlobalBufferFactoryCAS->largeBufferSize () ) { - pGlobalBufferFactoryCAS->destroyLargeBuffer ( this->pBuf ); - } - else { - delete [] this->pBuf; - } + this->memMgr.release ( this->pBuf, this->bufSize ); } // @@ -61,8 +50,8 @@ inBuf::~inBuf () // void inBuf::show (unsigned level) const { - if (level>1u) { - printf( + if ( level > 1u ) { + printf ( "\tUnprocessed request bytes = %d\n", this->bytesAvailable()); } @@ -167,13 +156,14 @@ bufSizeT inBuf::popCtx ( const inBufCtx &ctx ) // X aCC 361 void inBuf::expandBuffer () { - if ( this->bufSize < pGlobalBufferFactoryCAS->largeBufferSize () ) { - char * pNewBuf = pGlobalBufferFactoryCAS->newLargeBuffer (); - memcpy ( pNewBuf, &this->pBuf[this->nextReadIndex], this->bytesPresent () ); + bufSizeT max = this->memMgr.maxSize(); + if ( this->bufSize < max ) { + casBufferParm bufParm = this->memMgr.allocate ( max ); + memcpy ( bufParm.pBuf, &this->pBuf[this->nextReadIndex], this->bytesPresent () ); this->nextReadIndex = 0u; - pGlobalBufferFactoryCAS->destroySmallBuffer ( this->pBuf ); - this->pBuf = pNewBuf; - this->bufSize = pGlobalBufferFactoryCAS->largeBufferSize (); + this->memMgr.release ( this->pBuf, this->bufSize ); + this->pBuf = bufParm.pBuf; + this->bufSize = bufParm.bufSize; } } diff --git a/src/cas/generic/outBuf.cc b/src/cas/generic/outBuf.cc index be1b7eb21..7507541cd 100644 --- a/src/cas/generic/outBuf.cc +++ b/src/cas/generic/outBuf.cc @@ -22,11 +22,14 @@ // // outBuf::outBuf() // -outBuf::outBuf ( outBufClient & clientIn ) : - client ( clientIn ), bufSize ( 0 ), stack ( 0u ), ctxRecursCount ( 0u ) +outBuf::outBuf ( outBufClient & clientIn, + clientBufMemoryManager & memMgrIn ) : + client ( clientIn ), memMgr ( memMgrIn ), bufSize ( 0 ), + stack ( 0u ), ctxRecursCount ( 0u ) { - this->pBuf = pGlobalBufferFactoryCAS->newSmallBuffer (); - this->bufSize = pGlobalBufferFactoryCAS->smallBufferSize (); + casBufferParm bufParm = memMgr.allocate ( 1 ); + this->pBuf = bufParm.pBuf; + this->bufSize = bufParm.bufSize; memset ( this->pBuf, '\0', this->bufSize ); } @@ -36,17 +39,7 @@ outBuf::outBuf ( outBufClient & clientIn ) : outBuf::~outBuf() { assert ( this->ctxRecursCount == 0 ); - if ( this->bufSize == pGlobalBufferFactoryCAS->smallBufferSize () ) { - pGlobalBufferFactoryCAS->destroySmallBuffer ( this->pBuf ); - } - else if ( this->bufSize == pGlobalBufferFactoryCAS->largeBufferSize () ) { - pGlobalBufferFactoryCAS->destroyLargeBuffer ( this->pBuf ); - } - else if ( this->pBuf ) { - errlogPrintf ( - "cas: unusual outBuf buffer size %u in destructor - probable leak\n", - this->bufSize ); - } + memMgr.release ( this->pBuf, this->bufSize ); } // @@ -324,12 +317,13 @@ void outBuf::show (unsigned level) const void outBuf::expandBuffer () { - if ( this->bufSize < pGlobalBufferFactoryCAS->largeBufferSize () ) { - char * pNewBuf = pGlobalBufferFactoryCAS->newLargeBuffer (); - memcpy ( pNewBuf, this->pBuf, this->stack ); - pGlobalBufferFactoryCAS->destroySmallBuffer ( this->pBuf ); - this->pBuf = pNewBuf; - this->bufSize = pGlobalBufferFactoryCAS->largeBufferSize (); + bufSizeT max = this->memMgr.maxSize(); + if ( this->bufSize < max ) { + casBufferParm bufParm = this->memMgr.allocate ( max ); + memcpy ( bufParm.pBuf, this->pBuf, this->stack ); + this->memMgr.release ( this->pBuf, this->bufSize ); + this->pBuf = bufParm.pBuf; + this->bufSize = bufParm.bufSize; } } diff --git a/src/cas/generic/server.h b/src/cas/generic/server.h index 68fcdfc19..24a0ac02f 100644 --- a/src/cas/generic/server.h +++ b/src/cas/generic/server.h @@ -42,7 +42,6 @@ #include "errMdef.h" // EPICS error codes #include "resourceLib.h" // EPICS hashing templates #include "errlog.h" // EPICS error logging interface -#include "epicsSingleton.h" // // CA @@ -246,7 +245,19 @@ private: unsigned largeBufferSizePriv; }; -extern epicsSingleton < casBufferFactory > pGlobalBufferFactoryCAS; +struct casBufferParm { + char * pBuf; + bufSizeT bufSize; +}; + +class clientBufMemoryManager { +public: + casBufferParm allocate ( bufSizeT newMinSize ); + void release ( char * pBuf, bufSizeT bufSize ); + bufSizeT maxSize () const; +private: + casBufferFactory bufferFactory; +}; class inBufClient { // X aCC 655 public: @@ -268,7 +279,8 @@ class inBuf { friend class inBufCtx; public: - inBuf ( inBufClient &, bufSizeT ioMinSizeIn ); + inBuf ( inBufClient &, clientBufMemoryManager &, + bufSizeT ioMinSizeIn ); virtual ~inBuf (); bufSizeT bytesPresent () const; @@ -310,6 +322,7 @@ public: private: epicsMutex mutex; inBufClient & client; + clientBufMemoryManager & memMgr; char * pBuf; bufSizeT bufSize; bufSizeT bytesInBuffer; @@ -356,7 +369,7 @@ class outBuf { friend class outBufCtx; public: - outBuf ( outBufClient & ); + outBuf ( outBufClient &, clientBufMemoryManager & ); virtual ~outBuf (); bufSizeT bytesPresent () const; @@ -403,12 +416,13 @@ public: void clear (); private: - mutable epicsMutex mutex; - outBufClient & client; - char * pBuf; - bufSizeT bufSize; - bufSizeT stack; - unsigned ctxRecursCount; + mutable epicsMutex mutex; + outBufClient & client; + clientBufMemoryManager & memMgr; + char * pBuf; + bufSizeT bufSize; + bufSizeT stack; + unsigned ctxRecursCount; void expandBuffer (); @@ -495,7 +509,7 @@ class casClient : public casCoreClient, public outBufClient, public inBufClient { public: - casClient ( caServerI &, bufSizeT ioMinSizeIn ); + casClient ( caServerI &, clientBufMemoryManager &, bufSizeT ioMinSizeIn ); virtual ~casClient (); virtual void show ( unsigned level ) const; @@ -583,7 +597,7 @@ private: class casStrmClient : public casClient, public tsDLNode { public: - casStrmClient (caServerI &cas); + casStrmClient ( caServerI &, clientBufMemoryManager & ); virtual ~casStrmClient(); void show (unsigned level) const; @@ -714,7 +728,7 @@ class casDGIntfIO; // class casDGClient : public casClient { public: - casDGClient (caServerI &serverIn); + casDGClient ( caServerI &serverIn, clientBufMemoryManager & ); virtual ~casDGClient(); virtual void show (unsigned level) const; @@ -923,6 +937,7 @@ public: void generateBeaconAnomaly (); private: + clientBufMemoryManager clientBufMemMgr; mutable epicsMutex mutex; tsDLList clientList; tsDLList intfList; diff --git a/src/cas/generic/st/casDGIntfOS.cc b/src/cas/generic/st/casDGIntfOS.cc index c8a0189eb..cdf2c07f0 100644 --- a/src/cas/generic/st/casDGIntfOS.cc +++ b/src/cas/generic/st/casDGIntfOS.cc @@ -78,13 +78,16 @@ private: // // casDGIntfOS::casDGIntfOS() // -casDGIntfOS::casDGIntfOS (caServerI &serverIn, const caNetAddr &addr, - bool autoBeaconAddr, bool addConfigBeaconAddr) : - casDGIntfIO (serverIn, addr, autoBeaconAddr, addConfigBeaconAddr), +casDGIntfOS::casDGIntfOS ( + caServerI & serverIn, clientBufMemoryManager & memMgrIn, + const caNetAddr & addr, bool autoBeaconAddr, + bool addConfigBeaconAddr) : + casDGIntfIO (serverIn, memMgrIn, addr, + autoBeaconAddr, addConfigBeaconAddr), pRdReg ( 0 ), pBCastRdReg ( 0 ), pWtReg ( 0 ), - sendBlocked (false) + sendBlocked ( false ) { this->xSetNonBlocking(); this->armRecv(); diff --git a/src/cas/generic/st/casIntfOS.cc b/src/cas/generic/st/casIntfOS.cc index 9f0362043..916c1ea58 100644 --- a/src/cas/generic/st/casIntfOS.cc +++ b/src/cas/generic/st/casIntfOS.cc @@ -40,11 +40,12 @@ private: // // casIntfOS::casIntfOS() // -casIntfOS::casIntfOS (caServerI &casIn, const caNetAddr &addrIn, - bool autoBeaconAddr, bool addConfigBeaconAddr) : - casIntfIO (addrIn), - casDGIntfOS (casIn, addrIn, autoBeaconAddr, addConfigBeaconAddr), - cas (casIn) +casIntfOS::casIntfOS ( caServerI & casIn, clientBufMemoryManager & memMgrIn, + const caNetAddr & addrIn, bool autoBeaconAddr, bool addConfigBeaconAddr ) : + casIntfIO ( addrIn ), + casDGIntfOS ( casIn, memMgrIn, addrIn, autoBeaconAddr, + addConfigBeaconAddr ), + cas ( casIn ) { this->setNonBlocking(); @@ -95,3 +96,5 @@ caNetAddr casIntfOS::serverAddress () const return this->casIntfIO::serverAddress(); } + + diff --git a/src/cas/generic/st/casOSD.h b/src/cas/generic/st/casOSD.h index 27371ad69..0d3b5f2a2 100644 --- a/src/cas/generic/st/casOSD.h +++ b/src/cas/generic/st/casOSD.h @@ -90,8 +90,9 @@ class casDGIntfOS : public casDGIntfIO { friend class casDGBCastReadReg; friend class casDGWriteReg; public: - casDGIntfOS (caServerI &serverIn, const caNetAddr &addr, - bool autoBeaconAddr=TRUE, bool addConfigBeaconAddr=FALSE); + casDGIntfOS ( caServerI &, clientBufMemoryManager &, + const caNetAddr & addr, bool autoBeaconAddr = true, + bool addConfigBeaconAddr = false); virtual ~casDGIntfOS (); @@ -135,17 +136,14 @@ class casIntfOS : public casIntfIO, public tsDLNode, { friend class casServerReg; public: - casIntfOS (caServerI &casIn, const caNetAddr &addr, - bool autoBeaconAddr=true, bool addConfigBeaconAddr=false); + casIntfOS ( caServerI &, clientBufMemoryManager &, const caNetAddr &, + bool autoBeaconAddr = true, bool addConfigBeaconAddr = false ); virtual ~casIntfOS(); - - virtual void show (unsigned level) const; - + void show ( unsigned level ) const; caNetAddr serverAddress () const; - private: - caServerI &cas; - casServerReg *pRdReg; + caServerI & cas; + casServerReg * pRdReg; casIntfOS ( const casIntfOS & ); casIntfOS & operator = ( const casIntfOS & ); @@ -192,22 +190,21 @@ private: // casStreamOS // class casStreamOS : public casStreamIO { - friend class casStreamWriteReg; - friend class casStreamReadReg; public: - casStreamOS (caServerI &, const ioArgsToNewStreamIO &ioArgs); + casStreamOS ( caServerI &, clientBufMemoryManager &, + const ioArgsToNewStreamIO & ); ~casStreamOS (); - void show (unsigned level) const; + void show ( unsigned level ) const; casProcCond processInput (); private: - casStreamEvWakeup evWk; - casStreamIOWakeup ioWk; - casStreamWriteReg *pWtReg; - casStreamReadReg *pRdReg; - bool sendBlocked; + casStreamEvWakeup evWk; + casStreamIOWakeup ioWk; + casStreamWriteReg * pWtReg; + casStreamReadReg * pRdReg; + bool sendBlocked; // // // @@ -228,6 +225,9 @@ private: casStreamOS ( const casStreamOS & ); casStreamOS & operator = ( const casStreamOS & ); + + friend class casStreamWriteReg; + friend class casStreamReadReg; }; // no additions below this line diff --git a/src/cas/generic/st/casStreamOS.cc b/src/cas/generic/st/casStreamOS.cc index 2b1727390..3fee5461c 100644 --- a/src/cas/generic/st/casStreamOS.cc +++ b/src/cas/generic/st/casStreamOS.cc @@ -146,7 +146,7 @@ void casStreamEvWakeup::show(unsigned level) const // // casStreamEvWakeup::expire() // -epicsTimerNotify::expireStatus casStreamEvWakeup::expire( const epicsTime & /* currentTime */ ) +epicsTimerNotify::expireStatus casStreamEvWakeup::expire ( const epicsTime & /* currentTime */ ) { casStreamOS &os = *this->pOS; this->pOS = 0; @@ -327,11 +327,10 @@ void casStreamOS::eventFlush() // // casStreamOS::casStreamOS() // -casStreamOS::casStreamOS(caServerI &cas, const ioArgsToNewStreamIO &ioArgs) : - casStreamIO (cas, ioArgs), - pWtReg (NULL), - pRdReg (NULL), - sendBlocked (FALSE) +casStreamOS::casStreamOS ( caServerI & cas, clientBufMemoryManager & bufMgrIn, + const ioArgsToNewStreamIO & ioArgs ) : + casStreamIO ( cas, bufMgrIn, ioArgs ), + pWtReg ( 0 ), pRdReg ( 0 ), sendBlocked ( false ) { this->xSetNonBlocking(); this->armRecv(); diff --git a/src/cas/io/bsdSocket/caServerIO.cc b/src/cas/io/bsdSocket/caServerIO.cc index b5e793387..807c55d82 100644 --- a/src/cas/io/bsdSocket/caServerIO.cc +++ b/src/cas/io/bsdSocket/caServerIO.cc @@ -16,8 +16,9 @@ #include +#include "epicsSignal.h" + #include "server.h" -#include "osiSigPipeIgnore.h" static char *getToken (const char **ppString, char *pBuf, unsigned bufSIze); @@ -142,11 +143,11 @@ caServerIO::~caServerIO() // inline void caServerIO::staticInit() { - if (caServerIO::staticInitialized) { + if ( caServerIO::staticInitialized ) { return; } - installSigPipeIgnore(); + epicsSignalInstallSigPipeIgnore (); caServerIO::staticInitialized = TRUE; } diff --git a/src/cas/io/bsdSocket/casDGIntfIO.cc b/src/cas/io/bsdSocket/casDGIntfIO.cc index 79ea27f54..c9480d6c0 100644 --- a/src/cas/io/bsdSocket/casDGIntfIO.cc +++ b/src/cas/io/bsdSocket/casDGIntfIO.cc @@ -43,15 +43,15 @@ static void forcePort (ELLLIST *pList, unsigned short port) // // casDGIntfIO::casDGIntfIO() // -casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr, - bool autoBeaconAddr, bool addConfigBeaconAddr) : - casDGClient (serverIn) +casDGIntfIO::casDGIntfIO ( caServerI & serverIn, clientBufMemoryManager & memMgr, + const caNetAddr & addr, bool autoBeaconAddr, bool addConfigBeaconAddr ) : + casDGClient ( serverIn, memMgr ) { ELLLIST BCastAddrList; osiSockAddr serverAddr; osiSockAddr serverBCastAddr; - int status; unsigned short beaconPort; + int status; ellInit ( &BCastAddrList ); ellInit ( &this->beaconAddrList ); @@ -177,7 +177,8 @@ casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr, assert ( offsetof (osiSockAddrNode, node) == 0 ); osiSockAddrNode * pNode = reinterpret_cast < osiSockAddrNode * > ( pRawNode ); if ( pNode->addr.sa.sa_family == AF_INET ) { - ipIgnoreEntry * pIPI = new ipIgnoreEntry ( pNode->addr.ia.sin_addr.s_addr ); + ipIgnoreEntry * pIPI = new ( this->ipIgnoreEntryFreeList ) + ipIgnoreEntry ( pNode->addr.ia.sin_addr.s_addr ); this->ignoreTable.add ( * pIPI ); } else { diff --git a/src/cas/io/bsdSocket/casIOD.h b/src/cas/io/bsdSocket/casIOD.h index a00487609..0027c18fe 100644 --- a/src/cas/io/bsdSocket/casIOD.h +++ b/src/cas/io/bsdSocket/casIOD.h @@ -25,7 +25,6 @@ #include "envDefs.h" #include "resourceLib.h" -#include "epicsSingleton.h" #include "tsFreeList.h" #include "osiSock.h" #include "inetAddrID.h" @@ -43,16 +42,19 @@ public: ipIgnoreEntry ( unsigned ipAddr ); void destroy (); void show ( unsigned level ) const; - void * operator new ( size_t size ); - void operator delete ( void * pCadaver, size_t size ); bool operator == ( const ipIgnoreEntry & ) const; resTableIndex hash () const; + void * operator new ( size_t size, + tsFreeList < class ipIgnoreEntry, 128 > & ); + void operator delete ( void *, + tsFreeList < class ipIgnoreEntry, 128 > & ); private: unsigned ipAddr; - static epicsSingleton < tsFreeList < class ipIgnoreEntry, 1024 > > pFreeList; ipIgnoreEntry ( const ipIgnoreEntry & ); ipIgnoreEntry & operator = ( const ipIgnoreEntry & ); + void * operator new ( size_t size ); + void operator delete ( void * ); }; // @@ -60,8 +62,9 @@ private: // class casDGIntfIO : public casDGClient { public: - casDGIntfIO ( caServerI &serverIn, const caNetAddr &addr, - bool autoBeaconAddr=TRUE, bool addConfigBeaconAddr = false ); + casDGIntfIO ( caServerI & serverIn, clientBufMemoryManager &, + const caNetAddr & addr, bool autoBeaconAddr = true, + bool addConfigBeaconAddr = false ); virtual ~casDGIntfIO(); int getFD () const; @@ -85,6 +88,7 @@ public: bufSizeT incomingBytesPresent () const; private: + tsFreeList < class ipIgnoreEntry, 128 > ipIgnoreEntryFreeList; resTable < ipIgnoreEntry, ipIgnoreEntry > ignoreTable; ELLLIST beaconAddrList; SOCKET sock; @@ -107,13 +111,14 @@ struct ioArgsToNewStreamIO { // class casStreamIO : public casStrmClient { public: - casStreamIO ( caServerI & cas, const ioArgsToNewStreamIO & args ); - ~casStreamIO(); + casStreamIO ( caServerI &, clientBufMemoryManager &, + const ioArgsToNewStreamIO & ); + ~casStreamIO (); - int getFD() const; - void xSetNonBlocking(); + int getFD () const; + void xSetNonBlocking (); - casIOState state() const; + casIOState state () const; void hostName ( char *pBuf, unsigned bufSize ) const; outBufClient::flushCondition osdSend ( const char *pBuf, bufSizeT nBytesReq, @@ -164,7 +169,8 @@ public: // called when we expect that a virtual circuit for a // client can be created // - casStreamOS *newStreamClient(caServerI &cas) const; + casStreamOS * newStreamClient ( caServerI & cas, + clientBufMemoryManager & ) const; caNetAddr serverAddress () const; diff --git a/src/cas/io/bsdSocket/casIODIL.h b/src/cas/io/bsdSocket/casIODIL.h index 2e3caf0e8..71c651066 100644 --- a/src/cas/io/bsdSocket/casIODIL.h +++ b/src/cas/io/bsdSocket/casIODIL.h @@ -27,14 +27,16 @@ inline bool casDGIntfIO::validBCastFD() const return this->bcastRecvSock != INVALID_SOCKET; } -inline void * ipIgnoreEntry::operator new ( size_t size ) +inline void * ipIgnoreEntry::operator new ( size_t size, + tsFreeList < class ipIgnoreEntry, 128 > & freeList ) { - return ipIgnoreEntry::pFreeList->allocate ( size ); + return freeList.allocate ( size ); } -inline void ipIgnoreEntry::operator delete ( void * pCadaver, size_t size ) +inline void ipIgnoreEntry::operator delete ( void * pCadaver, + tsFreeList < class ipIgnoreEntry, 128 > & freeList ) { - ipIgnoreEntry::pFreeList->release ( pCadaver, size ); + freeList.release ( pCadaver ); } inline ipIgnoreEntry::ipIgnoreEntry ( unsigned ipAddrIn ) : diff --git a/src/cas/io/bsdSocket/casIntfIO.cc b/src/cas/io/bsdSocket/casIntfIO.cc index 6e566279a..45293b9ca 100644 --- a/src/cas/io/bsdSocket/casIntfIO.cc +++ b/src/cas/io/bsdSocket/casIntfIO.cc @@ -151,7 +151,8 @@ casIntfIO::~casIntfIO() // // newStreamIO::newStreamClient() // -casStreamOS *casIntfIO::newStreamClient(caServerI &cas) const +casStreamOS *casIntfIO::newStreamClient ( caServerI & cas, + clientBufMemoryManager & bufMgr ) const { static bool oneMsgFlag = false; struct sockaddr newAddr; @@ -179,7 +180,7 @@ casStreamOS *casIntfIO::newStreamClient(caServerI &cas) const ioArgsToNewStreamIO args; args.addr = newAddr; args.sock = newSock; - pOS = new casStreamOS ( cas, args ); + pOS = new casStreamOS ( cas, bufMgr, args ); if ( ! pOS ) { errMessage ( S_cas_noMemory, "unable to create data structures for a new client" ); diff --git a/src/cas/io/bsdSocket/casStreamIO.cc b/src/cas/io/bsdSocket/casStreamIO.cc index 71fde2eb8..905e787dc 100644 --- a/src/cas/io/bsdSocket/casStreamIO.cc +++ b/src/cas/io/bsdSocket/casStreamIO.cc @@ -16,9 +16,11 @@ // // casStreamIO::casStreamIO() // -casStreamIO::casStreamIO(caServerI &cas, const ioArgsToNewStreamIO &args) : - casStrmClient(cas), sock(args.sock), addr(args.addr), blockingFlag(xIsBlocking) -{ +casStreamIO::casStreamIO ( caServerI & cas, clientBufMemoryManager & bufMgr, + const ioArgsToNewStreamIO & args ) : + casStrmClient ( cas, bufMgr ), sock ( args.sock ), addr ( args.addr), + blockingFlag ( xIsBlocking ) + { assert (sock>=0); int yes = TRUE; int status; diff --git a/src/cas/io/bsdSocket/ipIgnoreEntry.cpp b/src/cas/io/bsdSocket/ipIgnoreEntry.cpp index e6c0f826a..8870e6b6f 100644 --- a/src/cas/io/bsdSocket/ipIgnoreEntry.cpp +++ b/src/cas/io/bsdSocket/ipIgnoreEntry.cpp @@ -20,8 +20,6 @@ #define caNetAddrSock #include "server.h" -epicsSingleton < tsFreeList < ipIgnoreEntry, 1024 > > ipIgnoreEntry::pFreeList; - void ipIgnoreEntry::show ( unsigned /* level */ ) const { char buf[256]; @@ -46,6 +44,11 @@ resTableIndex ipIgnoreEntry::hash () const inetAddrMaxIndexBitWidth, this->ipAddr ); } +void ipIgnoreEntry::operator delete ( void * pCadaver ) +{ + throw std::logic_error ( "compiler is confused about placement delete" ); +} + diff --git a/src/db/dbCAC.h b/src/db/dbCAC.h index 029571d9a..4a62e4e2b 100644 --- a/src/db/dbCAC.h +++ b/src/db/dbCAC.h @@ -35,7 +35,6 @@ #endif #include "tsDLList.h" -#include "epicsSingleton.h" #include "tsFreeList.h" #include "resourceLib.h" #include "cacIO.h" @@ -79,13 +78,13 @@ extern "C" void dbSubscriptionEventCallback ( void *pPrivate, struct dbAddr *pad class dbSubscriptionIO : public tsDLNode , public dbBaseIO { public: dbSubscriptionIO ( dbServiceIO &, dbChannelIO &, struct dbAddr &, cacStateNotify &, - unsigned type, unsigned long count, unsigned mask, cacChannel::ioid * ); + unsigned type, unsigned long count, unsigned mask, dbEventCtx ); void destroy (); void unsubscribe (); void channelDeleteException (); void show ( unsigned level ) const; - void * operator new ( size_t size ); - void operator delete ( void *pCadaver, size_t size ); + void * operator new ( size_t size, tsFreeList < dbSubscriptionIO > & ); + void operator delete ( void *, tsFreeList < dbSubscriptionIO > & ); protected: virtual ~dbSubscriptionIO (); private: @@ -96,11 +95,12 @@ private: unsigned long count; unsigned id; dbSubscriptionIO * isSubscription (); - static epicsSingleton < tsFreeList < dbSubscriptionIO > > pFreeList; friend void dbSubscriptionEventCallback ( void *pPrivate, struct dbAddr *paddr, int eventsRemaining, struct db_field_log *pfl ); dbSubscriptionIO ( const dbSubscriptionIO & ); dbSubscriptionIO & operator = ( const dbSubscriptionIO & ); + void * operator new ( size_t size ); + void operator delete ( void * ); }; class dbServiceIO; @@ -138,16 +138,18 @@ public: dbServiceIO (); virtual ~dbServiceIO (); cacChannel * createChannel ( const char *pName, - cacChannelNotify &, cacChannel::priLev ); + cacChannelNotify &, cacChannel::priLev ); void callReadNotify ( struct dbAddr &addr, unsigned type, unsigned long count, cacReadNotify ¬ify ); void callStateNotify ( struct dbAddr &addr, unsigned type, unsigned long count, - const struct db_field_log *pfl, cacStateNotify ¬ify ); - dbEventSubscription subscribe ( struct dbAddr & addr, dbChannelIO & chan, - dbSubscriptionIO & subscr, unsigned mask ); + const struct db_field_log * pfl, cacStateNotify & notify ); + void subscribe ( + struct dbAddr & addr, dbChannelIO & chan, + unsigned type, unsigned long count, unsigned mask, + cacStateNotify & notify, cacChannel::ioid * pId ); void initiatePutNotify ( dbChannelIO &, struct dbAddr &, unsigned type, - unsigned long count, const void *pValue, cacWriteNotify ¬ify, - cacChannel::ioid *pId ); + unsigned long count, const void *pValue, cacWriteNotify ¬ify, + cacChannel::ioid * pId ); void show ( unsigned level ) const; void showAllIO ( const dbChannelIO &chan, unsigned level ) const; void destroyAllIO ( dbChannelIO & chan ); @@ -155,6 +157,9 @@ public: void ioShow ( const cacChannel::ioid &id, unsigned level ) const; private: mutable epicsMutex mutex; + tsFreeList < dbPutNotifyBlocker > dbPutNotifyBlockerFreeList; + tsFreeList < dbSubscriptionIO > dbSubscriptionIOFreeList; + tsFreeList < dbChannelIO > dbChannelIOFreeList; chronIntIdResTable < dbBaseIO > ioTable; dbServiceIOReadNotifyCache readNotifyCache; dbEventCtx ctx; diff --git a/src/db/dbChannelIO.cpp b/src/db/dbChannelIO.cpp index 4b9b69764..b4b6b02da 100644 --- a/src/db/dbChannelIO.cpp +++ b/src/db/dbChannelIO.cpp @@ -24,12 +24,13 @@ * 505 665 1831 */ +#include + #include #include "tsFreeList.h" #include "epicsMutex.h" #include "epicsEvent.h" -#include "epicsSingleton.h" #include "db_access.h" #define epicsExportSharedSymbols @@ -38,8 +39,6 @@ #include "dbChannelIO.h" #include "dbPutNotifyBlocker.h" -epicsSingleton < tsFreeList < dbChannelIO > > dbChannelIO::pFreeList; - dbChannelIO::dbChannelIO ( cacChannelNotify ¬ify, const dbAddr &addrIn, dbServiceIO &serviceIO ) : cacChannel ( notify ), serviceIO ( serviceIO ), @@ -90,17 +89,10 @@ cacChannel::ioStatus dbChannelIO::write ( unsigned type, unsigned long count, } void dbChannelIO::subscribe ( unsigned type, unsigned long count, - unsigned mask, cacStateNotify ¬ify, ioid *pId ) + unsigned mask, cacStateNotify & notify, ioid * pId ) { - if ( type > INT_MAX ) { - throw cacChannel::badType(); - } - if ( count > INT_MAX ) { - throw cacChannel::outOfBounds(); - } - - new dbSubscriptionIO ( this->serviceIO, *this, - this->addr, notify, type, count, mask, pId ); + this->serviceIO.subscribe ( this->addr, *this, + type, count, mask, notify, pId ); } void dbChannelIO::ioCancel ( const ioid & id ) @@ -129,5 +121,10 @@ void dbChannelIO::show ( unsigned level ) const } } +void dbChannelIO::operator delete ( void *pCadaver ) +{ + throw std::logic_error + ( "compiler is confused about placement delete" ); +} diff --git a/src/db/dbChannelIO.h b/src/db/dbChannelIO.h index b3ae5818f..3037d189a 100644 --- a/src/db/dbChannelIO.h +++ b/src/db/dbChannelIO.h @@ -40,9 +40,9 @@ public: void callStateNotify ( unsigned type, unsigned long count, const struct db_field_log *pfl, cacStateNotify ¬ify ); void show ( unsigned level ) const; - void * operator new ( size_t size); - void operator delete ( void *pCadaver, size_t size ); const char *pName () const; + void * operator new ( size_t size, tsFreeList < dbChannelIO > & ); + void operator delete ( void *, tsFreeList < dbChannelIO > & ); protected: ~dbChannelIO (); // allocate only from pool private: @@ -61,9 +61,10 @@ private: void ioShow ( const ioid &, unsigned level ) const; short nativeType () const; unsigned long nativeElementCount () const; - static epicsSingleton < tsFreeList < dbChannelIO > > pFreeList; dbChannelIO ( const dbChannelIO & ); dbChannelIO & operator = ( const dbChannelIO & ); + void * operator new ( size_t size ); + void operator delete ( void * ); }; @@ -80,14 +81,16 @@ inline void dbChannelIO::destroy () delete this; } -inline void * dbChannelIO::operator new ( size_t size ) +inline void * dbChannelIO::operator new ( size_t size, + tsFreeList < dbChannelIO > & freeList ) { - return dbChannelIO::pFreeList->allocate ( size ); + return freeList.allocate ( size ); } -inline void dbChannelIO::operator delete ( void *pCadaver, size_t size ) +inline void dbChannelIO::operator delete ( void *pCadaver, + tsFreeList < dbChannelIO > & freeList ) { - dbChannelIO::pFreeList->release ( pCadaver, size ); + freeList.release ( pCadaver ); } inline const char *dbChannelIO::pName () const diff --git a/src/db/dbPutNotifyBlocker.cpp b/src/db/dbPutNotifyBlocker.cpp index 2e63d91e6..546779325 100644 --- a/src/db/dbPutNotifyBlocker.cpp +++ b/src/db/dbPutNotifyBlocker.cpp @@ -25,6 +25,8 @@ * 505 665 1831 */ +#include + #include #include @@ -32,7 +34,6 @@ #include "epicsEvent.h" #include "epicsTime.h" #include "tsFreeList.h" -#include "epicsSingleton.h" #include "errMdef.h" #include "caerr.h" // this needs to be eliminated @@ -43,9 +44,6 @@ #include "dbChannelIO.h" #include "dbPutNotifyBlocker.h" -epicsSingleton < tsFreeList < dbPutNotifyBlocker, 1024 > > - dbPutNotifyBlocker::pFreeList; - dbPutNotifyBlocker::dbPutNotifyBlocker () : pNotify ( 0 ), maxValueSize ( sizeof ( this->dbrScalarValue ) ) { @@ -189,3 +187,8 @@ dbSubscriptionIO * dbPutNotifyBlocker::isSubscription () return 0; } +void dbPutNotifyBlocker::operator delete ( void * pCadaver ) +{ + throw std::logic_error + ( "compiler is confused about placement delete" ); +} diff --git a/src/db/dbPutNotifyBlocker.h b/src/db/dbPutNotifyBlocker.h index dc897eef1..dcd614811 100644 --- a/src/db/dbPutNotifyBlocker.h +++ b/src/db/dbPutNotifyBlocker.h @@ -35,7 +35,6 @@ #include "shareLib.h" #include "tsFreeList.h" -#include "epicsSingleton.h" #ifdef dbPutNotifyBlockerh_restore_epicsExportSharedSymbols #define epicsExportSharedSymbols @@ -51,9 +50,11 @@ public: unsigned type, unsigned long count, const void * pValue ); void cancel (); void show ( unsigned level ) const; - void * operator new ( size_t size ); - void operator delete ( void *pCadaver, size_t size ); void destroy (); + void * operator new ( size_t size, + tsFreeList < dbPutNotifyBlocker > & ); + void operator delete ( void *, + tsFreeList < dbPutNotifyBlocker > & ); protected: virtual ~dbPutNotifyBlocker (); private: @@ -79,20 +80,23 @@ private: unsigned long maxValueSize; dbSubscriptionIO * isSubscription (); void expandValueBuf ( unsigned long newSize ); - static epicsSingleton < tsFreeList < dbPutNotifyBlocker > > pFreeList; friend void putNotifyCompletion ( putNotify *ppn ); dbPutNotifyBlocker ( const dbPutNotifyBlocker & ); dbPutNotifyBlocker & operator = ( const dbPutNotifyBlocker & ); + void * operator new ( size_t size ); + void operator delete ( void * ); }; -inline void * dbPutNotifyBlocker::operator new ( size_t size ) +inline void * dbPutNotifyBlocker::operator new ( size_t size, + tsFreeList < dbPutNotifyBlocker > & freeList ) { - return dbPutNotifyBlocker::pFreeList->allocate ( size ); + return freeList.allocate ( size ); } -inline void dbPutNotifyBlocker::operator delete ( void *pCadaver, size_t size ) +inline void dbPutNotifyBlocker::operator delete ( void *pCadaver, + tsFreeList < dbPutNotifyBlocker > & freeList ) { - dbPutNotifyBlocker::pFreeList->release ( pCadaver, size ); + freeList.release ( pCadaver ); } #endif // ifndef dbPutNotifyBlockerh diff --git a/src/db/dbServiceIO.cpp b/src/db/dbServiceIO.cpp index c2c5d69d6..c3f90dbb9 100644 --- a/src/db/dbServiceIO.cpp +++ b/src/db/dbServiceIO.cpp @@ -60,7 +60,8 @@ dbBaseIO::dbBaseIO () {} dbServiceIOLoadTimeInit::dbServiceIOLoadTimeInit () { - pGlobalServiceListCAC->registerService ( this->dbio ); + epicsSingleton < cacServiceList > :: reference ref ( globalServiceListCAC ); + ref->registerService ( this->dbio ); } dbServiceIO::dbServiceIO () : @@ -78,12 +79,12 @@ dbServiceIO::~dbServiceIO () } cacChannel *dbServiceIO::createChannel ( // X aCC 361 - const char *pName, cacChannelNotify ¬ify, + const char * pName, cacChannelNotify & notify, cacChannel::priLev ) { struct dbAddr addr; - int status = db_name_to_addr ( pName, &addr ); + int status = db_name_to_addr ( pName, & addr ); if ( status ) { return 0; } @@ -94,7 +95,8 @@ cacChannel *dbServiceIO::createChannel ( // X aCC 361 return 0; } else { - return new dbChannelIO ( notify, addr, *this ); + return new ( this->dbChannelIOFreeList ) + dbChannelIO ( notify, addr, *this ); } } @@ -145,47 +147,60 @@ extern "C" void cacAttachClientCtx ( void * pPrivate ) assert ( status == ECA_NORMAL ); } -dbEventSubscription dbServiceIO::subscribe ( struct dbAddr & addr, dbChannelIO & chan, - dbSubscriptionIO & subscr, unsigned mask ) +void dbServiceIO::subscribe ( + struct dbAddr & addr, dbChannelIO & chan, + unsigned type, unsigned long count, unsigned mask, + cacStateNotify & notify, cacChannel::ioid * pId ) { - dbEventSubscription es; - int status; + /* + * the database uses type "int" to store these parameters + */ + if ( type > INT_MAX ) { + throw cacChannel::badType(); + } + if ( count > INT_MAX ) { + throw cacChannel::outOfBounds(); + } { epicsGuard < epicsMutex > locker ( this->mutex ); if ( ! this->ctx ) { this->ctx = db_init_events (); if ( ! this->ctx ) { - return 0; + throw std::bad_alloc (); } unsigned selfPriority = epicsThreadGetPrioritySelf (); unsigned above; - epicsThreadBooleanStatus tbs = epicsThreadLowestPriorityLevelAbove (selfPriority, &above); + epicsThreadBooleanStatus tbs = + epicsThreadLowestPriorityLevelAbove ( selfPriority, &above ); if ( tbs != epicsThreadBooleanStatusSuccess ) { above = selfPriority; } - status = db_start_events ( this->ctx, "CAC-event", + int status = db_start_events ( this->ctx, "CAC-event", cacAttachClientCtx, ca_current_context (), above ); if ( status ) { db_close_events ( this->ctx ); this->ctx = 0; - return 0; + throw std::bad_alloc (); } } + } + + dbSubscriptionIO & subscr = + * new ( this->dbSubscriptionIOFreeList ) + dbSubscriptionIO ( *this, chan, + addr, notify, type, count, mask, pId ); + + { + epicsGuard < epicsMutex > locker ( this->mutex ); chan.dbServicePrivateListOfIO::eventq.add ( subscr ); this->ioTable.add ( subscr ); } - es = db_add_event ( this->ctx, &addr, - dbSubscriptionEventCallback, (void *) &subscr, mask ); - if ( ! es ) { - epicsGuard < epicsMutex > locker ( this->mutex ); - chan.dbServicePrivateListOfIO::eventq.remove ( subscr ); - this->ioTable.remove ( subscr ); + if ( pId ) { + *pId = subscr.getId (); } - - return es; } void dbServiceIO::initiatePutNotify ( @@ -195,7 +210,9 @@ void dbServiceIO::initiatePutNotify ( { epicsGuard < epicsMutex > locker ( this->mutex ); if ( ! chan.dbServicePrivateListOfIO::pBlocker ) { - chan.dbServicePrivateListOfIO::pBlocker = new dbPutNotifyBlocker (); + chan.dbServicePrivateListOfIO::pBlocker = + new ( this->dbPutNotifyBlockerFreeList ) + dbPutNotifyBlocker (); this->ioTable.add ( *chan.dbServicePrivateListOfIO::pBlocker ); } chan.dbServicePrivateListOfIO::pBlocker->initiatePutNotify ( diff --git a/src/db/dbServiceIOReadNotifyCache.cpp b/src/db/dbServiceIOReadNotifyCache.cpp index eff5f81fe..84f10a6d2 100644 --- a/src/db/dbServiceIOReadNotifyCache.cpp +++ b/src/db/dbServiceIOReadNotifyCache.cpp @@ -15,7 +15,6 @@ #include "epicsMutex.h" #include "tsFreeList.h" -#include "epicsSingleton.h" #include "cadef.h" // this can be eliminated when the callbacks use the new interface #include "db_access.h" // should be eliminated here in the future diff --git a/src/db/dbSubscriptionIO.cpp b/src/db/dbSubscriptionIO.cpp index ede431cab..9f10dd6ab 100644 --- a/src/db/dbSubscriptionIO.cpp +++ b/src/db/dbSubscriptionIO.cpp @@ -24,12 +24,13 @@ * 505 665 1831 */ +#include + #include #include "epicsMutex.h" #include "epicsEvent.h" #include "tsFreeList.h" -#include "epicsSingleton.h" #include "db_access.h" // need to eliminate this #include "cadef.h" // this can be eliminated when the callbacks use the new interface @@ -39,22 +40,18 @@ #include "dbChannelIO.h" #include "db_access_routines.h" -epicsSingleton < tsFreeList < dbSubscriptionIO > > dbSubscriptionIO::pFreeList; - -dbSubscriptionIO::dbSubscriptionIO ( dbServiceIO &serviceIO, dbChannelIO &chanIO, - dbAddr &addr, cacStateNotify ¬ifyIn, - unsigned typeIn, unsigned long countIn, unsigned maskIn, - cacChannel::ioid * pId ) : +dbSubscriptionIO::dbSubscriptionIO ( dbServiceIO & serviceIO, dbChannelIO & chanIO, + dbAddr & addr, cacStateNotify & notifyIn, unsigned typeIn, unsigned long countIn, + unsigned maskIn, dbEventCtx ctx ) : notify ( notifyIn ), chan ( chanIO ), es ( 0 ), type ( typeIn ), count ( countIn ), id ( 0u ) { - this->es = serviceIO.subscribe ( addr, chanIO, *this, maskIn ); - if ( pId ) { - *pId = this->getId (); + this->es = db_add_event ( ctx, & addr, + dbSubscriptionEventCallback, (void *) this, maskIn ); + if ( this->es == 0 ) { + throw std::bad_alloc(); } - db_post_single_event ( this->es ); - db_event_enable ( this->es ); } @@ -82,14 +79,22 @@ void dbSubscriptionIO::channelDeleteException () this->chan.pName(), this->type, this->count ); } -void * dbSubscriptionIO::operator new ( size_t size ) +void dbSubscriptionIO::operator delete ( void * pCadaver ) { - return dbSubscriptionIO::pFreeList->allocate ( size ); + throw std::logic_error + ( "compiler is confused about placement delete" ); } -void dbSubscriptionIO::operator delete ( void *pCadaver, size_t size ) +void * dbSubscriptionIO::operator new ( size_t size, + tsFreeList < dbSubscriptionIO > & freeList ) { - dbSubscriptionIO::pFreeList->release ( pCadaver, size ); + return freeList.allocate ( size ); +} + +void dbSubscriptionIO::operator delete ( void * pCadaver, + tsFreeList < dbSubscriptionIO > & freeList ) +{ + freeList.release ( pCadaver ); } extern "C" void dbSubscriptionEventCallback ( void *pPrivate, struct dbAddr * /* paddr */, diff --git a/src/db/templateInstances.cpp b/src/db/templateInstances.cpp index a73338cfa..b3caf2b79 100644 --- a/src/db/templateInstances.cpp +++ b/src/db/templateInstances.cpp @@ -37,13 +37,10 @@ #endif template class tsFreeList < dbChannelIO >; -template class epicsSingleton < tsFreeList < dbChannelIO > >; template class tsFreeList < dbPutNotifyBlocker, 1024 >; -template class epicsSingleton < tsFreeList < dbPutNotifyBlocker, 1024 > >; template class resTable < dbBaseIO, chronIntId >; template class chronIntIdResTable < dbBaseIO >; template class tsFreeList < dbSubscriptionIO >; -template class epicsSingleton < tsFreeList < dbSubscriptionIO > >; #ifdef _MSC_VER # pragma warning ( pop )