diff --git a/src/ca/bhe.h b/src/ca/bhe.h index c14eb99ab..77f7ff410 100644 --- a/src/ca/bhe.h +++ b/src/ca/bhe.h @@ -83,8 +83,6 @@ private: bhe & operator = ( const bhe & ); void * operator new ( size_t size ); epicsShareFunc void operator delete ( void * ); - void * operator new [] ( size_t size ); - void operator delete [] ( void * ); }; // using a wrapper class around the free list avoids diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index bf4f190af..0776e36bf 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -538,9 +538,8 @@ bool cac::lookupChannelAndTransferToTCP ( char acc[64]; pChan->getPIIU()->hostName ( acc, sizeof ( acc ) ); msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList ) - msgForMultiplyDefinedPV ( - this->cbMutex, *this, pChan->pName (), acc, addr ); - this->ipAddrToAsciiAsynchronousRequestInstall ( *pMsg ); + msgForMultiplyDefinedPV ( *this, pChan->pName (), acc, addr ); + pMsg->ioInitiate ( this->ipToAEngine ); } return true; } @@ -759,7 +758,7 @@ void cac::flushIfRequired ( epicsGuard < cacMutex > & guard, netiiu & iiu ) } } -void cac::writeRequest ( nciu & chan, unsigned type, unsigned nElem, const void * pValue ) +void cac::writeRequest ( nciu & chan, unsigned type, arrayElementCount nElem, const void * pValue ) { epicsGuard < cacMutex > guard ( this->mutex ); this->flushIfRequired ( guard, *chan.getPIIU() ); @@ -767,8 +766,8 @@ void cac::writeRequest ( nciu & chan, unsigned type, unsigned nElem, const void } cacChannel::ioid -cac::writeNotifyRequest ( nciu &chan, unsigned type, // X aCC 361 - unsigned nElem, const void *pValue, cacWriteNotify ¬ifyIn ) +cac::writeNotifyRequest ( nciu & chan, unsigned type, // X aCC 361 + arrayElementCount nElem, const void * pValue, cacWriteNotify & notifyIn ) { epicsGuard < cacMutex > guard ( this->mutex ); autoPtrRecycle < netWriteNotifyIO > pIO ( this->ioTable, chan.cacPrivateListOfIO::eventq, @@ -782,8 +781,8 @@ cac::writeNotifyRequest ( nciu &chan, unsigned type, // X aCC 361 } cacChannel::ioid -cac::readNotifyRequest ( nciu &chan, unsigned type, // X aCC 361 - unsigned nElem, cacReadNotify ¬ifyIn ) +cac::readNotifyRequest ( nciu & chan, unsigned type, // X aCC 361 + arrayElementCount nElem, cacReadNotify & notifyIn ) { epicsGuard < cacMutex > guard ( this->mutex ); autoPtrRecycle < netReadNotifyIO > pIO ( this->ioTable, @@ -796,8 +795,8 @@ cac::readNotifyRequest ( nciu &chan, unsigned type, // X aCC 361 return pIO.release()->getId (); } -void cac::ioCancel ( nciu &chan, const cacChannel::ioid & idIn ) -{ +void cac::ioCancel ( nciu & chan, const cacChannel::ioid & idIn ) +{ baseNMIU * pmiu; // unistall the IO object so that a receive thread will not find it, @@ -1597,3 +1596,19 @@ void cacComBufMemoryManager::release ( void * pCadaver ) epics_throws (()) return this->freeList.release ( pCadaver ); } +void cac::pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv, + const char * pChannelName, const char * pAcc, const char * pRej ) +{ + char buf[256]; + sprintf ( buf, "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s", + pChannelName, pAcc, pRej ); + { + epicsGuard < callbackMutex > cbGuard ( this->cbMutex ); + this->exception ( cbGuard, ECA_DBLCHNL, buf, __FILE__, __LINE__ ); + } + mfmdpv.~msgForMultiplyDefinedPV (); + this->mdpvFreeList.release ( & mfmdpv ); +} + + + diff --git a/src/ca/cac.h b/src/ca/cac.h index 900325237..e64145508 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -33,6 +33,7 @@ #include "cxxCompilerDependencies.h" #include "ipAddrToAsciiAsynchronous.h" +#include "msgForMultiplyDefinedPV.h" #include "epicsTimer.h" #include "epicsEvent.h" #include "freeList.h" @@ -111,7 +112,8 @@ public: epicsGuard < cacMutex > &, nciu & chan ) = 0; }; -class cac : private cacRecycle, private cacDisconnectChannelPrivate +class cac : private cacRecycle, private cacDisconnectChannelPrivate, + private callbackForMultiplyDefinedPV { public: cac ( cacNotify &, bool enablePreemptiveCallbackIn ); @@ -128,8 +130,6 @@ public: epicsGuard < callbackMutex > callbackGuardFactory (); bool executeResponse ( epicsGuard < callbackMutex > &, tcpiiu &, caHdrLargeArray &, char *pMsgBody ); - void ioCancel ( nciu &chan, const cacChannel::ioid &id ); - void ioShow ( const cacChannel::ioid &id, unsigned level ) const; // channel routines bool lookupChannelAndTransferToTCP ( @@ -145,15 +145,17 @@ public: void registerService ( cacService &service ); void initiateConnect ( nciu & ); - // IO request stubs + // IO requests void writeRequest ( nciu &, unsigned type, - unsigned nElem, const void *pValue ); + arrayElementCount nElem, const void * pValue ); cacChannel::ioid writeNotifyRequest ( nciu &, unsigned type, - unsigned nElem, const void *pValue, cacWriteNotify & ); + arrayElementCount nElem, const void *pValue, cacWriteNotify & ); cacChannel::ioid readNotifyRequest ( nciu &, unsigned type, - unsigned nElem, cacReadNotify & ); + arrayElementCount nElem, cacReadNotify & ); cacChannel::ioid subscriptionRequest ( nciu &, unsigned type, arrayElementCount nElem, unsigned mask, cacStateNotify & ); + void ioCancel ( nciu & chan, const cacChannel::ioid & id ); + void ioShow ( const cacChannel::ioid &id, unsigned level ) const; // sync group routines CASG * lookupCASG ( unsigned id ); @@ -169,7 +171,6 @@ public: void show ( unsigned level ) const; int printf ( const char *pformat, ... ) const; int vPrintf ( const char *pformat, va_list args ) const; - void ipAddrToAsciiAsynchronousRequestInstall ( ipAddrToAsciiAsynchronous & request ); void signal ( int ca_status, const char *pfilenm, int lineno, const char *pFormat, ... ); void vSignal ( int ca_status, const char *pfilenm, @@ -275,6 +276,9 @@ private: void ioExceptionNotify ( unsigned id, int status, const char *pContext, unsigned type, arrayElementCount count ); + void pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv, + const char * pChannelName, const char * pAcc, const char * pRej ); + void ioCompletionNotifyAndDestroy ( unsigned id ); void ioCompletionNotifyAndDestroy ( unsigned id, unsigned type, arrayElementCount count, const void *pData ); @@ -341,11 +345,6 @@ inline const char * cac::userNamePointer () const return this->pUserName; } -inline void cac::ipAddrToAsciiAsynchronousRequestInstall ( ipAddrToAsciiAsynchronous & request ) -{ - request.ioInitiate ( this->ipToAEngine ); -} - inline unsigned cac::getInitializingThreadsPriority () const { return this->initializingThreadsPriority; diff --git a/src/ca/msgForMultiplyDefinedPV.cpp b/src/ca/msgForMultiplyDefinedPV.cpp index f5335db5b..5c48a3ba7 100644 --- a/src/ca/msgForMultiplyDefinedPV.cpp +++ b/src/ca/msgForMultiplyDefinedPV.cpp @@ -37,10 +37,9 @@ #undef epicsExportSharedSymbols msgForMultiplyDefinedPV::msgForMultiplyDefinedPV ( - callbackMutex & mutexIn, cac & cacRefIn, - const char * pChannelName, const char * pAcc, const osiSockAddr &rej ) : - ipAddrToAsciiAsynchronous ( rej ), cacRef ( cacRefIn ), - mutex ( mutexIn ) + callbackForMultiplyDefinedPV & cbIn, const char * pChannelName, + const char * pAcc, const osiSockAddr &rej ) : + ipAddrToAsciiAsynchronous ( rej ), cb ( cbIn ) { strncpy ( this->acc, pAcc, sizeof ( this->acc ) ); this->acc[ sizeof ( this->acc ) - 1 ] = '\0'; @@ -50,17 +49,26 @@ msgForMultiplyDefinedPV::msgForMultiplyDefinedPV ( void msgForMultiplyDefinedPV::ioCompletionNotify ( const char * pHostNameRej ) { - char buf[256]; - sprintf ( buf, "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s", - this->channel, this->acc, pHostNameRej ); - { - epicsGuard < callbackMutex > cbGuard ( this->mutex ); - genLocalExcep ( cbGuard, this->cacRef, ECA_DBLCHNL, buf ); - } - delete this; + this->cb.pvMultiplyDefinedNotify ( *this, this->channel, this->acc, pHostNameRej ); + // dont touch this pointer after cb interfaces is called above because + // this object may no-longer exist! } -void msgForMultiplyDefinedPV::operator delete ( void *pCadaver ) +void * msgForMultiplyDefinedPV::operator new ( size_t size, + tsFreeList < class msgForMultiplyDefinedPV, 16 > & freeList ) +{ + return freeList.allocate ( size ); +} + +#ifdef CXX_PLACEMENT_DELETE +void msgForMultiplyDefinedPV::operator delete ( void *pCadaver, + tsFreeList < class msgForMultiplyDefinedPV, 16 > & freeList ) +{ + freeList.release ( pCadaver, sizeof ( msgForMultiplyDefinedPV ) ); +} +#endif + +void msgForMultiplyDefinedPV::operator delete ( void * ) { // Visual C++ .net appears to require operator delete if // placement operator delete is defined? I smell a ms rat @@ -71,3 +79,8 @@ void msgForMultiplyDefinedPV::operator delete ( void *pCadaver ) __FILE__, __LINE__ ); } +callbackForMultiplyDefinedPV::~callbackForMultiplyDefinedPV () +{ +} + + diff --git a/src/ca/msgForMultiplyDefinedPV.h b/src/ca/msgForMultiplyDefinedPV.h index cfd8e0765..e0ebff482 100644 --- a/src/ca/msgForMultiplyDefinedPV.h +++ b/src/ca/msgForMultiplyDefinedPV.h @@ -29,47 +29,35 @@ #include "ipAddrToAsciiAsynchronous.h" #include "tsFreeList.h" -#include "epicsMutex.h" #include "cxxCompilerDependencies.h" -class cac; -class callbackMutex; +class callbackForMultiplyDefinedPV { +public: + virtual ~callbackForMultiplyDefinedPV () = 0; + virtual void pvMultiplyDefinedNotify ( + class msgForMultiplyDefinedPV &, const char * pChannelName, + const char * pAcc, const char * pRej ) = 0; +}; class msgForMultiplyDefinedPV : public ipAddrToAsciiAsynchronous { public: - msgForMultiplyDefinedPV ( callbackMutex &, - cac & cacRefIn, const char * pChannelName, const char * pAcc, - const osiSockAddr & rej ); - msgForMultiplyDefinedPV ( const osiSockAddr &addr, ipAddrToAsciiEngine &engine ); + msgForMultiplyDefinedPV ( callbackForMultiplyDefinedPV &, + const char * pChannelName, const char * pAcc, const osiSockAddr & rej ); + //msgForMultiplyDefinedPV ( const osiSockAddr &addr, ipAddrToAsciiEngine &engine ); void * operator new ( size_t size, tsFreeList < class msgForMultiplyDefinedPV, 16 > & ); # ifdef CXX_PLACEMENT_DELETE void operator delete ( void *, tsFreeList < class msgForMultiplyDefinedPV, 16 > & ); # endif private: - void ioCompletionNotify ( const char *pHostName ); char acc[64]; char channel[64]; - cac & cacRef; - callbackMutex & mutex; + callbackForMultiplyDefinedPV & cb; + void ioCompletionNotify ( const char *pHostName ); msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & ); msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & ); void * operator new ( size_t size ); void operator delete ( void * ); }; -inline void * msgForMultiplyDefinedPV::operator new ( size_t size, - tsFreeList < class msgForMultiplyDefinedPV, 16 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void msgForMultiplyDefinedPV::operator delete ( void *pCadaver, - tsFreeList < class msgForMultiplyDefinedPV, 16 > & freeList ) -{ - freeList.release ( pCadaver, sizeof ( msgForMultiplyDefinedPV ) ); -} -#endif - #endif // ifdef msgForMultiplyDefinedPVh diff --git a/src/cas/io/bsdSocket/casDGIntfIO.cc b/src/cas/io/bsdSocket/casDGIntfIO.cc index c9480d6c0..04e1b3139 100644 --- a/src/cas/io/bsdSocket/casDGIntfIO.cc +++ b/src/cas/io/bsdSocket/casDGIntfIO.cc @@ -266,7 +266,12 @@ casDGIntfIO::~casDGIntfIO() free ( pnode ); } - this->ignoreTable.traverse ( & ipIgnoreEntry::destroy ); + tsSLList < ipIgnoreEntry > tmp; + this->ignoreTable.removeAll ( tmp ); + while ( ipIgnoreEntry * pEntry = tmp.get() ) { + pEntry->~ipIgnoreEntry (); + this->ipIgnoreEntryFreeList.release ( pEntry ); + } osiSockRelease (); } diff --git a/src/cas/io/bsdSocket/casIOD.h b/src/cas/io/bsdSocket/casIOD.h index 0027c18fe..934700b27 100644 --- a/src/cas/io/bsdSocket/casIOD.h +++ b/src/cas/io/bsdSocket/casIOD.h @@ -28,6 +28,7 @@ #include "tsFreeList.h" #include "osiSock.h" #include "inetAddrID.h" +#include "cxxCompilerDependencies.h" #ifdef ipIgnoreEntryEpicsExportSharedSymbols # define epicsExportSharedSymbols @@ -40,15 +41,15 @@ void hostNameFromIPAddr ( const class caNetAddr * pAddr, class ipIgnoreEntry : public tsSLNode < ipIgnoreEntry > { public: ipIgnoreEntry ( unsigned ipAddr ); - void destroy (); void show ( unsigned level ) const; bool operator == ( const ipIgnoreEntry & ) const; resTableIndex hash () const; void * operator new ( size_t size, tsFreeList < class ipIgnoreEntry, 128 > & ); +# ifdef CXX_PLACEMENT_DELETE void operator delete ( void *, tsFreeList < class ipIgnoreEntry, 128 > & ); - +# endif private: unsigned ipAddr; ipIgnoreEntry ( const ipIgnoreEntry & ); diff --git a/src/cas/io/bsdSocket/casIODIL.h b/src/cas/io/bsdSocket/casIODIL.h index 71c651066..4f115cc57 100644 --- a/src/cas/io/bsdSocket/casIODIL.h +++ b/src/cas/io/bsdSocket/casIODIL.h @@ -27,27 +27,5 @@ inline bool casDGIntfIO::validBCastFD() const return this->bcastRecvSock != INVALID_SOCKET; } -inline void * ipIgnoreEntry::operator new ( size_t size, - tsFreeList < class ipIgnoreEntry, 128 > & freeList ) -{ - return freeList.allocate ( size ); -} - -inline void ipIgnoreEntry::operator delete ( void * pCadaver, - tsFreeList < class ipIgnoreEntry, 128 > & freeList ) -{ - freeList.release ( pCadaver ); -} - -inline ipIgnoreEntry::ipIgnoreEntry ( unsigned ipAddrIn ) : - ipAddr ( ipAddrIn ) -{ -} - -inline void ipIgnoreEntry::destroy () -{ - delete this; -} - #endif // casIODILh diff --git a/src/cas/io/bsdSocket/ipIgnoreEntry.cpp b/src/cas/io/bsdSocket/ipIgnoreEntry.cpp index 61f1efe04..8381154b1 100644 --- a/src/cas/io/bsdSocket/ipIgnoreEntry.cpp +++ b/src/cas/io/bsdSocket/ipIgnoreEntry.cpp @@ -44,7 +44,26 @@ resTableIndex ipIgnoreEntry::hash () const inetAddrMaxIndexBitWidth, this->ipAddr ); } -void ipIgnoreEntry::operator delete ( void * pCadaver ) +ipIgnoreEntry::ipIgnoreEntry ( unsigned ipAddrIn ) : + ipAddr ( ipAddrIn ) +{ +} + +void * ipIgnoreEntry::operator new ( size_t size, + tsFreeList < class ipIgnoreEntry, 128 > & freeList ) +{ + return freeList.allocate ( size ); +} + +#ifdef CXX_PLACEMENT_DELETE +void ipIgnoreEntry::operator delete ( void * pCadaver, + tsFreeList < class ipIgnoreEntry, 128 > & freeList ) +{ + freeList.release ( pCadaver ); +} +#endif + +void ipIgnoreEntry::operator delete ( void * ) { // Visual C++ .net appears to require operator delete if // placement operator delete is defined? I smell a ms rat diff --git a/src/db/dbCAC.h b/src/db/dbCAC.h index 4a62e4e2b..ced4bac91 100644 --- a/src/db/dbCAC.h +++ b/src/db/dbCAC.h @@ -38,13 +38,13 @@ #include "tsFreeList.h" #include "resourceLib.h" #include "cacIO.h" +#include "cxxCompilerDependencies.h" #ifdef dbCACh_restore_epicsExportSharedSymbols # define epicsExportSharedSymbols # include "shareLib.h" #endif - #include "db_access.h" #include "dbNotify.h" #include "dbEvent.h" @@ -65,7 +65,6 @@ class dbBaseIO // X aCC 655 : public chronIntIdRes < dbBaseIO > { public: virtual dbSubscriptionIO * isSubscription () = 0; - virtual void destroy () = 0; virtual void show ( unsigned level ) const = 0; dbBaseIO (); dbBaseIO ( const dbBaseIO & ); @@ -79,14 +78,14 @@ class dbSubscriptionIO : public tsDLNode , public dbBaseIO { public: dbSubscriptionIO ( dbServiceIO &, dbChannelIO &, struct dbAddr &, cacStateNotify &, unsigned type, unsigned long count, unsigned mask, dbEventCtx ); - void destroy (); + virtual ~dbSubscriptionIO (); void unsubscribe (); void channelDeleteException (); void show ( unsigned level ) const; void * operator new ( size_t size, tsFreeList < dbSubscriptionIO > & ); +# ifdef CXX_PLACEMENT_DELETE void operator delete ( void *, tsFreeList < dbSubscriptionIO > & ); -protected: - virtual ~dbSubscriptionIO (); +# endif private: cacStateNotify & notify; dbChannelIO & chan; @@ -110,7 +109,7 @@ public: dbServicePrivateListOfIO (); private: tsDLList < dbSubscriptionIO > eventq; - dbPutNotifyBlocker *pBlocker; + dbPutNotifyBlocker * pBlocker; friend class dbServiceIO; dbServicePrivateListOfIO ( const dbServicePrivateListOfIO & ); dbServicePrivateListOfIO & operator = ( const dbServicePrivateListOfIO & ); @@ -139,6 +138,7 @@ public: virtual ~dbServiceIO (); cacChannel * createChannel ( const char *pName, cacChannelNotify &, cacChannel::priLev ); + void destroyChannel ( dbChannelIO & ); void callReadNotify ( struct dbAddr &addr, unsigned type, unsigned long count, cacReadNotify ¬ify ); void callStateNotify ( struct dbAddr &addr, unsigned type, unsigned long count, diff --git a/src/db/dbChannelIO.cpp b/src/db/dbChannelIO.cpp index 59393a1e6..1f4ff0d5d 100644 --- a/src/db/dbChannelIO.cpp +++ b/src/db/dbChannelIO.cpp @@ -39,8 +39,8 @@ #include "dbChannelIO.h" #include "dbPutNotifyBlocker.h" -dbChannelIO::dbChannelIO ( cacChannelNotify ¬ify, - const dbAddr &addrIn, dbServiceIO &serviceIO ) : +dbChannelIO::dbChannelIO ( cacChannelNotify & notify, + const dbAddr & addrIn, dbServiceIO & serviceIO ) : cacChannel ( notify ), serviceIO ( serviceIO ), addr ( addrIn ) { @@ -56,6 +56,14 @@ dbChannelIO::~dbChannelIO () this->serviceIO.destroyAllIO ( *this ); } +void dbChannelIO::destroy () +{ + this->serviceIO.destroyChannel ( *this ); + // dont access this pointer after above call because + // object nolonger exists +} + + cacChannel::ioStatus dbChannelIO::read ( unsigned type, unsigned long count, cacReadNotify ¬ify, ioid * ) { @@ -121,7 +129,21 @@ void dbChannelIO::show ( unsigned level ) const } } -void dbChannelIO::operator delete ( void *pCadaver ) +void * dbChannelIO::operator new ( size_t size, + tsFreeList < dbChannelIO > & freeList ) +{ + return freeList.allocate ( size ); +} + +# ifdef CXX_PLACEMENT_DELETE +void dbChannelIO::operator delete ( void *pCadaver, + tsFreeList < dbChannelIO > & freeList ) +{ + freeList.release ( pCadaver ); +} +#endif + +void dbChannelIO::operator delete ( void * ) { // Visual C++ .net appears to require operator delete if // placement operator delete is defined? I smell a ms rat diff --git a/src/db/dbChannelIO.h b/src/db/dbChannelIO.h index 3037d189a..7491a25ba 100644 --- a/src/db/dbChannelIO.h +++ b/src/db/dbChannelIO.h @@ -30,10 +30,22 @@ #ifndef dbChannelIOh #define dbChannelIOh +#ifdef epicsExportSharedSymbols +# define dbChannelIOh_restore_epicsExportSharedSymbols +# undef epicsExportSharedSymbols +#endif + +#include "cxxCompilerDependencies.h" + +#ifdef dbChannelIOh_restore_epicsExportSharedSymbols +# define epicsExportSharedSymbols +#endif + class dbChannelIO : public cacChannel, public dbServicePrivateListOfIO { public: dbChannelIO ( cacChannelNotify ¬ify, const dbAddr &addr, dbServiceIO &serviceIO ); + ~dbChannelIO (); void destroy (); void callReadNotify ( unsigned type, unsigned long count, cacReadNotify ¬ify ); @@ -42,9 +54,9 @@ public: void show ( unsigned level ) const; const char *pName () const; void * operator new ( size_t size, tsFreeList < dbChannelIO > & ); +# ifdef CXX_PLACEMENT_DELETE void operator delete ( void *, tsFreeList < dbChannelIO > & ); -protected: - ~dbChannelIO (); // allocate only from pool +# endif private: dbServiceIO & serviceIO; dbAddr addr; @@ -76,23 +88,6 @@ inline unsigned long dbChannelIO::nativeElementCount () const return 0u; } -inline void dbChannelIO::destroy () -{ - delete this; -} - -inline void * dbChannelIO::operator new ( size_t size, - tsFreeList < dbChannelIO > & freeList ) -{ - return freeList.allocate ( size ); -} - -inline void dbChannelIO::operator delete ( void *pCadaver, - tsFreeList < dbChannelIO > & freeList ) -{ - freeList.release ( pCadaver ); -} - inline const char *dbChannelIO::pName () const { return addr.precord->name; diff --git a/src/db/dbPutNotifyBlocker.cpp b/src/db/dbPutNotifyBlocker.cpp index 6b217c026..e9a4dd082 100644 --- a/src/db/dbPutNotifyBlocker.cpp +++ b/src/db/dbPutNotifyBlocker.cpp @@ -61,11 +61,6 @@ dbPutNotifyBlocker::~dbPutNotifyBlocker () } } -void dbPutNotifyBlocker::destroy () -{ - delete this; -} - void dbPutNotifyBlocker::cancel () { if ( this->pn.paddr ) { @@ -187,7 +182,21 @@ dbSubscriptionIO * dbPutNotifyBlocker::isSubscription () return 0; } -void dbPutNotifyBlocker::operator delete ( void * pCadaver ) +void * dbPutNotifyBlocker::operator new ( size_t size, + tsFreeList < dbPutNotifyBlocker > & freeList ) +{ + return freeList.allocate ( size ); +} + +# ifdef CXX_PLACEMENT_DELETE +void dbPutNotifyBlocker::operator delete ( void *pCadaver, + tsFreeList < dbPutNotifyBlocker > & freeList ) +{ + freeList.release ( pCadaver ); +} +# endif + +void dbPutNotifyBlocker::operator delete ( void * ) { // Visual C++ .net appears to require operator delete if // placement operator delete is defined? I smell a ms rat diff --git a/src/db/dbPutNotifyBlocker.h b/src/db/dbPutNotifyBlocker.h index dcd614811..feddac67d 100644 --- a/src/db/dbPutNotifyBlocker.h +++ b/src/db/dbPutNotifyBlocker.h @@ -32,31 +32,28 @@ #undef epicsExportSharedSymbols #endif -#include "shareLib.h" - #include "tsFreeList.h" +#include "cxxCompilerDependencies.h" #ifdef dbPutNotifyBlockerh_restore_epicsExportSharedSymbols #define epicsExportSharedSymbols #endif -#include "shareLib.h" - class dbPutNotifyBlocker : public dbBaseIO { public: dbPutNotifyBlocker (); + virtual ~dbPutNotifyBlocker (); void initiatePutNotify ( epicsGuard < epicsMutex > & locker, cacWriteNotify & notify, struct dbAddr & addr, unsigned type, unsigned long count, const void * pValue ); void cancel (); void show ( unsigned level ) const; - void destroy (); void * operator new ( size_t size, tsFreeList < dbPutNotifyBlocker > & ); +# ifdef CXX_PLACEMENT_DELETE void operator delete ( void *, tsFreeList < dbPutNotifyBlocker > & ); -protected: - virtual ~dbPutNotifyBlocker (); +# endif private: putNotify pn; // @@ -87,17 +84,5 @@ private: void operator delete ( void * ); }; -inline void * dbPutNotifyBlocker::operator new ( size_t size, - tsFreeList < dbPutNotifyBlocker > & freeList ) -{ - return freeList.allocate ( size ); -} - -inline void dbPutNotifyBlocker::operator delete ( void *pCadaver, - tsFreeList < dbPutNotifyBlocker > & freeList ) -{ - freeList.release ( pCadaver ); -} - #endif // ifndef dbPutNotifyBlockerh diff --git a/src/db/dbServiceIO.cpp b/src/db/dbServiceIO.cpp index c3f90dbb9..e599fae40 100644 --- a/src/db/dbServiceIO.cpp +++ b/src/db/dbServiceIO.cpp @@ -100,6 +100,12 @@ cacChannel *dbServiceIO::createChannel ( // X aCC 361 } } +void dbServiceIO::destroyChannel ( dbChannelIO & chan ) +{ + chan.~dbChannelIO (); + this->dbChannelIOFreeList.release ( & chan ); +} + void dbServiceIO::callStateNotify ( struct dbAddr & addr, unsigned type, unsigned long count, const struct db_field_log * pfl, @@ -243,28 +249,32 @@ void dbServiceIO::destroyAllIO ( dbChannelIO & chan ) // If they call ioCancel() here it will be ignored // because the IO has been unregistered above. pIO->channelDeleteException (); - pIO->destroy (); + pIO->~dbSubscriptionIO (); + this->dbSubscriptionIOFreeList.release ( pIO ); } if ( chan.dbServicePrivateListOfIO::pBlocker ) { - chan.dbServicePrivateListOfIO::pBlocker->destroy (); + chan.dbServicePrivateListOfIO::pBlocker->~dbPutNotifyBlocker (); + this->dbPutNotifyBlockerFreeList.release ( chan.dbServicePrivateListOfIO::pBlocker ); + chan.dbServicePrivateListOfIO::pBlocker = 0; } } void dbServiceIO::ioCancel ( dbChannelIO & chan, const cacChannel::ioid &id ) { epicsGuard < epicsMutex > locker ( this->mutex ); - dbBaseIO *pIO = this->ioTable.remove ( id ); + dbBaseIO * pIO = this->ioTable.remove ( id ); if ( pIO ) { dbSubscriptionIO *pSIO = pIO->isSubscription (); if ( pSIO ) { chan.dbServicePrivateListOfIO::eventq.remove ( *pSIO ); - pIO->destroy (); + pSIO->~dbSubscriptionIO (); + this->dbSubscriptionIOFreeList.release ( pSIO ); } else if ( pIO == chan.dbServicePrivateListOfIO::pBlocker ) { chan.dbServicePrivateListOfIO::pBlocker->cancel (); } else { - errlogPrintf ( "dbServiceIO::ioCancel() unrecognized IO was probably leaked\n" ); + errlogPrintf ( "dbServiceIO::ioCancel() unrecognized IO was probably leaked or not canceled\n" ); } } } diff --git a/src/db/dbSubscriptionIO.cpp b/src/db/dbSubscriptionIO.cpp index 3e0ea58a2..c230fcad5 100644 --- a/src/db/dbSubscriptionIO.cpp +++ b/src/db/dbSubscriptionIO.cpp @@ -60,11 +60,6 @@ dbSubscriptionIO::~dbSubscriptionIO () this->unsubscribe (); } -void dbSubscriptionIO::destroy () -{ - delete this; -} - void dbSubscriptionIO::unsubscribe () { if ( this->es ) { @@ -79,7 +74,7 @@ void dbSubscriptionIO::channelDeleteException () this->chan.pName(), this->type, this->count ); } -void dbSubscriptionIO::operator delete ( void * pCadaver ) +void dbSubscriptionIO::operator delete ( void * ) { // Visual C++ .net appears to require operator delete if // placement operator delete is defined? I smell a ms rat @@ -96,11 +91,13 @@ void * dbSubscriptionIO::operator new ( size_t size, return freeList.allocate ( size ); } +#ifdef CXX_PLACEMENT_DELETE void dbSubscriptionIO::operator delete ( void * pCadaver, tsFreeList < dbSubscriptionIO > & freeList ) { freeList.release ( pCadaver ); } +#endif extern "C" void dbSubscriptionEventCallback ( void *pPrivate, struct dbAddr * /* paddr */, int /* eventsRemaining */, struct db_field_log *pfl )