diff --git a/src/ca/putCallback.cpp b/src/ca/putCallback.cpp index 8132a26fc..c92df5b97 100644 --- a/src/ca/putCallback.cpp +++ b/src/ca/putCallback.cpp @@ -24,12 +24,12 @@ * 505 665 1831 */ +#include + #define epicsExportSharedSymbols #include "iocinf.h" #include "oldAccess.h" -epicsSingleton < tsFreeList < class putCallback, 1024 > > putCallback::pFreeList; - putCallback::putCallback ( oldChannelNotify &chanIn, caEventCallBackFunc *pFuncIn, void *pPrivateIn ) : chan ( chanIn ), pFunc ( pFuncIn ), pPrivate ( pPrivateIn ) @@ -51,7 +51,7 @@ void putCallback::completion () args.status = ECA_NORMAL; args.dbr = 0; ( *this->pFunc ) (args); - delete this; + this->chan.getClientCtx().destroyPutCallback ( *this ); } void putCallback::exception ( @@ -68,7 +68,12 @@ void putCallback::exception ( args.dbr = 0; ( *this->pFunc ) (args); } - delete this; + this->chan.getClientCtx().destroyPutCallback ( *this ); } +void putCallback::operator delete ( void * pCadaver ) +{ + throw std::logic_error + ( "compiler is confused about placement delete" ); +} diff --git a/src/ca/repeater.cpp b/src/ca/repeater.cpp index 8f2673dd1..0060b4af9 100644 --- a/src/ca/repeater.cpp +++ b/src/ca/repeater.cpp @@ -78,6 +78,8 @@ * received). -- Jeff */ +#include + #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" #include "tsDLList.h" @@ -99,14 +101,12 @@ */ static tsDLList < repeaterClient > client_list; -epicsSingleton < tsFreeList < repeaterClient, 0x20 > > repeaterClient::pFreeList; - static const unsigned short PORT_ANY = 0u; typedef struct { SOCKET sock; int errNumber; - const char *pErrStr; + const char * pErrStr; } makeSocketReturn; /* @@ -249,20 +249,25 @@ repeaterClient::~repeaterClient () debugPrintf ( ( "Deleted client %u\n", epicsNTOH16 ( this->from.ia.sin_port ) ) ); } -inline void * repeaterClient::operator new ( size_t size ) +inline void repeaterClient::operator delete ( void *pCadaver ) { - return repeaterClient::pFreeList->allocate ( size ); + throw std::logic_error + ( "compiler is confused about placement delete" ); } -inline void repeaterClient::operator delete ( void *pCadaver, size_t size ) +inline void * repeaterClient::operator new ( size_t size, + tsFreeList < repeaterClient, 0x20 > & freeList ) { - repeaterClient::pFreeList->release ( pCadaver, size ); + return freeList.allocate ( size ); } -inline void repeaterClient::destroy () -{ - delete this; +#ifdef CXX_PLACEMENT_DELETE +inline void repeaterClient::operator delete ( void *pCadaver, + tsFreeList < repeaterClient, 0x20 > & freeList ) +{ + freeList.release ( pCadaver ); } +#endif inline unsigned short repeaterClient::port () const { @@ -315,7 +320,7 @@ bool repeaterClient::verify () // X aCC 361 /* * verifyClients() */ -static void verifyClients() +static void verifyClients ( tsFreeList < repeaterClient, 0x20 > & freeList ) { static tsDLList < repeaterClient > theClients; repeaterClient *pclient; @@ -325,7 +330,8 @@ static void verifyClients() theClients.add ( *pclient ); } else { - pclient->destroy (); + pclient->~repeaterClient (); + freeList.release ( pclient ); } } client_list.add ( theClients ); @@ -334,7 +340,8 @@ static void verifyClients() /* * fanOut() */ -static void fanOut ( const osiSockAddr &from, const void *pMsg, unsigned msgSize ) +static void fanOut ( const osiSockAddr & from, const void * pMsg, + unsigned msgSize, tsFreeList < repeaterClient, 0x20 > & freeList ) { static tsDLList < repeaterClient > theClients; repeaterClient *pclient; @@ -349,7 +356,8 @@ static void fanOut ( const osiSockAddr &from, const void *pMsg, unsigned msgSize if ( ! pclient->sendMessage ( pMsg, msgSize ) ) { if ( ! pclient->verify () ) { theClients.remove ( *pclient ); - pclient->destroy (); + pclient->~repeaterClient (); + freeList.release ( pclient ); } } } @@ -360,7 +368,8 @@ static void fanOut ( const osiSockAddr &from, const void *pMsg, unsigned msgSize /* * register_new_client() */ -static void register_new_client ( osiSockAddr &from ) +static void register_new_client ( osiSockAddr & from, + tsFreeList < repeaterClient, 0x20 > & freeList ) { int status; bool newClient = false; @@ -428,13 +437,14 @@ static void register_new_client ( osiSockAddr &from ) pNewClient = pclient.pointer (); } else { - pNewClient = new repeaterClient ( from ); + pNewClient = new ( freeList ) repeaterClient ( from ); if ( ! pNewClient ) { fprintf ( stderr, "%s: no memory for new client\n", __FILE__ ); return; } if ( ! pNewClient->connect () ) { - pclient->destroy (); + pNewClient->~repeaterClient (); + freeList.release ( pNewClient ); return; } client_list.add ( *pNewClient ); @@ -443,7 +453,8 @@ static void register_new_client ( osiSockAddr &from ) if ( ! pNewClient->sendConfirm () ) { client_list.remove ( *pNewClient ); - pNewClient->destroy (); + pNewClient->~repeaterClient (); + freeList.release ( pNewClient ); debugPrintf ( ( "Deleted repeater client=%u (error while sending ack)\n", epicsNTOH16 (from.ia.sin_port) ) ); } @@ -455,7 +466,7 @@ static void register_new_client ( osiSockAddr &from ) caHdr noop; memset ( (char *) &noop, '\0', sizeof ( noop ) ); noop.m_cmmd = epicsHTON16 ( CA_PROTO_VERSION ); - fanOut ( from, &noop, sizeof ( noop ) ); + fanOut ( from, &noop, sizeof ( noop ), freeList ); if ( newClient ) { /* @@ -469,7 +480,7 @@ static void register_new_client ( osiSockAddr &from ) * This is done here in order to avoid deleting a client * prior to sending its confirm message. */ - verifyClients (); + verifyClients ( freeList ); } } @@ -479,6 +490,7 @@ static void register_new_client ( osiSockAddr &from ) */ void ca_repeater () { + tsFreeList < repeaterClient, 0x20 > freeList; int size; SOCKET sock; osiSockAddr from; @@ -490,7 +502,7 @@ void ca_repeater () assert ( osiSockAttach() ); - port = envGetInetPortConfigParam ( &EPICS_CA_REPEATER_PORT, + port = envGetInetPortConfigParam ( & EPICS_CA_REPEATER_PORT, static_cast (CA_REPEATER_PORT) ); msr = makeSocket ( port, true ); @@ -541,7 +553,7 @@ void ca_repeater () */ if ( ( (size_t) size) >= sizeof (*pMsg) ) { if ( epicsNTOH16 ( pMsg->m_cmmd ) == REPEATER_REGISTER ) { - register_new_client ( from ); + register_new_client ( from, freeList ); /* * strip register client message @@ -559,11 +571,11 @@ void ca_repeater () } } else if ( size == 0 ) { - register_new_client ( from ); + register_new_client ( from, freeList ); continue; } - fanOut ( from, pMsg, size ); + fanOut ( from, pMsg, size, freeList ); } } diff --git a/src/ca/repeaterClient.h b/src/ca/repeaterClient.h index c5309d05e..822ca9d09 100644 --- a/src/ca/repeaterClient.h +++ b/src/ca/repeaterClient.h @@ -33,7 +33,8 @@ #endif #include "tsDLList.h" -#include "epicsSingleton.h" +#include "tsFreeList.h" +#include "cxxCompilerDepPlacementDelete.h" #ifdef repeaterClienth_restore_epicsExportSharedSymbols # define epicsExportSharedSymbols @@ -49,22 +50,27 @@ union osiSockAddr; class repeaterClient : public tsDLNode < repeaterClient > { public: repeaterClient ( const osiSockAddr & from ); + ~repeaterClient (); bool connect (); bool sendConfirm (); bool sendMessage ( const void *pBuf, unsigned bufSize ); - void destroy (); bool verify (); bool identicalAddress ( const osiSockAddr &from ); bool identicalPort ( const osiSockAddr &from ); - void * operator new ( size_t size ); - void operator delete ( void *pCadaver, size_t size ); -protected: - ~repeaterClient (); + void * operator new ( size_t size, + tsFreeList < repeaterClient, 0x20 > & ); +#ifdef CXX_PLACEMENT_DELETE + void operator delete ( void *, + tsFreeList < repeaterClient, 0x20 > & ); +#endif private: osiSockAddr from; SOCKET sock; unsigned short port () const; - static epicsSingleton < tsFreeList < class repeaterClient, 0x20 > > pFreeList; + void * operator new ( size_t size ); + void operator delete ( void * ); + void * operator new [] ( size_t size ); + void operator delete [] ( void * ); }; #endif // repeaterClienth diff --git a/src/ca/syncGroup.h b/src/ca/syncGroup.h index 5b271e9ef..3e29e1fa2 100644 --- a/src/ca/syncGroup.h +++ b/src/ca/syncGroup.h @@ -33,9 +33,9 @@ #include "tsDLList.h" #include "tsFreeList.h" -#include "epicsSingleton.h" #include "resourceLib.h" #include "epicsEvent.h" +#include "cxxCompilerDepPlacementDelete.h" #ifdef syncGrouph_restore_epicsExportSharedSymbols # define epicsExportSharedSymbols @@ -45,17 +45,6 @@ #include "cadef.h" #include "cacIO.h" -// does the compiler support placement delete -#if defined (_MSC_VER) && ( _MSC_VER >= 1200 ) -# define CASG_PLACEMENT_DELETE -#elif defined ( __HP_aCC ) && ( _HP_aCC > 033300 ) -# define CASG_PLACEMENT_DELETE -#elif defined ( __BORLANDC__ ) && ( __BORLANDC__ > 0x550 ) -# define CASG_PLACEMENT_DELETE -#else -# define CASG_PLACEMENT_DELETE -#endif - static const unsigned CASG_MAGIC = 0xFAB4CAFE; // used to control access to CASG's recycle routines which @@ -99,9 +88,11 @@ private: syncGroupReadNotify ( struct CASG &sgIn, chid, void *pValueIn ); void * operator new ( size_t ); void operator delete ( void * ); + void * operator new [] ( size_t ); + void operator delete [] ( void * ); void * operator new ( size_t, tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & ); -# if defined ( CASG_PLACEMENT_DELETE ) +# if defined ( CXX_PLACEMENT_DELETE ) void operator delete ( void *, tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & ); # endif @@ -129,9 +120,11 @@ private: syncGroupWriteNotify ( struct CASG &, chid ); void * operator new ( size_t ); void operator delete ( void * ); + void * operator new [] ( size_t ); + void operator delete [] ( void * ); void * operator new ( size_t, tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & ); -# if defined ( CASG_PLACEMENT_DELETE ) +# if defined ( CXX_PLACEMENT_DELETE ) void operator delete ( void *, tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & ); # endif @@ -158,8 +151,8 @@ template < class T > class sgAutoPtr; struct CASG : public chronIntIdRes < CASG >, private casgRecycle { public: CASG ( ca_client_context & cacIn ); + ~CASG (); bool ioComplete (); - void destroy (); bool verify () const; int block ( double timeout ); void reset (); @@ -167,16 +160,16 @@ public: void get ( chid pChan, unsigned type, arrayElementCount count, void * pValue ); void put ( chid pChan, unsigned type, arrayElementCount count, const void * pValue ); void completionNotify ( syncGroupNotify & ); - void * operator new ( size_t size ); - void operator delete ( void * pCadaver, size_t size ); int printf ( const char * pFormat, ... ); void exception ( int status, const char *pContext, const char *pFileName, unsigned lineNo ); void exception ( int status, const char *pContext, const char *pFileName, unsigned lineNo, oldChannelNotify &chan, unsigned type, arrayElementCount count, unsigned op ); -protected: - virtual ~CASG (); + void * operator new ( size_t size, tsFreeList < struct CASG, 128 > & ); +# if defined ( CXX_PLACEMENT_DELETE ) + void operator delete ( void *, tsFreeList < struct CASG, 128 > & ); +# endif private: tsDLList < syncGroupNotify > ioPendingList; tsDLList < syncGroupNotify > ioCompletedList; @@ -188,7 +181,6 @@ private: tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > freeListWriteOP; void recycleSyncGroupWriteNotify ( syncGroupWriteNotify &io ); void recycleSyncGroupReadNotify ( syncGroupReadNotify &io ); - static epicsSingleton < tsFreeList < struct CASG, 128 > > pFreeList; void destroyPendingIO ( syncGroupNotify * ); void destroyCompletedIO (); @@ -197,10 +189,29 @@ private: CASG ( const CASG & ); CASG & operator = ( const CASG & ); + void * operator new ( size_t size ); + void operator delete ( void * ); + void * operator new [] ( size_t size ); + void operator delete [] ( void * ); + friend class sgAutoPtr < syncGroupWriteNotify >; friend class sgAutoPtr < syncGroupReadNotify >; }; +inline void * CASG::operator new ( size_t size, + tsFreeList < struct CASG, 128 > & freeList ) +{ + return freeList.allocate ( size ); +} + +# if defined ( CXX_PLACEMENT_DELETE ) +inline void CASG::operator delete ( void * pCadaver, + tsFreeList < struct CASG, 128 > & freeList ) +{ + freeList.release ( pCadaver ); +} +#endif + inline bool syncGroupNotify::ioInitiated () const { return this->idIsValid; diff --git a/src/ca/syncgrp.cpp b/src/ca/syncgrp.cpp index a65371a5e..9e5a88d10 100644 --- a/src/ca/syncgrp.cpp +++ b/src/ca/syncgrp.cpp @@ -24,7 +24,7 @@ /* * ca_sg_create() */ -extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID *pgid ) // X aCC 361 +extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid ) // X aCC 361 { ca_client_context *pcac; int caStatus; @@ -35,14 +35,17 @@ extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID *pgid ) // X aCC 361 return caStatus; } - pcasg = new CASG ( *pcac ); - if ( pcasg ) { + try { + pcasg = new ( pcac->casgFreeList ) CASG ( *pcac ); *pgid = pcasg->getId (); return ECA_NORMAL; } - else { + catch ( std::bad_alloc & ) { return ECA_ALLOCMEM; } + catch ( ... ) { + return ECA_INTERNAL; + } } /* @@ -50,21 +53,23 @@ extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID *pgid ) // X aCC 361 */ extern "C" int epicsShareAPI ca_sg_delete ( const CA_SYNC_GID gid ) { - ca_client_context *pcac; - int caStatus; - CASG *pcasg; - - caStatus = fetchClientContext ( &pcac ); + ca_client_context * pcac; + int caStatus = fetchClientContext ( & pcac ); if ( caStatus != ECA_NORMAL ) { return caStatus; } - pcasg = pcac->lookupCASG ( gid ); + CASG * pcasg = pcac->lookupCASG ( gid ); if ( ! pcasg ) { return ECA_BADSYNCGRP; } - pcasg->destroy (); + pcasg->~CASG (); +# if defined ( CXX_PLACEMENT_DELETE ) && 0 + CASG::operator delete ( pcasg, pcac->casgFreeList ); +# else + pcac->casgFreeList.release ( pcasg ); +# endif return ECA_NORMAL; }