use placement new
This commit is contained in:
@@ -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" );
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user