use placement new
This commit is contained in:
@@ -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" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 () {}
|
||||
|
||||
|
||||
|
||||
63
src/ca/bhe.h
63
src/ca/bhe.h
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
117
src/ca/cac.cpp
117
src/ca/cac.cpp
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
79
src/ca/cac.h
79
src/ca/cac.h
@@ -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 ();
|
||||
|
||||
@@ -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?" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "epicsGuard.h"
|
||||
#include "cacIO.h"
|
||||
|
||||
epicsShareDef epicsSingleton < cacServiceList > pGlobalServiceListCAC;
|
||||
epicsShareDef epicsSingleton < cacServiceList > globalServiceListCAC;
|
||||
|
||||
cacServiceList::cacServiceList ()
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 () {}
|
||||
|
||||
229
src/ca/comBuf.h
229
src/ca/comBuf.h
@@ -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 ();
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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" );
|
||||
}
|
||||
|
||||
|
||||
@@ -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" );
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user