use placement new

This commit is contained in:
Jeff Hill
2002-10-23 23:37:30 +00:00
parent 340e0c1d58
commit e36083d5ef
22 changed files with 712 additions and 455 deletions

View File

@@ -14,6 +14,8 @@
* (505) 665 1831
*/
#include <stdexcept>
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#define epicsExportSharedSymbols
@@ -24,19 +26,12 @@
#include "cac.h"
#include "sgAutoPtr.h"
epicsSingleton < tsFreeList < struct CASG, 128 > > CASG::pFreeList;
CASG::CASG ( ca_client_context &cacIn ) :
client ( cacIn ), magic ( CASG_MAGIC )
{
client.installCASG ( *this );
}
void CASG::destroy ()
{
delete this;
}
CASG::~CASG ()
{
if ( this->verify () ) {
@@ -243,24 +238,14 @@ void CASG::completionNotify ( syncGroupNotify & notify )
}
}
void CASG::recycleSyncGroupWriteNotify ( syncGroupWriteNotify &io )
void CASG::recycleSyncGroupWriteNotify ( syncGroupWriteNotify & io )
{
this->freeListWriteOP.release ( &io, sizeof ( io ) );
this->freeListWriteOP.release ( & io );
}
void CASG::recycleSyncGroupReadNotify ( syncGroupReadNotify &io )
void CASG::recycleSyncGroupReadNotify ( syncGroupReadNotify & io )
{
this->freeListReadOP.release ( &io, sizeof ( io ) );
}
void * CASG::operator new (size_t size)
{
return CASG::pFreeList->allocate ( size );
}
void CASG::operator delete (void *pCadaver, size_t size)
{
CASG::pFreeList->release ( pCadaver, size );
this->freeListReadOP.release ( & io );
}
int CASG::printf ( const char *pformat, ... )
@@ -291,5 +276,11 @@ void CASG::exception ( int status, const char *pContext,
lineNo, chan, type, count, op );
}
void CASG::operator delete ( void * pCadaver )
{
throw std::logic_error
( "compiler is confused about placement delete" );
}

View File

@@ -68,11 +68,9 @@ extern "C" void ca_init_client_context ( void * )
*/
int fetchClientContext ( ca_client_context **ppcac )
{
epicsThreadOnce ( &caClientContextIdOnce, ca_init_client_context, 0 );
if ( caClientContextId == 0 ) {
epicsThreadOnce ( &caClientContextIdOnce, ca_init_client_context, 0 );
if ( caClientContextId == 0 ) {
return ECA_ALLOCMEM;
}
return ECA_ALLOCMEM;
}
int status;
@@ -233,18 +231,20 @@ int epicsShareAPI ca_search_and_connect (
// extern "C"
int epicsShareAPI ca_create_channel (
const char *name_str, caCh * conn_func, void * puser,
const char * name_str, caCh * conn_func, void * puser,
capri priority, chid * chanptr )
{
ca_client_context *pcac;
int caStatus = fetchClientContext ( &pcac );
ca_client_context * pcac;
int caStatus = fetchClientContext ( & pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
try {
oldChannelNotify * pChanNotify = new oldChannelNotify (
* pcac, name_str, conn_func, puser, priority );
oldChannelNotify * pChanNotify =
new ( pcac->oldChannelNotifyFreeList )
oldChannelNotify ( *pcac, name_str,
conn_func, puser, priority );
// make sure that their chan pointer is set prior to
// calling connection call backs
*chanptr = pChanNotify;
@@ -272,9 +272,11 @@ int epicsShareAPI ca_create_channel (
// extern "C"
int epicsShareAPI ca_clear_channel ( chid pChan )
{
pChan->destroy ();
ca_client_context & cac = pChan->getClientCtx ();
cac.destroyChannel ( *pChan );
return ECA_NORMAL;
}
#include "autoPtrFreeList.h"
/*
* ca_array_get ()
@@ -283,24 +285,17 @@ int epicsShareAPI ca_clear_channel ( chid pChan )
int epicsShareAPI ca_array_get ( chtype type,
arrayElementCount count, chid pChan, void *pValue )
{
ca_client_context *pcac;
int caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
if ( type < 0 ) {
return ECA_BADTYPE;
}
unsigned tmpType = static_cast < unsigned > ( type );
autoPtrDestroy < getCopy > pNotify
( new getCopy ( *pcac, *pChan, tmpType, count, pValue ) );
if ( ! pNotify.get() ) {
return ECA_ALLOCMEM;
}
int caStatus;
try {
if ( type < 0 ) {
return ECA_BADTYPE;
}
unsigned tmpType = static_cast < unsigned > ( type );
autoPtrFreeList < getCopy > pNotify
( pChan->getClientCtx().getCopyFreeList,
new ( pChan->getClientCtx().getCopyFreeList )
getCopy ( pChan->getClientCtx(), *pChan,
tmpType, count, pValue ) );
pChan->read ( type, count, *pNotify );
pNotify.release ();
caStatus = ECA_NORMAL;
@@ -355,19 +350,16 @@ int epicsShareAPI ca_array_get_callback ( chtype type,
arrayElementCount count, chid pChan,
caEventCallBackFunc *pfunc, void *arg )
{
if ( type < 0 ) {
return ECA_BADTYPE;
}
unsigned tmpType = static_cast < unsigned > ( type );
autoPtrDestroy < getCallback > pNotify
( new getCallback ( *pChan, pfunc, arg ) );
if ( ! pNotify.get() ) {
return ECA_ALLOCMEM;
}
int caStatus;
try {
if ( type < 0 ) {
return ECA_BADTYPE;
}
unsigned tmpType = static_cast < unsigned > ( type );
autoPtrDestroy < getCallback > pNotify
( new ( pChan->getClientCtx().getCallbackFreeList )
getCallback ( *pChan, pfunc, arg ) );
pChan->read ( tmpType, count, *pNotify );
pNotify.release ();
caStatus = ECA_NORMAL;
@@ -421,19 +413,16 @@ int epicsShareAPI ca_array_get_callback ( chtype type,
int epicsShareAPI ca_array_put_callback ( chtype type, arrayElementCount count,
chid pChan, const void *pValue, caEventCallBackFunc *pfunc, void *usrarg )
{
if ( type < 0 ) {
return ECA_BADTYPE;
}
unsigned tmpType = static_cast < unsigned > ( type );
autoPtrDestroy < putCallback > pNotify
( new putCallback ( *pChan, pfunc, usrarg ) );
if ( ! pNotify.get() ) {
return ECA_ALLOCMEM;
}
int caStatus;
try {
if ( type < 0 ) {
return ECA_BADTYPE;
}
unsigned tmpType = static_cast < unsigned > ( type );
autoPtrFreeList < putCallback > pNotify
( pChan->getClientCtx().putCallbackFreeList,
new ( pChan->getClientCtx().putCallbackFreeList )
putCallback ( *pChan, pfunc, usrarg ) );
pChan->write ( tmpType, count, pValue, *pNotify );
pNotify.release ();
caStatus = ECA_NORMAL;
@@ -601,21 +590,19 @@ int epicsShareAPI ca_add_masked_array_event (
}
try {
autoPtrDestroy < oldSubscription > pSubsr
( new oldSubscription ( *pChan, pCallBack, pCallBackArg ) );
if ( pSubsr.get () ) {
evid pTmp = pSubsr.release ();
if ( monixptr ) {
*monixptr = pTmp;
}
pTmp->begin ( tmpType, count, mask );
// dont touch pTmp after this because
// the first callback might have canceled it
return ECA_NORMAL;
}
else {
return ECA_ALLOCMEM;
autoPtrFreeList < oldSubscription > pSubsr
( pChan->getClientCtx().subscriptionFreeList,
new ( pChan->getClientCtx().subscriptionFreeList )
oldSubscription ( *pChan,
pCallBack, pCallBackArg ) );
evid pTmp = pSubsr.release ();
if ( monixptr ) {
*monixptr = pTmp;
}
pTmp->begin ( tmpType, count, mask );
// dont touch pTmp after this because
// the first callback might have canceled it
return ECA_NORMAL;
}
catch ( cacChannel::badType & )
{
@@ -656,7 +643,10 @@ int epicsShareAPI ca_add_masked_array_event (
// extern "C"
int epicsShareAPI ca_clear_event ( evid pMon )
{
pMon->destroy ();
oldChannelNotify & chan = pMon->channel ();
ca_client_context & cac = chan.getClientCtx ();
pMon->ioCancel ();
cac.destroySubscription ( *pMon );
return ECA_NORMAL;
}

View File

@@ -19,7 +19,7 @@
* Author: Jeff Hill
*/
#include <stdexcept>
#include <limits.h>
#include <float.h>
@@ -30,18 +30,6 @@
#include "virtualCircuit.h"
#include "bhe.h"
epicsSingleton < tsFreeList < class bhe, 1024 > > bhe::pFreeList;
void * bhe::operator new ( size_t size )
{
return bhe::pFreeList->allocate ( size );
}
void bhe::operator delete ( void *pCadaver, size_t size )
{
bhe::pFreeList->release ( pCadaver, size );
}
/*
* set average to -1.0 so that when the next beacon
* occurs we can distinguish between:
@@ -236,12 +224,7 @@ void bhe::show ( unsigned /* level */ ) const
static_cast <const void *> ( this ), this->averagePeriod );
}
void bhe::destroy ()
{
delete this;
}
double bhe::period () const
double bhe::period () const throw ()
{
return this->averagePeriod;
}
@@ -263,3 +246,22 @@ void bhe::unregisterIIU ( tcpiiu & iiu )
this->averagePeriod = - DBL_MAX;
}
void bhe::operator delete ( void * )
{
throw std::logic_error
( "compiler is confused about placement delete?" );
}
void * bheFreeStore::allocate ( size_t size )
{
return freeList.allocate ( size );
}
void bheFreeStore::release ( void * pCadaver )
{
freeList.release ( pCadaver );
}
epicsShareFunc bheMemoryManager::~bheMemoryManager () {}

View File

@@ -30,8 +30,8 @@
#include "tsDLList.h"
#include "tsFreeList.h"
#include "epicsSingleton.h"
#include "epicsTime.h"
#include "cxxCompilerDepPlacementDelete.h"
#ifdef bhehEpicsExportSharedSymbols
# define epicsExportSharedSymbols
@@ -42,34 +42,75 @@
#include "caProto.h"
class tcpiiu;
class bheMemoryManager;
// using a pure abstract wrapper class around the free list avoids
// Tornado 2.0.1 GNU compiler bugs
class bheMemoryManager {
public:
epicsShareFunc virtual ~bheMemoryManager ();
virtual void * allocate ( size_t ) = 0;
virtual void release ( void * ) = 0;
};
class bhe : public tsSLNode < bhe >, public inetAddrID {
public:
epicsShareFunc bhe ( const epicsTime &initialTimeStamp,
unsigned initialBeaconNumber, const inetAddrID &addr );
epicsShareFunc bhe ( const epicsTime & initialTimeStamp,
unsigned initialBeaconNumber, const inetAddrID & addr ) throw ();
epicsShareFunc ~bhe ();
epicsShareFunc void destroy ();
epicsShareFunc bool updatePeriod ( const epicsTime & programBeginTime,
const epicsTime & currentTime, ca_uint32_t beaconNumber,
unsigned protocolRevision );
epicsShareFunc double period () const;
epicsShareFunc bool updatePeriod (
const epicsTime & programBeginTime,
const epicsTime & currentTime, ca_uint32_t beaconNumber,
unsigned protocolRevision );
epicsShareFunc double period () const throw ();
epicsShareFunc epicsTime updateTime () const;
epicsShareFunc void show ( unsigned level) const;
epicsShareFunc void registerIIU ( tcpiiu & );
epicsShareFunc void unregisterIIU ( tcpiiu & );
epicsShareFunc void * operator new ( size_t size );
epicsShareFunc void operator delete ( void *pCadaver, size_t size );
epicsShareFunc void * operator new ( size_t size,
bheMemoryManager & );
#ifdef CXX_PLACEMENT_DELETE
epicsShareFunc void operator delete ( void *,
bheMemoryManager & );
#endif
private:
tsDLList < tcpiiu > iiuList;
epicsTime timeStamp;
double averagePeriod;
ca_uint32_t lastBeaconNumber;
void beaconAnomalyNotify ();
static epicsSingleton < tsFreeList < class bhe, 1024 > > pFreeList;
bhe ( const bhe & );
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
// Tornado 2.0.1 GNU compiler bugs
class bheFreeStore : public bheMemoryManager {
public:
void * allocate ( size_t );
void release ( void * );
private:
tsFreeList < class bhe, 0x100 > freeList;
};
inline void * bhe::operator new ( size_t size,
bheMemoryManager & mgr )
{
return mgr.allocate ( size );
}
#ifdef CXX_PLACEMENT_DELETE
inline void bhe::operator delete ( void * pCadaver,
bheMemoryManager & mgr )
{
mgr.release ( pCadaver );
}
#endif
#endif // ifdef bheh

View File

@@ -46,6 +46,56 @@ ca_client_context::~ca_client_context ()
delete & this->clientCtx;
}
void ca_client_context::destroyChannel ( oldChannelNotify & chan )
{
chan.~oldChannelNotify ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
oldChannelNotify::operator delete ( & chan, this->oldChannelNotifyFreeList );
# else
this->oldChannelNotifyFreeList.release ( & chan );
# endif
}
void ca_client_context::destroyGetCopy ( getCopy & gc )
{
gc.~getCopy ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
getCopy::operator delete ( & gc, this->getCopyFreeList );
# else
this->getCopyFreeList.release ( & gc );
# endif
}
void ca_client_context::destroyGetCallback ( getCallback & gcb )
{
gcb.~getCallback ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
getCallback::operator delete ( & gcb, this->getCallbackFreeList );
# else
this->getCallbackFreeList.release ( & gcb );
# endif
}
void ca_client_context::destroyPutCallback ( putCallback & pcb )
{
pcb.~putCallback ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
putCallback::operator delete ( & pcb, this->putCallbackFreeList );
# else
this->putCallbackFreeList.release ( & pcb );
# endif
}
void ca_client_context::destroySubscription ( oldSubscription & os )
{
os.~oldSubscription ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
oldSubscription::operator delete ( & os, this->subscriptionFreeList );
# else
this->subscriptionFreeList.release ( & os );
# endif
}
void ca_client_context::changeExceptionEvent ( caExceptionHandler *pfunc, void *arg )
{
epicsGuard < ca_client_context_mutex > guard ( this->mutex );
@@ -225,21 +275,15 @@ void ca_client_context::attachToClientCtx ()
void ca_client_context::incrementOutstandingIO ( unsigned ioSeqNoIn )
{
epicsGuard < ca_client_context_mutex > guard ( this->mutex );
if ( this->ioSeqNo == ioSeqNoIn ) {
epicsGuard < ca_client_context_mutex > guard ( this->mutex );
if ( this->ioSeqNo == ioSeqNoIn ) {
assert ( this->pndRecvCnt < UINT_MAX );
this->pndRecvCnt++;
}
assert ( this->pndRecvCnt < UINT_MAX );
this->pndRecvCnt++;
}
}
void ca_client_context::decrementOutstandingIO ( unsigned ioSeqNoIn )
{
if ( this->ioSeqNo != ioSeqNoIn ) {
return;
}
bool signalNeeded;
{
epicsGuard < ca_client_context_mutex > guard ( this->mutex );

View File

@@ -23,11 +23,10 @@
#include <new>
#include "epicsMemory.h"
#include "epicsGuard.h"
#include "epicsVersion.h"
#include "osiProcess.h"
#include "osiSigPipeIgnore.h"
#include "epicsSignal.h"
#include "envDefs.h"
#define epicsExportSharedSymbols
@@ -43,6 +42,7 @@
#include "udpiiu.h"
#include "bhe.h"
#include "net_convert.h"
#include "autoPtrDestroy.h"
static const char *id = "@(#) " EPICS_VERSION_STRING ", CA Portable Server Library" __DATE__;
@@ -137,6 +137,7 @@ cac::cac ( cacNotify & notifyIn, bool enablePreemptiveCallbackIn ) :
programBeginTime ( epicsTime::getCurrent() ),
connTMO ( CA_CONN_VERIFY_PERIOD ),
cbMutex ( ! enablePreemptiveCallbackIn ),
globalServiceList ( globalServiceListCAC ),
timerQueue ( epicsTimerQueueActive::allocate ( false,
lowestPriorityLevelAbove(epicsThreadGetPrioritySelf()) ) ),
pUserName ( 0 ),
@@ -158,7 +159,7 @@ cac::cac ( cacNotify & notifyIn, bool enablePreemptiveCallbackIn ) :
try {
long status;
installSigPipeIgnore ();
epicsSignalInstallSigPipeIgnore ();
{
char tmp[256];
@@ -272,7 +273,16 @@ cac::~cac ()
delete [] this->pUserName;
this->beaconTable.traverse ( &bhe::destroy );
tsSLList < bhe > tmpBeaconList;
this->beaconTable.removeAll ( tmpBeaconList );
while ( bhe * pBHE = tmpBeaconList.get() ) {
pBHE->~bhe ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
bhe::operator delete ( pBHE, this->bheFreeList );
# else
this->bheFreeList.release ( pBHE );
# endif
}
osiSockRelease ();
@@ -401,10 +411,16 @@ void cac::beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime,
* time that we have seen a server's beacon
* shortly after the program started up)
*/
pBHE = new bhe ( currentTime, beaconNumber, addr );
pBHE = new ( this->bheFreeList )
bhe ( currentTime, beaconNumber, addr );
if ( pBHE ) {
if ( this->beaconTable.add ( *pBHE ) < 0 ) {
pBHE->destroy ();
pBHE->~bhe ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
bhe::operator delete ( pBHE, this->bheFreeList );
# else
this->bheFreeList.release ( pBHE );
# endif
}
}
return;
@@ -453,8 +469,6 @@ void cac::registerService ( cacService & service )
cacChannel & cac::createChannel ( const char * pName,
cacChannelNotify & chan, cacChannel::priLev pri )
{
cacChannel *pIO;
if ( pri > cacChannel::priorityMax ) {
throw cacChannel::badPriority ();
}
@@ -463,24 +477,23 @@ cacChannel & cac::createChannel ( const char * pName,
throw cacChannel::badString ();
}
pIO = this->services.createChannel ( pName, chan, pri );
if ( ! pIO ) {
pIO = pGlobalServiceListCAC->createChannel ( pName, chan, pri );
if ( ! pIO ) {
if ( ! this->pudpiiu ) {
epicsGuard < cacMutex > guard ( this->mutex );
if ( ! this->pudpiiu ) {
this->pudpiiu = new udpiiu ( this->timerQueue, this->cbMutex, *this );
}
}
autoPtrDestroy < cacChannel >
pIO ( this->services.createChannel ( pName, chan, pri ) );
if ( pIO.get() == 0 ) {
pIO = this->globalServiceList->createChannel ( pName, chan, pri );
if ( pIO.get() == 0 ) {
epicsGuard < cacMutex > guard ( this->mutex );
epics_auto_ptr < nciu > pNetChan
( new nciu ( *this, *this->pudpiiu, chan, pName, pri ) );
if ( ! this->pudpiiu ) {
this->pudpiiu = new udpiiu ( this->timerQueue, this->cbMutex, *this );
}
autoPtrDestroy < nciu > pNetChan
( new ( this->channelFreeList )
nciu ( *this, *this->pudpiiu, chan, pName, pri ) );
this->chanTable.add ( *pNetChan );
return *pNetChan.release ();
return * pNetChan.release ();
}
}
return *pIO;
return * pIO.release ();
}
void cac::repeaterSubscribeConfirmNotify ()
@@ -524,11 +537,10 @@ bool cac::lookupChannelAndTransferToTCP (
if ( ! sockAddrAreIdentical ( &addr, &chanAddr ) ) {
char acc[64];
pChan->getPIIU()->hostName ( acc, sizeof ( acc ) );
msgForMultiplyDefinedPV *pMsg = new msgForMultiplyDefinedPV (
this->cbMutex, *this, pChan->pName (), acc, addr );
if ( pMsg ) {
this->ipAddrToAsciiAsynchronousRequestInstall ( *pMsg );
}
msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList )
msgForMultiplyDefinedPV (
this->cbMutex, *this, pChan->pName (), acc, addr );
this->ipAddrToAsciiAsynchronousRequestInstall ( *pMsg );
}
return true;
}
@@ -547,23 +559,13 @@ bool cac::lookupChannelAndTransferToTCP (
try {
epics_auto_ptr < tcpiiu > pnewiiu ( new tcpiiu (
*this, this->cbMutex, this->connTMO, this->timerQueue,
addr, minorVersionNumber, this->ipToAEngine,
pChan->getPriority() ) );
if ( pnewiiu.get() == 0 ) {
return true;
}
addr, this->comBufMemMgr, minorVersionNumber,
this->ipToAEngine, pChan->getPriority() ) );
bhe * pBHE = this->beaconTable.lookup ( addr.ia );
if ( ! pBHE ) {
epics_auto_ptr < bhe > pNewBHE ( new bhe ( epicsTime (), 0u, addr.ia ) );
if ( pNewBHE.get () ) {
if ( this->beaconTable.add ( *pNewBHE ) >= 0 ) {
pBHE = pNewBHE.release ();
}
else {
return true;
}
}
else {
pBHE = new ( this->bheFreeList )
bhe ( epicsTime (), 0u, addr.ia );
if ( this->beaconTable.add ( *pBHE ) < 0 ) {
return true;
}
}
@@ -572,8 +574,11 @@ bool cac::lookupChannelAndTransferToTCP (
piiu = pnewiiu.release ();
newIIU = true;
}
catch ( std::bad_alloc & ) {
return true;
}
catch ( ... ) {
this->printf ( "CAC: Exception during virtual circuit creation\n" );
this->printf ( "CAC: Unexpected exception during virtual circuit creation\n" );
return true;
}
}
@@ -625,7 +630,7 @@ bool cac::lookupChannelAndTransferToTCP (
return true;
}
void cac::uninstallChannel ( nciu & chan )
void cac::destroyChannel ( nciu & chan )
{
tsDLList < baseNMIU > tmpList;
@@ -707,6 +712,14 @@ void cac::uninstallChannel ( nciu & chan )
chan.getPIIU()->uninstallChan ( guard, chan );
}
}
// run channel's destructor and return it to the free list
chan.~nciu ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
nciu::operator delete ( & chan, this->channelFreeList );
# else
this->channelFreeList.release ( & chan );
# endif
}
int cac::printf ( const char *pformat, ... ) const
@@ -1043,17 +1056,17 @@ void cac::disconnectAllIO ( epicsGuard < cacMutex > &locker, nciu & chan, bool e
void cac::recycleReadNotifyIO ( netReadNotifyIO &io )
{
this->freeListReadNotifyIO.release ( &io, sizeof ( io ) );
this->freeListReadNotifyIO.release ( & io );
}
void cac::recycleWriteNotifyIO ( netWriteNotifyIO &io )
{
this->freeListWriteNotifyIO.release ( &io, sizeof ( io ) );
this->freeListWriteNotifyIO.release ( & io );
}
void cac::recycleSubscription ( netSubscription &io )
{
this->freeListSubscription.release ( &io, sizeof ( io ) );
this->freeListSubscription.release ( & io );
}
cacChannel::ioid
@@ -1574,3 +1587,13 @@ void cac::initiateConnect ( nciu & chan )
this->pudpiiu->installChannel ( chan );
}
void *cacComBufMemoryManager::allocate ( size_t size ) throw ( std::bad_alloc )
{
return this->freeList.allocate ( size );
}
void cacComBufMemoryManager::release ( void * pCadaver ) throw ()
{
return this->freeList.release ( pCadaver );
}

View File

@@ -41,11 +41,12 @@
# include "shareLib.h"
#endif
#include "nciu.h"
#include "comBuf.h"
#include "bhe.h"
#include "cacIO.h"
#include "netIO.h"
#include "localHostName.h"
class netWriteNotifyIO;
class netReadNotifyIO;
@@ -94,6 +95,15 @@ private:
epicsMutex mutex;
};
class cacComBufMemoryManager : public comBufMemoryManager
{
public:
void * allocate ( size_t ) throw ( std::bad_alloc );
void release ( void * ) throw ();
private:
tsFreeList < class comBuf, 0x20 > freeList;
};
class cacDisconnectChannelPrivate { // X aCC 655
public:
virtual void disconnectChannel ( epicsGuard < callbackMutex > &,
@@ -128,7 +138,7 @@ public:
unsigned minorVersionNumber, const osiSockAddr &,
const epicsTime & currentTime );
void uninstallChannel ( nciu & );
void destroyChannel ( nciu & );
cacChannel & createChannel ( const char *name_str,
cacChannelNotify &chan, cacChannel::priLev pri );
void registerService ( cacService &service );
@@ -188,10 +198,10 @@ public:
void uninstallIIU ( tcpiiu & );
private:
ipAddrToAsciiEngine ipToAEngine;
cacServiceList services;
chronIntIdResTable
< nciu > chanTable;
localHostName hostNameCache;
ipAddrToAsciiEngine ipToAEngine;
cacServiceList services;
chronIntIdResTable < nciu > chanTable;
//
// !!!! There is at this point no good reason
// !!!! to maintain one IO table for all types of
@@ -204,41 +214,46 @@ private:
// !!!! approach would also probably be safer in
// !!!! terms of detecting damaged protocol.
//
chronIntIdResTable
< baseNMIU > ioTable;
chronIntIdResTable
< CASG > sgTable;
resTable
< bhe, inetAddrID > beaconTable;
resTable
< tcpiiu, caServerID > serverTable;
chronIntIdResTable < baseNMIU > ioTable;
chronIntIdResTable < CASG > sgTable;
resTable < bhe, inetAddrID > beaconTable;
resTable < tcpiiu, caServerID > serverTable;
tsFreeList
< class netReadNotifyIO, 1024, epicsMutexNOOP >
freeListReadNotifyIO;
freeListReadNotifyIO;
tsFreeList
< class netWriteNotifyIO, 1024, epicsMutexNOOP >
freeListWriteNotifyIO;
freeListWriteNotifyIO;
tsFreeList
< class netSubscription, 1024, epicsMutexNOOP >
freeListSubscription;
epicsTime programBeginTime;
double connTMO;
freeListSubscription;
tsFreeList < class nciu, 1024 > channelFreeList;
tsFreeList
< class msgForMultiplyDefinedPV, 16 >
mdpvFreeList;
cacComBufMemoryManager comBufMemMgr;
bheFreeStore bheFreeList;
epicsTime programBeginTime;
double connTMO;
// **** lock hierarchy ****
// callback lock must always be acquired before
// the primary mutex if both locks are needed
callbackMutex cbMutex;
mutable cacMutex mutex;
epicsEvent iiuUninstall;
epicsTimerQueueActive & timerQueue;
char * pUserName;
class udpiiu * pudpiiu;
void * tcpSmallRecvBufFreeList;
void * tcpLargeRecvBufFreeList;
cacNotify & notify;
epicsThreadId initializingThreadsId;
unsigned initializingThreadsPriority;
unsigned maxRecvBytesTCP;
bool preemptiveCallbackEnabled;
callbackMutex cbMutex;
mutable cacMutex mutex;
epicsEvent iiuUninstall;
epicsSingleton
< cacServiceList >::reference
globalServiceList;
epicsTimerQueueActive & timerQueue;
char * pUserName;
class udpiiu * pudpiiu;
void * tcpSmallRecvBufFreeList;
void * tcpLargeRecvBufFreeList;
cacNotify & notify;
epicsThreadId initializingThreadsId;
unsigned initializingThreadsPriority;
unsigned maxRecvBytesTCP;
bool preemptiveCallbackEnabled;
void privateUninstallIIU ( epicsGuard < callbackMutex > &, tcpiiu &iiu );
void run ();

View File

@@ -20,6 +20,7 @@
* Author: Jeff Hill
*/
#include <stdexcept>
#include <float.h>
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
@@ -72,7 +73,9 @@ bool cacChannel::connected () const
void cacChannel::hostName ( char *pBuf, unsigned bufLength ) const
{
if ( bufLength ) {
pLocalHostNameAtLoadTime->copy ( pBuf, bufLength );
epicsSingleton < localHostName >::reference
ref ( localHostNameAtLoadTime );
ref->copy ( pBuf, bufLength );
}
}
@@ -80,7 +83,22 @@ void cacChannel::hostName ( char *pBuf, unsigned bufLength ) const
// the default is to assume that it is a locally hosted channel
const char * cacChannel::pHostName () const
{
return pLocalHostNameAtLoadTime->pointer ();
epicsSingleton < localHostName >::reference
ref ( localHostNameAtLoadTime );
return ref->pointer ();
}
// ms visual c++ 7.0 appears to require these when they
// are not called?
void cacChannel::operator delete ( void * )
{
throw std::logic_error (
"why is the compiler calling cacChannel::operator delete?" );
}
void cacChannel::operator delete [] ( void * )
{
throw std::logic_error (
"why is the compiler calling cacChannel::operator delete?" );
}

View File

@@ -159,8 +159,8 @@ public:
cacChannel ( cacChannelNotify & );
cacChannelNotify & notify () const;
virtual ~cacChannel () = 0;
virtual const char *pName () const = 0;
virtual void destroy () = 0;
virtual const char * pName () const = 0; // not thread safe
virtual void show ( unsigned level ) const = 0;
virtual void initiateConnect () = 0;
virtual ioStatus read ( unsigned type, arrayElementCount count,
@@ -181,8 +181,7 @@ public:
virtual bool ca_v42_ok () const; // defaults to true
virtual bool connected () const; // defaults to true
virtual void hostName (
char *pBuf, unsigned bufLength ) const; // defaults to local host name
char * pBuf, unsigned bufLength ) const; // defaults to local host name
virtual const char * pHostName () const;
// exceptions
@@ -198,10 +197,17 @@ public:
class msgBodyCacheTooSmall {}; // hopefully this one goes away in the future
class requestTimedOut {};
protected:
virtual ~cacChannel () = 0;
private:
cacChannelNotify & callback;
cacChannel ( const cacChannel & );
cacChannel & operator = ( const cacChannel & );
void * operator new ( size_t );
void * operator new [] ( size_t );
void operator delete ( void * );
void operator delete [] ( void * );
};
class cacNotify { // X aCC 655
@@ -244,7 +250,7 @@ private:
};
template < class T > class epicsSingleton;
epicsShareExtern epicsSingleton < cacServiceList > pGlobalServiceListCAC;
epicsShareExtern epicsSingleton < cacServiceList > globalServiceListCAC;
epicsShareFunc int epicsShareAPI ca_register_service ( cacService *pService );

View File

@@ -30,7 +30,7 @@
#include "epicsGuard.h"
#include "cacIO.h"
epicsShareDef epicsSingleton < cacServiceList > pGlobalServiceListCAC;
epicsShareDef epicsSingleton < cacServiceList > globalServiceListCAC;
cacServiceList::cacServiceList ()
{

View File

@@ -31,8 +31,29 @@
#include "udpiiu.h"
#include "inetAddrID.h"
// using a wrapper class around the free list avoids
// Tornado 2.0.1 GNU compiler bugs
class bheFreeStoreMgr : public bheMemoryManager {
public:
void * allocate ( size_t );
void release ( void * );
private:
tsFreeList < class bhe, 0x100 > freeList;
};
void * bheFreeStoreMgr::allocate ( size_t size )
{
return freeList.allocate ( size );
}
void bheFreeStoreMgr::release ( void * pCadaver )
{
freeList.release ( pCadaver );
}
int main ( int argc, char ** argv )
{
bheFreeStoreMgr bheFreeList;
epicsTime programBeginTime = epicsTime::getCurrent ();
bool validCommandLine = false;
unsigned interest = 0u;
@@ -230,10 +251,12 @@ int main ( int argc, char ** argv )
* time that we have seen a server's beacon
* shortly after the program started up)
*/
pBHE = new bhe ( currentTime, beaconNumber, ina );
pBHE = new ( bheFreeList )
bhe ( currentTime, beaconNumber, ina );
if ( pBHE ) {
if ( beaconTable.add ( *pBHE ) < 0 ) {
pBHE->destroy ();
pBHE->~bhe ();
bheFreeList.release ( pBHE );
}
}
}

View File

@@ -22,14 +22,14 @@
* johill@lanl.gov
*/
#include <stdexcept>
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#include "iocinf.h"
#include "comBuf.h"
epicsSingleton < tsFreeList < class comBuf, 0x20 > > comBuf::pFreeList;
bool comBuf::flushToWire ( wireSendAdapter & wire )
bool comBuf::flushToWire ( wireSendAdapter & wire ) throw ()
{
unsigned occupied = this->occupiedBytes ();
while ( occupied ) {
@@ -44,7 +44,7 @@ bool comBuf::flushToWire ( wireSendAdapter & wire )
return true;
}
unsigned comBuf::push ( const epicsInt16 * pValue, unsigned nElem )
unsigned comBuf::push ( const epicsInt16 * pValue, unsigned nElem ) throw ()
{
nElem = this->unoccupiedElem ( sizeof (*pValue), nElem );
for ( unsigned i = 0u; i < nElem; i++ ) {
@@ -56,7 +56,7 @@ unsigned comBuf::push ( const epicsInt16 * pValue, unsigned nElem )
return nElem;
}
unsigned comBuf::push ( const epicsUInt16 * pValue, unsigned nElem )
unsigned comBuf::push ( const epicsUInt16 * pValue, unsigned nElem ) throw ()
{
nElem = this->unoccupiedElem ( sizeof (*pValue), nElem );
for ( unsigned i = 0u; i < nElem; i++ ) {
@@ -68,7 +68,7 @@ unsigned comBuf::push ( const epicsUInt16 * pValue, unsigned nElem )
return nElem;
}
unsigned comBuf::push ( const epicsInt32 * pValue, unsigned nElem )
unsigned comBuf::push ( const epicsInt32 * pValue, unsigned nElem ) throw ()
{
nElem = this->unoccupiedElem ( sizeof (*pValue), nElem );
for ( unsigned i = 0u; i < nElem; i++ ) {
@@ -84,7 +84,7 @@ unsigned comBuf::push ( const epicsInt32 * pValue, unsigned nElem )
return nElem;
}
unsigned comBuf::push ( const epicsUInt32 * pValue, unsigned nElem )
unsigned comBuf::push ( const epicsUInt32 * pValue, unsigned nElem ) throw ()
{
nElem = this->unoccupiedElem ( sizeof (*pValue), nElem );
for ( unsigned i = 0u; i < nElem; i++ ) {
@@ -100,7 +100,7 @@ unsigned comBuf::push ( const epicsUInt32 * pValue, unsigned nElem )
return nElem;
}
unsigned comBuf::push ( const epicsFloat32 * pValue, unsigned nElem )
unsigned comBuf::push ( const epicsFloat32 * pValue, unsigned nElem ) throw ()
{
nElem = this->unoccupiedElem ( sizeof (*pValue), nElem );
for ( unsigned i = 0u; i < nElem; i++ ) {
@@ -111,7 +111,7 @@ unsigned comBuf::push ( const epicsFloat32 * pValue, unsigned nElem )
return nElem;
}
unsigned comBuf::push ( const epicsFloat64 * pValue, unsigned nElem )
unsigned comBuf::push ( const epicsFloat64 * pValue, unsigned nElem ) throw ()
{
nElem = this->unoccupiedElem ( sizeof (*pValue), nElem );
for ( unsigned i = 0u; i < nElem; i++ ) {
@@ -124,7 +124,17 @@ unsigned comBuf::push ( const epicsFloat64 * pValue, unsigned nElem )
// throwing the exception from a function that isnt inline
// shrinks the GNU compiled object code
void comBuf::throwInsufficentBytesException ()
void comBuf::throwInsufficentBytesException ()
throw ( insufficentBytesAvailable )
{
throw insufficentBytesAvailable ();
}
void comBuf::operator delete ( void *pCadaver )
throw ( std::logic_error )
{
throw std::logic_error
( "compiler is confused about placement delete" );
}
comBufMemoryManager::~comBufMemoryManager () {}

View File

@@ -32,148 +32,164 @@
#include "epicsAssert.h"
#include "epicsTypes.h"
#include "tsFreeList.h"
#include "epicsSingleton.h"
#include "tsDLList.h"
#include "osiWireFormat.h"
#include "cxxCompilerDepPlacementDelete.h"
static const unsigned comBufSize = 0x4000;
class wireSendAdapter { // X aCC 655
// this wrapper avoids Tornado 2.0.1 compiler bugs
class comBufMemoryManager {
public:
virtual unsigned sendBytes ( const void *pBuf,
unsigned nBytesInBuf ) = 0;
virtual ~comBufMemoryManager ();
virtual void * allocate ( size_t )
throw ( std::bad_alloc ) = 0;
virtual void release ( void * )
throw () = 0;
};
class wireRecvAdapter { // X aCC 655
class wireSendAdapter { // X aCC 655
public:
virtual unsigned sendBytes ( const void *pBuf,
unsigned nBytesInBuf ) throw () = 0;
};
class wireRecvAdapter { // X aCC 655
public:
virtual unsigned recvBytes ( void *pBuf,
unsigned nBytesInBuf ) = 0;
unsigned nBytesInBuf ) throw () = 0;
};
class comBuf : public tsDLNode < comBuf > {
public:
comBuf ();
void destroy ();
unsigned unoccupiedBytes () const;
unsigned occupiedBytes () const;
unsigned uncommittedBytes () const;
static unsigned capacityBytes ();
void clear ();
unsigned copyInBytes ( const void *pBuf, unsigned nBytes );
unsigned push ( comBuf & );
bool push ( const epicsInt8 & value );
bool push ( const epicsUInt8 & value );
bool push ( const epicsInt16 & value );
bool push ( const epicsUInt16 & value );
bool push ( const epicsInt32 & value );
bool push ( const epicsUInt32 & value );
bool push ( const epicsFloat32 & value );
bool push ( const epicsFloat64 & value );
bool push ( const epicsOldString & value );
unsigned push ( const epicsInt8 *pValue, unsigned nElem );
unsigned push ( const epicsUInt8 *pValue, unsigned nElem );
unsigned push ( const epicsInt16 *pValue, unsigned nElem );
unsigned push ( const epicsUInt16 *pValue, unsigned nElem );
unsigned push ( const epicsInt32 *pValue, unsigned nElem );
unsigned push ( const epicsUInt32 *pValue, unsigned nElem );
unsigned push ( const epicsFloat32 *pValue, unsigned nElem );
unsigned push ( const epicsFloat64 *pValue, unsigned nElem );
unsigned push ( const epicsOldString *pValue, unsigned nElem );
void commitIncomming ();
void clearUncommittedIncomming ();
bool copyInAllBytes ( const void *pBuf, unsigned nBytes );
unsigned copyOutBytes ( void *pBuf, unsigned nBytes );
bool copyOutAllBytes ( void *pBuf, unsigned nBytes );
unsigned removeBytes ( unsigned nBytes );
void * operator new ( size_t size );
void operator delete ( void *pCadaver, size_t size );
bool flushToWire ( wireSendAdapter & );
unsigned fillFromWire ( wireRecvAdapter & );
epicsUInt8 popUInt8 ();
epicsUInt16 popUInt16 ();
epicsUInt32 popUInt32 ();
static void throwInsufficentBytesException ();
class insufficentBytesAvailable {};
protected:
~comBuf ();
comBuf () throw();
unsigned unoccupiedBytes () const throw();
unsigned occupiedBytes () const throw();
unsigned uncommittedBytes () const throw();
static unsigned capacityBytes () throw();
void clear () throw ();
unsigned copyInBytes ( const void *pBuf, unsigned nBytes ) throw();
unsigned push ( comBuf & ) throw();
bool push ( const epicsInt8 & value ) throw();
bool push ( const epicsUInt8 & value ) throw();
bool push ( const epicsInt16 & value ) throw();
bool push ( const epicsUInt16 & value ) throw();
bool push ( const epicsInt32 & value ) throw();
bool push ( const epicsUInt32 & value ) throw();
bool push ( const epicsFloat32 & value ) throw();
bool push ( const epicsFloat64 & value ) throw();
bool push ( const epicsOldString & value ) throw();
unsigned push ( const epicsInt8 *pValue, unsigned nElem ) throw();
unsigned push ( const epicsUInt8 *pValue, unsigned nElem ) throw();
unsigned push ( const epicsInt16 *pValue, unsigned nElem ) throw();
unsigned push ( const epicsUInt16 *pValue, unsigned nElem ) throw();
unsigned push ( const epicsInt32 *pValue, unsigned nElem ) throw();
unsigned push ( const epicsUInt32 *pValue, unsigned nElem ) throw();
unsigned push ( const epicsFloat32 *pValue, unsigned nElem ) throw();
unsigned push ( const epicsFloat64 *pValue, unsigned nElem ) throw();
unsigned push ( const epicsOldString *pValue, unsigned nElem ) throw();
void commitIncomming () throw();
void clearUncommittedIncomming () throw();
bool copyInAllBytes ( const void *pBuf, unsigned nBytes ) throw();
unsigned copyOutBytes ( void *pBuf, unsigned nBytes ) throw();
bool copyOutAllBytes ( void *pBuf, unsigned nBytes ) throw();
unsigned removeBytes ( unsigned nBytes ) throw();
bool flushToWire ( wireSendAdapter & ) throw ();
unsigned fillFromWire ( wireRecvAdapter & ) throw ();
epicsUInt8 popUInt8 ()
throw ( comBuf::insufficentBytesAvailable );
epicsUInt16 popUInt16 ()
throw ( comBuf::insufficentBytesAvailable );
epicsUInt32 popUInt32 ()
throw ( comBuf::insufficentBytesAvailable );
static void throwInsufficentBytesException ()
throw ( comBuf::insufficentBytesAvailable );
void * operator new ( size_t size,
comBufMemoryManager & ) throw ( std::bad_alloc );
# ifdef CXX_PLACEMENT_DELETE
void operator delete ( void *,
comBufMemoryManager & ) throw ();
# endif
private:
unsigned commitIndex;
unsigned nextWriteIndex;
unsigned nextReadIndex;
epicsUInt8 buf [ comBufSize ];
unsigned unoccupiedElem ( unsigned elemSize, unsigned nElem );
unsigned occupiedElem ( unsigned elemSize, unsigned nElem );
static epicsSingleton < tsFreeList < class comBuf, 0x20 > > pFreeList;
unsigned unoccupiedElem ( unsigned elemSize, unsigned nElem ) throw ();
unsigned occupiedElem ( unsigned elemSize, unsigned nElem ) throw ();
void * operator new ( size_t size ) throw ( std::bad_alloc );
void operator delete ( void * ) throw ( std::logic_error );
void * operator new [] ( size_t size ) throw ( std::bad_alloc );
void operator delete [] ( void * ) throw ( std::logic_error );
};
inline comBuf::comBuf () : commitIndex ( 0u ),
inline void * comBuf::operator new ( size_t size,
comBufMemoryManager & mgr )
throw ( std::bad_alloc )
{
return mgr.allocate ( size );
}
#ifdef CXX_PLACEMENT_DELETE
inline void comBuf::operator delete ( void * pCadaver,
comBufMemoryManager & mgr ) throw ()
{
mgr.release ( pCadaver );
}
#endif
inline comBuf::comBuf () throw () : commitIndex ( 0u ),
nextWriteIndex ( 0u ), nextReadIndex ( 0u )
{
}
inline comBuf::~comBuf ()
{
}
inline void comBuf::destroy ()
{
delete this;
}
inline void comBuf::clear ()
inline void comBuf::clear () throw ()
{
this->commitIndex = 0u;
this->nextWriteIndex = 0u;
this->nextReadIndex = 0u;
}
inline void * comBuf::operator new ( size_t size )
{
return comBuf::pFreeList->allocate ( size );
}
inline void comBuf::operator delete ( void *pCadaver, size_t size )
{
comBuf::pFreeList->release ( pCadaver, size );
}
inline unsigned comBuf::unoccupiedBytes () const
inline unsigned comBuf::unoccupiedBytes () const throw ()
{
return sizeof ( this->buf ) - this->nextWriteIndex;
}
inline unsigned comBuf::occupiedBytes () const
inline unsigned comBuf::occupiedBytes () const throw ()
{
return this->commitIndex - this->nextReadIndex;
}
inline unsigned comBuf::uncommittedBytes () const
inline unsigned comBuf::uncommittedBytes () const throw ()
{
return this->nextWriteIndex - this->commitIndex;
}
inline unsigned comBuf::push ( comBuf & bufIn )
inline unsigned comBuf::push ( comBuf & bufIn ) throw ()
{
unsigned nBytes = this->copyInBytes ( &bufIn.buf[bufIn.nextReadIndex],
bufIn.commitIndex - bufIn.nextReadIndex );
unsigned nBytes = this->copyInBytes (
& bufIn.buf[ bufIn.nextReadIndex ],
bufIn.commitIndex - bufIn.nextReadIndex );
bufIn.nextReadIndex += nBytes;
return nBytes;
}
inline unsigned comBuf::capacityBytes ()
inline unsigned comBuf::capacityBytes () throw ()
{
return comBufSize;
}
inline unsigned comBuf::fillFromWire ( wireRecvAdapter & wire )
inline unsigned comBuf::fillFromWire ( wireRecvAdapter & wire ) throw ()
{
unsigned nNewBytes = wire.recvBytes ( &this->buf[this->nextWriteIndex],
sizeof ( this->buf ) - this->nextWriteIndex );
unsigned nNewBytes = wire.recvBytes (
& this->buf[this->nextWriteIndex],
sizeof ( this->buf ) - this->nextWriteIndex );
this->nextWriteIndex += nNewBytes;
return nNewBytes;
}
inline unsigned comBuf::unoccupiedElem ( unsigned elemSize, unsigned nElem )
inline unsigned comBuf::unoccupiedElem ( unsigned elemSize, unsigned nElem ) throw ()
{
unsigned avail = this->unoccupiedBytes ();
if ( elemSize * nElem > avail ) {
@@ -182,7 +198,7 @@ inline unsigned comBuf::unoccupiedElem ( unsigned elemSize, unsigned nElem )
return nElem;
}
inline bool comBuf::push ( const epicsInt8 & value )
inline bool comBuf::push ( const epicsInt8 & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -192,7 +208,7 @@ inline bool comBuf::push ( const epicsInt8 & value )
return true;
}
inline bool comBuf::push ( const epicsUInt8 & value )
inline bool comBuf::push ( const epicsUInt8 & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -201,7 +217,7 @@ inline bool comBuf::push ( const epicsUInt8 & value )
return true;
}
inline bool comBuf::push ( const epicsInt16 & value )
inline bool comBuf::push ( const epicsInt16 & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -213,7 +229,7 @@ inline bool comBuf::push ( const epicsInt16 & value )
return true;
}
inline bool comBuf::push ( const epicsUInt16 & value )
inline bool comBuf::push ( const epicsUInt16 & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -225,7 +241,7 @@ inline bool comBuf::push ( const epicsUInt16 & value )
return true;
}
inline bool comBuf::push ( const epicsInt32 & value )
inline bool comBuf::push ( const epicsInt32 & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -241,7 +257,7 @@ inline bool comBuf::push ( const epicsInt32 & value )
return true;
}
inline bool comBuf::push ( const epicsUInt32 & value )
inline bool comBuf::push ( const epicsUInt32 & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -257,7 +273,7 @@ inline bool comBuf::push ( const epicsUInt32 & value )
return true;
}
inline bool comBuf::push ( const epicsFloat32 & value )
inline bool comBuf::push ( const epicsFloat32 & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -268,7 +284,7 @@ inline bool comBuf::push ( const epicsFloat32 & value )
return true;
}
inline bool comBuf::push ( const epicsFloat64 & value )
inline bool comBuf::push ( const epicsFloat64 & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -279,7 +295,7 @@ inline bool comBuf::push ( const epicsFloat64 & value )
return true;
}
inline bool comBuf::push ( const epicsOldString & value )
inline bool comBuf::push ( const epicsOldString & value ) throw ()
{
if ( this->unoccupiedBytes () < sizeof ( value ) ) {
return false;
@@ -289,17 +305,17 @@ inline bool comBuf::push ( const epicsOldString & value )
return true;
}
inline unsigned comBuf::push ( const epicsInt8 *pValue, unsigned nElem )
inline unsigned comBuf::push ( const epicsInt8 *pValue, unsigned nElem ) throw ()
{
return copyInBytes ( pValue, nElem );
}
inline unsigned comBuf::push ( const epicsUInt8 *pValue, unsigned nElem )
inline unsigned comBuf::push ( const epicsUInt8 *pValue, unsigned nElem ) throw ()
{
return copyInBytes ( pValue, nElem );
}
inline unsigned comBuf::push ( const epicsOldString *pValue, unsigned nElem )
inline unsigned comBuf::push ( const epicsOldString *pValue, unsigned nElem ) throw ()
{
nElem = this->unoccupiedElem ( sizeof (*pValue), nElem );
unsigned size = nElem * sizeof ( *pValue );
@@ -308,7 +324,7 @@ inline unsigned comBuf::push ( const epicsOldString *pValue, unsigned nElem )
return nElem;
}
inline unsigned comBuf::occupiedElem ( unsigned elemSize, unsigned nElem )
inline unsigned comBuf::occupiedElem ( unsigned elemSize, unsigned nElem ) throw ()
{
unsigned avail = this->occupiedBytes ();
if ( elemSize * nElem > avail ) {
@@ -317,17 +333,17 @@ inline unsigned comBuf::occupiedElem ( unsigned elemSize, unsigned nElem )
return nElem;
}
inline void comBuf::commitIncomming ()
inline void comBuf::commitIncomming () throw ()
{
this->commitIndex = this->nextWriteIndex;
}
inline void comBuf::clearUncommittedIncomming ()
inline void comBuf::clearUncommittedIncomming () throw ()
{
this->nextWriteIndex = this->commitIndex;
}
inline bool comBuf::copyInAllBytes ( const void *pBuf, unsigned nBytes )
inline bool comBuf::copyInAllBytes ( const void *pBuf, unsigned nBytes ) throw ()
{
if ( nBytes <= this->unoccupiedBytes () ) {
memcpy ( & this->buf[this->nextWriteIndex], pBuf, nBytes );
@@ -337,7 +353,7 @@ inline bool comBuf::copyInAllBytes ( const void *pBuf, unsigned nBytes )
return false;
}
inline unsigned comBuf::copyInBytes ( const void *pBuf, unsigned nBytes )
inline unsigned comBuf::copyInBytes ( const void *pBuf, unsigned nBytes ) throw ()
{
if ( nBytes > 0u ) {
unsigned available = this->unoccupiedBytes ();
@@ -350,7 +366,7 @@ inline unsigned comBuf::copyInBytes ( const void *pBuf, unsigned nBytes )
return nBytes;
}
inline bool comBuf::copyOutAllBytes ( void * pBuf, unsigned nBytes )
inline bool comBuf::copyOutAllBytes ( void * pBuf, unsigned nBytes ) throw ()
{
if ( nBytes <= this->occupiedBytes () ) {
memcpy ( pBuf, &this->buf[this->nextReadIndex], nBytes);
@@ -360,7 +376,7 @@ inline bool comBuf::copyOutAllBytes ( void * pBuf, unsigned nBytes )
return false;
}
inline unsigned comBuf::copyOutBytes ( void *pBuf, unsigned nBytes )
inline unsigned comBuf::copyOutBytes ( void *pBuf, unsigned nBytes ) throw ()
{
unsigned occupied = this->occupiedBytes ();
if ( nBytes > occupied ) {
@@ -371,7 +387,7 @@ inline unsigned comBuf::copyOutBytes ( void *pBuf, unsigned nBytes )
return nBytes;
}
inline unsigned comBuf::removeBytes ( unsigned nBytes )
inline unsigned comBuf::removeBytes ( unsigned nBytes ) throw ()
{
unsigned occupied = this->occupiedBytes ();
if ( nBytes > occupied ) {
@@ -382,6 +398,7 @@ inline unsigned comBuf::removeBytes ( unsigned nBytes )
}
inline epicsUInt8 comBuf::popUInt8 ()
throw ( comBuf::insufficentBytesAvailable )
{
if ( this->occupiedBytes () < 1u ) {
comBuf::throwInsufficentBytesException ();
@@ -390,6 +407,7 @@ inline epicsUInt8 comBuf::popUInt8 ()
}
inline epicsUInt16 comBuf::popUInt16 ()
throw ( comBuf::insufficentBytesAvailable )
{
if ( this->occupiedBytes () < 2u ) {
comBuf::throwInsufficentBytesException ();
@@ -399,7 +417,8 @@ inline epicsUInt16 comBuf::popUInt16 ()
return static_cast < epicsUInt16 > ( byte1 << 8u | byte2 );
}
inline epicsUInt32 comBuf::popUInt32 ()
inline epicsUInt32 comBuf::popUInt32 ()
throw ( comBuf::insufficentBytesAvailable )
{
if ( this->occupiedBytes () < 4u ) {
comBuf::throwInsufficentBytesException ();

View File

@@ -27,25 +27,27 @@
#include "iocinf.h"
#include "virtualCircuit.h"
comQueRecv::comQueRecv (): nBytesPending ( 0u )
comQueRecv::comQueRecv ( comBufMemoryManager & comBufMemoryManagerIn ) throw () :
comBufMemMgr ( comBufMemoryManagerIn ), nBytesPending ( 0u )
{
}
comQueRecv::~comQueRecv ()
comQueRecv::~comQueRecv () throw ()
{
this->clear ();
}
void comQueRecv::clear ()
void comQueRecv::clear () throw ()
{
comBuf *pBuf;
while ( ( pBuf = this->bufs.get () ) ) {
pBuf->destroy ();
pBuf->~comBuf ();
this->comBufMemMgr.release ( pBuf );
}
this->nBytesPending = 0u;
}
unsigned comQueRecv::copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes )
unsigned comQueRecv::copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes ) throw ()
{
unsigned totalBytes = 0u;
do {
@@ -57,7 +59,8 @@ unsigned comQueRecv::copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes )
totalBytes += pComBuf->copyOutBytes ( &pBuf[totalBytes], nBytes - totalBytes );
if ( pComBuf->occupiedBytes () == 0u ) {
this->bufs.remove ( *pComBuf );
pComBuf->destroy ();
pComBuf->~comBuf ();
this->comBufMemMgr.release ( pComBuf );
}
}
while ( totalBytes < nBytes );
@@ -65,7 +68,7 @@ unsigned comQueRecv::copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes )
return totalBytes;
}
unsigned comQueRecv::removeBytes ( unsigned nBytes )
unsigned comQueRecv::removeBytes ( unsigned nBytes ) throw ()
{
unsigned totalBytes = 0u;
unsigned bytesLeft = nBytes;
@@ -78,7 +81,8 @@ unsigned comQueRecv::removeBytes ( unsigned nBytes )
unsigned nBytesThisTime = pComBuf->removeBytes ( bytesLeft );
if ( pComBuf->occupiedBytes () == 0u ) {
this->bufs.remove ( *pComBuf );
pComBuf->destroy ();
pComBuf->~comBuf ();
this->comBufMemMgr.release ( pComBuf );
}
if ( nBytesThisTime == 0u) {
break;
@@ -91,6 +95,7 @@ unsigned comQueRecv::removeBytes ( unsigned nBytes )
}
void comQueRecv::popString ( epicsOldString *pStr )
throw ( comBuf::insufficentBytesAvailable )
{
for ( unsigned i = 0u; i < sizeof ( *pStr ); i++ ) {
pStr[0][i] = this->popInt8 ();
@@ -98,6 +103,7 @@ void comQueRecv::popString ( epicsOldString *pStr )
}
void comQueRecv::pushLastComBufReceived ( comBuf & bufIn )
throw ()
{
bufIn.commitIncomming ();
comBuf * pComBuf = this->bufs.last ();
@@ -113,7 +119,8 @@ void comQueRecv::pushLastComBufReceived ( comBuf & bufIn )
this->bufs.add ( bufIn );
}
else {
bufIn.destroy ();
bufIn.~comBuf ();
this->comBufMemMgr.release ( & bufIn );
}
}
@@ -121,6 +128,7 @@ void comQueRecv::pushLastComBufReceived ( comBuf & bufIn )
// 2) using canonical unsigned tmp avoids ANSI C conversions to int
// 3) cast required because sizeof(unsigned) >= sizeof(epicsUInt32)
epicsUInt16 comQueRecv::multiBufferPopUInt16 ()
throw ( comBuf::insufficentBytesAvailable )
{
epicsUInt16 tmp;
if ( this->occupiedBytes() >= sizeof (tmp) ) {
@@ -139,6 +147,7 @@ epicsUInt16 comQueRecv::multiBufferPopUInt16 ()
// 2) using canonical unsigned temporary avoids ANSI C conversions to int
// 3) cast required because sizeof(unsigned) >= sizeof(epicsUInt32)
epicsUInt32 comQueRecv::multiBufferPopUInt32 ()
throw ( comBuf::insufficentBytesAvailable )
{
epicsUInt32 tmp;
if ( this->occupiedBytes() >= sizeof (tmp) ) {
@@ -159,8 +168,9 @@ epicsUInt32 comQueRecv::multiBufferPopUInt32 ()
return tmp;
}
void comQueRecv::removeAndDestroyBuf ( comBuf & buf )
void comQueRecv::removeAndDestroyBuf ( comBuf & buf ) throw ()
{
this->bufs.remove ( buf );
buf.destroy ();
buf.~comBuf ();
this->comBufMemMgr.release ( & buf );
}

View File

@@ -29,50 +29,54 @@
class comQueRecv {
public:
comQueRecv ();
~comQueRecv ();
unsigned occupiedBytes () const;
unsigned copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes );
unsigned removeBytes ( unsigned nBytes );
void pushLastComBufReceived ( comBuf & );
void clear ();
epicsInt8 popInt8 ();
epicsUInt8 popUInt8 ();
epicsInt16 popInt16 ();
epicsUInt16 popUInt16 ();
epicsInt32 popInt32 ();
epicsUInt32 popUInt32 ();
epicsFloat32 popFloat32 ();
epicsFloat64 popFloat64 ();
void popString ( epicsOldString * );
class insufficentBytesAvailable {};
comQueRecv ( comBufMemoryManager & ) throw ();
~comQueRecv () throw ();
unsigned occupiedBytes () const throw ();
unsigned copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes ) throw ();
unsigned removeBytes ( unsigned nBytes ) throw ();
void pushLastComBufReceived ( comBuf & ) throw ();
void clear () throw ();
epicsInt8 popInt8 () throw ( comBuf::insufficentBytesAvailable );
epicsUInt8 popUInt8 () throw ( comBuf::insufficentBytesAvailable );
epicsInt16 popInt16 () throw ( comBuf::insufficentBytesAvailable );
epicsUInt16 popUInt16 () throw ( comBuf::insufficentBytesAvailable );
epicsInt32 popInt32 () throw ( comBuf::insufficentBytesAvailable );
epicsUInt32 popUInt32 () throw ( comBuf::insufficentBytesAvailable );
epicsFloat32 popFloat32 () throw ( comBuf::insufficentBytesAvailable );
epicsFloat64 popFloat64 () throw ( comBuf::insufficentBytesAvailable );
void popString ( epicsOldString * ) throw ( comBuf::insufficentBytesAvailable );
private:
tsDLList < comBuf > bufs;
comBufMemoryManager & comBufMemMgr;
unsigned nBytesPending;
epicsUInt16 multiBufferPopUInt16 ();
epicsUInt32 multiBufferPopUInt32 ();
void removeAndDestroyBuf ( comBuf & );
comQueRecv ( const comQueRecv & );
comQueRecv & operator = ( const comQueRecv & );
epicsUInt16 multiBufferPopUInt16 () throw ( comBuf::insufficentBytesAvailable );
epicsUInt32 multiBufferPopUInt32 () throw ( comBuf::insufficentBytesAvailable );
void removeAndDestroyBuf ( comBuf & ) throw ();
comQueRecv ( const comQueRecv & ) throw ();
comQueRecv & operator = ( const comQueRecv & ) throw ();
};
inline unsigned comQueRecv::occupiedBytes () const
throw ()
{
return this->nBytesPending;
}
inline epicsInt8 comQueRecv::popInt8 ()
throw ( comBuf::insufficentBytesAvailable )
{
return static_cast < epicsInt8 > ( this->popUInt8() );
}
inline epicsInt16 comQueRecv::popInt16 ()
throw ( comBuf::insufficentBytesAvailable )
{
return static_cast < epicsInt16 > ( this->popInt8() << 8u
| this->popInt8() << 0u );
}
inline epicsInt32 comQueRecv::popInt32 ()
throw ( comBuf::insufficentBytesAvailable )
{
epicsInt32 tmp ;
tmp = this->popInt8() << 24u;
@@ -83,6 +87,7 @@ inline epicsInt32 comQueRecv::popInt32 ()
}
inline epicsFloat32 comQueRecv::popFloat32 ()
throw ( comBuf::insufficentBytesAvailable )
{
epicsFloat32 tmp;
epicsUInt8 wire[ sizeof ( tmp ) ];
@@ -95,6 +100,7 @@ inline epicsFloat32 comQueRecv::popFloat32 ()
}
inline epicsFloat64 comQueRecv::popFloat64 ()
throw ( comBuf::insufficentBytesAvailable )
{
epicsFloat64 tmp;
epicsUInt8 wire[ sizeof ( tmp ) ];
@@ -106,7 +112,8 @@ inline epicsFloat64 comQueRecv::popFloat64 ()
return tmp;
}
inline epicsUInt8 comQueRecv::popUInt8 ()
inline epicsUInt8 comQueRecv::popUInt8 ()
throw ( comBuf::insufficentBytesAvailable )
{
comBuf * pComBuf = this->bufs.first ();
if ( ! pComBuf ) {
@@ -122,6 +129,7 @@ inline epicsUInt8 comQueRecv::popUInt8 ()
// optimization here complicates this function somewhat
inline epicsUInt16 comQueRecv::popUInt16 ()
throw ( comBuf::insufficentBytesAvailable )
{
comBuf *pComBuf = this->bufs.first ();
if ( ! pComBuf ) {
@@ -147,6 +155,7 @@ inline epicsUInt16 comQueRecv::popUInt16 ()
// optimization here complicates this function somewhat
inline epicsUInt32 comQueRecv::popUInt32 ()
throw ( comBuf::insufficentBytesAvailable )
{
comBuf *pComBuf = this->bufs.first ();
if ( ! pComBuf ) {

View File

@@ -80,29 +80,36 @@ const char cacNillBytes [] =
0, 0, 0, 0
};
comQueSend::comQueSend ( wireSendAdapter & wireIn ) :
wire ( wireIn ), nBytesPending ( 0u )
comQueSend::comQueSend ( wireSendAdapter & wireIn,
comBufMemoryManager & comBufMemMgrIn ) throw () :
comBufMemMgr ( comBufMemMgrIn ), wire ( wireIn ),
nBytesPending ( 0u )
{
}
comQueSend::~comQueSend ()
comQueSend::~comQueSend () throw ()
{
this->clear ();
}
void comQueSend::clear ()
void comQueSend::clear () throw ()
{
comBuf *pBuf;
while ( ( pBuf = this->bufs.get () ) ) {
this->nBytesPending -= pBuf->occupiedBytes ();
pBuf->destroy ();
pBuf->~comBuf ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
comBuf::operator delete ( pBuf, this->comBufMemMgr );
# else
this->comBufMemMgr.release ( pBuf );
# endif
}
this->pFirstUncommited = tsDLIter < comBuf > ();
assert ( this->nBytesPending == 0 );
}
void comQueSend::clearUncommitted ()
void comQueSend::clearUncommitted () throw ()
{
while ( this->pFirstUncommited.valid() ) {
tsDLIter < comBuf > next = this->pFirstUncommited;
@@ -110,38 +117,44 @@ void comQueSend::clearUncommitted ()
this->pFirstUncommited->clearUncommittedIncomming ();
if ( this->pFirstUncommited->occupiedBytes() == 0u ) {
this->bufs.remove ( *this->pFirstUncommited );
this->pFirstUncommited->destroy ();
this->pFirstUncommited->~comBuf ();
# if defined ( CXX_PLACEMENT_DELETE ) && 0
comBuf::operator delete
( this->pFirstUncommited.pointer(), this->comBufMemMgr );
# else
this->comBufMemMgr.release ( this->pFirstUncommited.pointer() );
# endif
}
this->pFirstUncommited = next;
}
}
void comQueSend::copy_dbr_string ( const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_string ( const void *pValue, unsigned nElem ) throw ()
{
this->push ( static_cast <const dbr_string_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_short ( const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_short ( const void *pValue, unsigned nElem ) throw ()
{
this->push ( static_cast <const dbr_short_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_float ( const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_float ( const void *pValue, unsigned nElem ) throw ()
{
this->push ( static_cast <const dbr_float_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_char ( const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_char ( const void *pValue, unsigned nElem ) throw ()
{
this->push ( static_cast <const dbr_char_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_long ( const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_long ( const void *pValue, unsigned nElem ) throw ()
{
this->push ( static_cast <const dbr_long_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_double ( const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_double ( const void *pValue, unsigned nElem ) throw ()
{
this->push ( static_cast <const dbr_double_t *> ( pValue ), nElem );
}
@@ -188,7 +201,7 @@ const comQueSend::copyFunc_t comQueSend::dbrCopyVector [39] = {
0 // DBR_CLASS_NAME
};
comBuf * comQueSend::popNextComBufToSend ()
comBuf * comQueSend::popNextComBufToSend () throw ()
{
comBuf *pBuf = this->bufs.get ();
if ( pBuf ) {
@@ -211,7 +224,8 @@ comBuf * comQueSend::popNextComBufToSend ()
void comQueSend::insertRequestHeader (
ca_uint16_t request, ca_uint32_t payloadSize,
ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid,
ca_uint32_t requestDependent, bool v49Ok )
ca_uint32_t requestDependent, bool v49Ok )
throw ( cacChannel::outOfBounds )
{
this->beginMsg ();
if ( payloadSize < 0xffff && nElem < 0xffff ) {
@@ -240,7 +254,7 @@ void comQueSend::insertRequestHeader (
void comQueSend::insertRequestWithPayLoad (
ca_uint16_t request, unsigned dataType, ca_uint32_t nElem,
ca_uint32_t cid, ca_uint32_t requestDependent, const void * pPayload,
bool v49Ok )
bool v49Ok ) throw ( cacChannel::outOfBounds )
{
if ( ! this->dbr_type_ok ( dataType ) ) {
throw cacChannel::badType();
@@ -285,7 +299,7 @@ void comQueSend::insertRequestWithPayLoad (
this->commitMsg ();
}
void comQueSend::commitMsg ()
void comQueSend::commitMsg () throw ()
{
while ( this->pFirstUncommited.valid() ) {
this->nBytesPending += this->pFirstUncommited->uncommittedBytes ();

View File

@@ -40,53 +40,56 @@
//
class comQueSend {
public:
comQueSend ( wireSendAdapter & );
~comQueSend ();
void clear ();
void beginMsg ();
void commitMsg ();
unsigned occupiedBytes () const;
bool flushEarlyThreshold ( unsigned nBytesThisMsg ) const;
bool flushBlockThreshold ( unsigned nBytesThisMsg ) const;
bool dbr_type_ok ( unsigned type );
void pushUInt16 ( const ca_uint16_t value );
void pushUInt32 ( const ca_uint32_t value );
void pushFloat32 ( const ca_float32_t value );
void pushString ( const char *pVal, unsigned nChar );
comQueSend ( wireSendAdapter &, comBufMemoryManager & ) throw ();
~comQueSend () throw ();
void clear () throw ();
void beginMsg () throw ();
void commitMsg () throw ();
unsigned occupiedBytes () const throw ();
bool flushEarlyThreshold ( unsigned nBytesThisMsg ) const throw ();
bool flushBlockThreshold ( unsigned nBytesThisMsg ) const throw ();
bool dbr_type_ok ( unsigned type ) throw ();
void pushUInt16 ( const ca_uint16_t value ) throw ();
void pushUInt32 ( const ca_uint32_t value ) throw ();
void pushFloat32 ( const ca_float32_t value ) throw ();
void pushString ( const char *pVal, unsigned nChar ) throw ();
void insertRequestHeader (
ca_uint16_t request, ca_uint32_t payloadSize,
ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid,
ca_uint32_t requestDependent, bool v49Ok );
ca_uint32_t requestDependent, bool v49Ok )
throw ( cacChannel::outOfBounds );
void insertRequestWithPayLoad (
ca_uint16_t request, unsigned dataType, ca_uint32_t nElem,
ca_uint32_t cid, ca_uint32_t requestDependent, const void * pPayload,
bool v49Ok );
void push_dbr_type ( unsigned type, const void *pVal, unsigned nElem );
comBuf * popNextComBufToSend ();
ca_uint32_t cid, ca_uint32_t requestDependent,
const void * pPayload, bool v49Ok )
throw ( cacChannel::outOfBounds );
void push_dbr_type ( unsigned type, const void *pVal, unsigned nElem ) throw ();
comBuf * popNextComBufToSend () throw ();
private:
comBufMemoryManager & comBufMemMgr;
tsDLList < comBuf > bufs;
tsDLIter < comBuf > pFirstUncommited;
wireSendAdapter & wire;
unsigned nBytesPending;
void copy_dbr_string ( const void *pValue, unsigned nElem );
void copy_dbr_short ( const void *pValue, unsigned nElem );
void copy_dbr_float ( const void *pValue, unsigned nElem );
void copy_dbr_char ( const void *pValue, unsigned nElem );
void copy_dbr_long ( const void *pValue, unsigned nElem );
void copy_dbr_double ( const void *pValue, unsigned nElem );
void pushComBuf ( comBuf & );
void copy_dbr_string ( const void *pValue, unsigned nElem ) throw ();
void copy_dbr_short ( const void *pValue, unsigned nElem ) throw ();
void copy_dbr_float ( const void *pValue, unsigned nElem ) throw ();
void copy_dbr_char ( const void *pValue, unsigned nElem ) throw ();
void copy_dbr_long ( const void *pValue, unsigned nElem ) throw ();
void copy_dbr_double ( const void *pValue, unsigned nElem ) throw ();
void pushComBuf ( comBuf & ) throw ();
typedef void ( comQueSend::*copyFunc_t ) (
const void *pValue, unsigned nElem );
static const copyFunc_t dbrCopyVector [39];
void clearUncommitted ();
void clearUncommitted () throw ();
//
// visual C++ version 6.0 does not allow out of
// visual C++ versions 6 & 7 do not allow out of
// class member template function definition
//
template < class T >
inline void push ( const T *pVal, const unsigned nElem )
inline void push ( const T *pVal, const unsigned nElem ) throw ()
{
comBuf * pLastBuf = this->bufs.last ();
unsigned nCopied;
@@ -97,36 +100,37 @@ private:
nCopied = 0u;
}
while ( nElem > nCopied ) {
comBuf * pComBuf = new comBuf;
unsigned nNew = pComBuf->push ( &pVal[nCopied], nElem - nCopied );
comBuf * pComBuf = new ( this->comBufMemMgr ) comBuf;
unsigned nNew = pComBuf->push
( &pVal[nCopied], nElem - nCopied );
nCopied += nNew;
this->pushComBuf ( *pComBuf );
}
}
//
// visual C++ version 6.0 does not allow out of
// visual C++ versions 6 and 7 do not allow out of
// class member template function definition
//
template < class T >
inline void push ( const T & val )
inline void push ( const T & val ) throw ()
{
register comBuf * pComBuf = this->bufs.last ();
comBuf * pComBuf = this->bufs.last ();
if ( pComBuf && pComBuf->push ( val ) ) {
return;
}
pComBuf = new comBuf;
pComBuf = new ( this->comBufMemMgr ) comBuf;
assert ( pComBuf->push ( val ) );
this->pushComBuf ( *pComBuf );
}
comQueSend ( const comQueSend & );
comQueSend & operator = ( const comQueSend & );
comQueSend ( const comQueSend & ) throw ();
comQueSend & operator = ( const comQueSend & ) throw ();
};
extern const char cacNillBytes[];
inline bool comQueSend::dbr_type_ok ( unsigned type )
inline bool comQueSend::dbr_type_ok ( unsigned type ) throw ()
{
if ( type >= ( sizeof ( this->dbrCopyVector ) / sizeof ( this->dbrCopyVector[0] ) ) ) {
return false;
@@ -137,34 +141,34 @@ inline bool comQueSend::dbr_type_ok ( unsigned type )
return true;
}
inline void comQueSend::pushUInt16 ( const ca_uint16_t value )
inline void comQueSend::pushUInt16 ( const ca_uint16_t value ) throw ()
{
this->push ( value );
}
inline void comQueSend::pushUInt32 ( const ca_uint32_t value )
inline void comQueSend::pushUInt32 ( const ca_uint32_t value ) throw ()
{
this->push ( value );
}
inline void comQueSend::pushFloat32 ( const ca_float32_t value )
inline void comQueSend::pushFloat32 ( const ca_float32_t value ) throw ()
{
this->push ( value );
}
inline void comQueSend::pushString ( const char *pVal, unsigned nChar )
inline void comQueSend::pushString ( const char *pVal, unsigned nChar ) throw ()
{
this->push ( pVal, nChar );
}
// it is assumed that dbr_type_ok() was called prior to calling this routine
// to check the type code
inline void comQueSend::push_dbr_type ( unsigned type, const void *pVal, unsigned nElem )
inline void comQueSend::push_dbr_type ( unsigned type, const void *pVal, unsigned nElem ) throw ()
{
( this->*dbrCopyVector [type] ) ( pVal, nElem );
}
inline void comQueSend::pushComBuf ( comBuf & cb )
inline void comQueSend::pushComBuf ( comBuf & cb ) throw ()
{
this->bufs.add ( cb );
if ( ! this->pFirstUncommited.valid() ) {
@@ -172,22 +176,22 @@ inline void comQueSend::pushComBuf ( comBuf & cb )
}
}
inline unsigned comQueSend::occupiedBytes () const
inline unsigned comQueSend::occupiedBytes () const throw ()
{
return this->nBytesPending;
}
inline bool comQueSend::flushBlockThreshold ( unsigned nBytesThisMsg ) const
inline bool comQueSend::flushBlockThreshold ( unsigned nBytesThisMsg ) const throw ()
{
return ( this->nBytesPending + nBytesThisMsg > 16 * comBuf::capacityBytes () );
}
inline bool comQueSend::flushEarlyThreshold ( unsigned nBytesThisMsg ) const
inline bool comQueSend::flushEarlyThreshold ( unsigned nBytesThisMsg ) const throw ()
{
return ( this->nBytesPending + nBytesThisMsg > 4 * comBuf::capacityBytes () );
}
inline void comQueSend::beginMsg ()
inline void comQueSend::beginMsg () throw ()
{
if ( this->pFirstUncommited.valid() ) {
this->clearUncommitted ();

View File

@@ -24,12 +24,12 @@
* 505 665 1831
*/
#include <stdexcept>
#define epicsExportSharedSymbols
#include "iocinf.h"
#include "oldAccess.h"
epicsSingleton < tsFreeList < class getCallback, 1024 > > getCallback::pFreeList;
getCallback::getCallback ( oldChannelNotify &chanIn,
caEventCallBackFunc *pFuncIn, void *pPrivateIn ) :
chan ( chanIn ), pFunc ( pFuncIn ), pPrivate ( pPrivateIn )
@@ -43,7 +43,7 @@ getCallback::~getCallback ()
void getCallback::completion (
unsigned type, arrayElementCount count, const void *pData )
{
struct event_handler_args args;
struct event_handler_args args;
args.usr = this->pPrivate;
args.chid = &this->chan;
args.type = type;
@@ -51,7 +51,7 @@ void getCallback::completion (
args.status = ECA_NORMAL;
args.dbr = pData;
( *this->pFunc ) ( args );
delete this;
this->chan.getClientCtx().destroyGetCallback ( *this );
}
void getCallback::exception (
@@ -59,7 +59,7 @@ void getCallback::exception (
unsigned type, arrayElementCount count )
{
if ( status != ECA_CHANDESTROY ) {
struct event_handler_args args;
struct event_handler_args args;
args.usr = this->pPrivate;
args.chid = &this->chan;
args.type = type;
@@ -68,6 +68,13 @@ void getCallback::exception (
args.dbr = 0;
( *this->pFunc ) ( args );
}
delete this;
this->chan.getClientCtx().destroyGetCallback ( *this );
}
void getCallback::operator delete ( void *pCadaver )
{
throw std::logic_error
( "compiler is confused about placement delete" );
}

View File

@@ -24,6 +24,8 @@
* 505 665 1831
*/
#include <stdexcept>
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#define epicsExportSharedSymbols
@@ -31,8 +33,6 @@
#include "oldAccess.h"
#include "cac.h"
epicsSingleton < tsFreeList < class getCopy, 1024 > > getCopy::pFreeList;
getCopy::getCopy ( ca_client_context &cacCtxIn, oldChannelNotify &chanIn,
unsigned typeIn, arrayElementCount countIn, void *pValueIn ) :
count ( countIn ), cacCtx ( cacCtxIn ), chan ( chanIn ), pValue ( pValueIn ),
@@ -50,11 +50,6 @@ void getCopy::cancel ()
this->cacCtx.decrementOutstandingIO ( this->ioSeqNo );
}
void getCopy::destroy ()
{
delete this;
}
void getCopy::completion ( unsigned typeIn,
arrayElementCount countIn, const void *pDataIn )
{
@@ -68,7 +63,7 @@ void getCopy::completion ( unsigned typeIn,
"bad data type match in get copy back response",
typeIn, countIn);
}
delete this;
this->cacCtx.destroyGetCopy ( *this );
}
void getCopy::exception (
@@ -79,7 +74,7 @@ void getCopy::exception (
__FILE__, __LINE__, this->chan, this->type,
this->count, CA_OP_GET );
}
delete this;
this->cacCtx.destroyGetCopy ( *this );
}
void getCopy::show ( unsigned level ) const
@@ -92,3 +87,10 @@ void getCopy::show ( unsigned level ) const
this->ioSeqNo, static_cast <const void *> ( this->pValue ) );
}
}
void getCopy::operator delete ( void *pCadaver )
{
throw std::logic_error
( "compiler is confused about placement delete" );
}

View File

@@ -24,6 +24,8 @@
* 505 665 1831
*/
#include <stdexcept>
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#include "iocinf.h"
@@ -34,9 +36,6 @@
#include "caerr.h" // for ECA_DBLCHNL
#undef epicsExportSharedSymbols
epicsSingleton < tsFreeList < class msgForMultiplyDefinedPV, 16 > >
msgForMultiplyDefinedPV::pFreeList;
msgForMultiplyDefinedPV::msgForMultiplyDefinedPV (
callbackMutex & mutexIn, cac & cacRefIn,
const char * pChannelName, const char * pAcc, const osiSockAddr &rej ) :
@@ -60,3 +59,10 @@ void msgForMultiplyDefinedPV::ioCompletionNotify ( const char * pHostNameRej )
}
delete this;
}
void msgForMultiplyDefinedPV::operator delete ( void *pCadaver )
{
throw std::logic_error
( "compiler is confused about placement delete" );
}

View File

@@ -29,8 +29,8 @@
#include "ipAddrToAsciiAsynchronous.h"
#include "tsFreeList.h"
#include "epicsSingleton.h"
#include "epicsMutex.h"
#include "cxxCompilerDepPlacementDelete.h"
class cac;
class callbackMutex;
@@ -41,28 +41,35 @@ public:
cac & cacRefIn, const char * pChannelName, const char * pAcc,
const osiSockAddr & rej );
msgForMultiplyDefinedPV ( const osiSockAddr &addr, ipAddrToAsciiEngine &engine );
void * operator new ( size_t size );
void operator delete ( void *pCadaver, size_t size );
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;
static epicsSingleton < tsFreeList < class msgForMultiplyDefinedPV, 16 > > pFreeList;
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 )
inline void * msgForMultiplyDefinedPV::operator new ( size_t size,
tsFreeList < class msgForMultiplyDefinedPV, 16 > & freeList )
{
return msgForMultiplyDefinedPV::pFreeList->allocate ( size );
return freeList.allocate ( size );
}
inline void msgForMultiplyDefinedPV::operator delete ( void *pCadaver, size_t size )
#ifdef CXX_PLACEMENT_DELETE
inline void msgForMultiplyDefinedPV::operator delete ( void *pCadaver,
tsFreeList < class msgForMultiplyDefinedPV, 16 > & freeList )
{
msgForMultiplyDefinedPV::pFreeList->release ( pCadaver, size );
freeList.release ( pCadaver, sizeof ( msgForMultiplyDefinedPV ) );
}
#endif
#endif // ifdef msgForMultiplyDefinedPVh

View File

@@ -36,6 +36,7 @@
#include "comQueRecv.h"
#include "tcpRecvWatchdog.h"
#include "tcpSendWatchdog.h"
#include "hostNameCache.h"
// a modified ca header with capacity for large arrays
struct caHdrLargeArray {
@@ -58,6 +59,7 @@ public:
virtual ~tcpRecvThread ();
void start ();
void exitWait ();
void interruptSocketRecv ();
private:
epicsThread thread;
class tcpiiu & iiu;
@@ -73,6 +75,7 @@ public:
void start ();
void exitWait ();
void exitWaitRelease ();
void interruptSocketSend ();
private:
class tcpiiu & iiu;
epicsThread thread;
@@ -84,9 +87,9 @@ class tcpiiu :
public tsSLNode < tcpiiu >, public caServerID,
private wireSendAdapter, private wireRecvAdapter {
public:
tcpiiu ( cac &cac, callbackMutex & cbMutex, double connectionTimeout,
tcpiiu ( cac & cac, callbackMutex & cbMutex, double connectionTimeout,
epicsTimerQueue & timerQueue, const osiSockAddr & addrIn,
unsigned minorVersion, ipAddrToAsciiEngine & engineIn,
comBufMemoryManager &, unsigned minorVersion, ipAddrToAsciiEngine & engineIn,
const cacChannel::priLev & priorityIn );
~tcpiiu ();
void start ( epicsGuard < callbackMutex > & );
@@ -126,7 +129,10 @@ public:
void uninstallChan ( epicsGuard < cacMutex > &, nciu & chan );
void initiateCleanShutdown ( epicsGuard < cacMutex > & );
bool bytesArePendingInOS () const;
private:
hostNameCache hostNameCacheInstance;
tcpRecvThread recvThread;
tcpSendThread sendThread;
tcpRecvWatchdog recvDog;
@@ -137,7 +143,7 @@ private:
caHdrLargeArray curMsg;
arrayElementCount curDataMax;
arrayElementCount curDataBytes;
epics_auto_ptr < hostNameCache > pHostNameCache;
comBufMemoryManager & comBufMemMgr;
cac & cacRef;
char * pCurData;
unsigned minorProtocolVersion;
@@ -235,5 +241,15 @@ inline unsigned tcpiiu::channelCount ()
return this->channelList.count ();
}
inline void tcpRecvThread::interruptSocketRecv ()
{
epicsSocketInterruptSystemCall ( this->thread.getId() );
}
inline void tcpSendThread::interruptSocketSend ()
{
epicsSocketInterruptSystemCall ( this->thread.getId() );
}
#endif // ifdef virtualCircuith