use placement new

This commit is contained in:
Jeff Hill
2002-10-23 22:58:49 +00:00
parent 0817ad51ba
commit 37d239eb88
5 changed files with 105 additions and 66 deletions

View File

@@ -24,12 +24,12 @@
* 505 665 1831
*/
#include <stdexcept>
#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" );
}

View File

@@ -78,6 +78,8 @@
* received). -- Jeff
*/
#include <stdexcept>
#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 <unsigned short> (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 );
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}