also merged in removal of c++ support for old HPUX compiler
This commit is contained in:
Jeff Hill johill@lanl.gov
2013-05-16 12:33:31 -06:00
parent 593e313fab
commit e0bc071de3
53 changed files with 635 additions and 399 deletions
+25 -31
View File
@@ -25,8 +25,6 @@
#include "cac.h"
#include "sgAutoPtr.h"
casgRecycle::~casgRecycle () {}
CASG::CASG ( epicsGuard < epicsMutex > & guard, ca_client_context & cacIn ) :
client ( cacIn ), magic ( CASG_MAGIC )
{
@@ -38,12 +36,13 @@ CASG::~CASG ()
}
void CASG::destructor (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
if ( this->verify ( guard ) ) {
this->reset ( guard );
this->reset ( cbGuard, guard );
this->client.uninstallCASG ( guard, *this );
this->magic = 0;
}
@@ -127,36 +126,37 @@ int CASG::block (
delay = cur_time - beg_time;
}
this->reset ( guard );
return status;
}
void CASG::reset (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->destroyCompletedIO ( guard );
this->destroyPendingIO ( guard );
this->destroyCompletedIO ( cbGuard, guard );
this->destroyPendingIO ( cbGuard, guard );
}
// lock must be applied
void CASG::destroyCompletedIO (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
syncGroupNotify * pNotify;
while ( ( pNotify = this->ioCompletedList.get () ) ) {
pNotify->destroy ( guard, * this );
pNotify->destroy ( cbGuard, guard );
}
}
void CASG::destroyPendingIO (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
while ( syncGroupNotify * pNotify = this->ioPendingList.first () ) {
pNotify->cancel ( guard );
pNotify->cancel ( cbGuard, guard );
// cancel must release the guard while
// canceling put callbacks so we
// must double check list membership
@@ -166,7 +166,7 @@ void CASG::destroyPendingIO (
else {
this->ioCompletedList.remove ( *pNotify );
}
pNotify->destroy ( guard, *this );
pNotify->destroy ( cbGuard, guard );
}
}
@@ -201,10 +201,11 @@ void CASG::show (
}
bool CASG::ioComplete (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->destroyCompletedIO ( guard );
this->destroyCompletedIO ( cbGuard, guard );
return this->ioPendingList.count () == 0u;
}
@@ -212,9 +213,9 @@ void CASG::put ( epicsGuard < epicsMutex > & guard, chid pChan,
unsigned type, arrayElementCount count, const void * pValue )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
sgAutoPtr < syncGroupWriteNotify > pNotify ( guard, *this, this->ioPendingList );
sgAutoPtr < syncGroupWriteNotify > pNotify ( guard, *this );
pNotify = syncGroupWriteNotify::factory (
this->freeListWriteOP, *this, pChan );
this->freeListWriteOP, *this, & CASG :: recycleWriteNotifyIO, pChan );
pNotify->begin ( guard, type, count, pValue );
pNotify.release ();
}
@@ -223,9 +224,9 @@ void CASG::get ( epicsGuard < epicsMutex > & guard, chid pChan,
unsigned type, arrayElementCount count, void *pValue )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
sgAutoPtr < syncGroupReadNotify > pNotify ( guard, *this, this->ioPendingList );
sgAutoPtr < syncGroupReadNotify > pNotify ( guard, *this );
pNotify = syncGroupReadNotify::factory (
this->freeListReadOP, *this, pChan, pValue );
this->freeListReadOP, *this, & CASG :: recycleReadNotifyIO, pChan, pValue );
pNotify->begin ( guard, type, count );
pNotify.release ();
}
@@ -241,20 +242,20 @@ void CASG::completionNotify (
}
}
void CASG::recycleSyncGroupWriteNotify (
epicsGuard < epicsMutex > & guard, syncGroupWriteNotify & io )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->freeListWriteOP.release ( & io );
}
void CASG::recycleSyncGroupReadNotify (
epicsGuard < epicsMutex > & guard, syncGroupReadNotify & io )
void CASG :: recycleReadNotifyIO ( epicsGuard < epicsMutex > & guard,
syncGroupReadNotify & io )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->freeListReadOP.release ( & io );
}
void CASG :: recycleWriteNotifyIO ( epicsGuard < epicsMutex > & guard,
syncGroupWriteNotify & io )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->freeListWriteOP.release ( & io );
}
int CASG :: printFormated ( const char *pformat, ... )
{
va_list theArgs;
@@ -295,13 +296,6 @@ void CASG::exception (
}
}
void * CASG::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void CASG::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
+30 -10
View File
@@ -376,15 +376,35 @@ int epicsShareAPI ca_create_channel (
int epicsShareAPI ca_clear_channel ( chid pChan )
{
ca_client_context & cac = pChan->getClientCtx ();
epicsGuard < epicsMutex > guard ( cac.mutex );
try {
pChan->eliminateExcessiveSendBacklog ( guard );
{
epicsGuard < epicsMutex > guard ( cac.mutex );
try {
pChan->eliminateExcessiveSendBacklog ( guard );
}
catch ( cacChannel::notConnected & ) {
// intentionally ignored
}
}
catch ( cacChannel::notConnected & ) {
// intentionally ignored
}
pChan->destructor ( guard );
if ( cac.pCallbackGuard.get() &&
cac.createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( cac.mutex );
pChan->destructor ( *cac.pCallbackGuard.get(), guard );
cac.oldChannelNotifyFreeList.release ( pChan );
}
else {
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( cac.cbMutex );
epicsGuard < epicsMutex > guard ( cac.mutex );
pChan->destructor ( *cac.pCallbackGuard.get(), guard );
cac.oldChannelNotifyFreeList.release ( pChan );
}
return ECA_NORMAL;
}
@@ -433,7 +453,7 @@ chid epicsShareAPI ca_evid_to_chid ( evid pMon )
}
// extern "C"
int epicsShareAPI ca_pend ( ca_real timeout, int early ) // X aCC 361
int epicsShareAPI ca_pend ( ca_real timeout, int early )
{
if ( early ) {
return ca_pend_io ( timeout );
@@ -516,7 +536,7 @@ int epicsShareAPI ca_flush_io ()
/*
* CA_TEST_IO ()
*/
int epicsShareAPI ca_test_io () // X aCC 361
int epicsShareAPI ca_test_io ()
{
ca_client_context *pcac;
int caStatus = fetchClientContext ( &pcac );
@@ -551,7 +571,7 @@ void epicsShareAPI ca_signal ( long ca_status, const char *message )
* (if they call this routine again).
*/
// extern "C"
const char * epicsShareAPI ca_message ( long ca_status ) // X aCC 361
const char * epicsShareAPI ca_message ( long ca_status )
{
unsigned msgNo = CA_EXTRACT_MSG_NO ( ca_status );
+158
View File
@@ -13,6 +13,7 @@
* Authors:
* Jeff Hill
* Murali Shankar - initial versions of verifyMultithreadSubscr
* Michael Abbott - initial versions of multiSubscrDestroyNoLateCallbackTest
*
*/
@@ -1328,6 +1329,158 @@ void test_sync_groups ( chid chan, unsigned interestLevel )
showProgressEnd ( interestLevel );
}
#define multiSubscrDestroyNoLateCallbackEventCount 500
struct MultiSubscrDestroyNoLateCallbackEventData {
evid m_id;
size_t m_nCallback;
int m_callbackIsOk;
struct MultiSubscrDestroyNoLateCallbackTestData * m_pTestData;
};
struct MultiSubscrDestroyNoLateCallbackTestData {
const char * m_pChanName;
chid m_chan;
epicsMutexId m_mutex;
epicsEventId m_testDoneEvent;
unsigned m_interestLevel;
struct MultiSubscrDestroyNoLateCallbackEventData
m_eventData [multiSubscrDestroyNoLateCallbackEventCount];
};
static void noLateCallbackDetect ( struct event_handler_args args )
{
int callbackIsOk;
struct MultiSubscrDestroyNoLateCallbackEventData * const pEventData = args.usr;
epicsMutexLockStatus lockStatus = epicsMutexLock ( pEventData->m_pTestData->m_mutex );
callbackIsOk = pEventData->m_callbackIsOk;
pEventData->m_nCallback++;
epicsMutexUnlock ( pEventData->m_pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
verify ( callbackIsOk );
}
static void multiSubscrDestroyNoLateCallbackThread ( void * pParm )
{
struct MultiSubscrDestroyNoLateCallbackTestData * const pTestData =
( struct MultiSubscrDestroyNoLateCallbackTestData * ) pParm;
unsigned i, j;
int status;
status = ca_context_create ( ca_enable_preemptive_callback );
verify ( status == ECA_NORMAL );
status = ca_create_channel ( pTestData->m_pChanName, 0, 0,
CA_PRIORITY_DEFAULT, &pTestData->m_chan );
status = ca_pend_io ( timeoutToPendIO );
SEVCHK ( status, "multiSubscrDestroyLateNoCallbackTest: channel connect failed" );
verify ( status == ECA_NORMAL );
/*
* create a set of subscriptions
*/
for ( i=0; i < 10000; i++ ) {
unsigned int priorityOfTestThread;
for ( j=0; j < multiSubscrDestroyNoLateCallbackEventCount; j++ ) {
epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
pTestData->m_eventData[j].m_nCallback = 0;
pTestData->m_eventData[j].m_callbackIsOk = TRUE;
pTestData->m_eventData[j].m_pTestData = pTestData;
epicsMutexUnlock ( pTestData->m_mutex );
SEVCHK ( ca_add_event ( DBR_GR_FLOAT, pTestData->m_chan, noLateCallbackDetect,
&pTestData->m_eventData[j], &pTestData->m_eventData[j].m_id ) , NULL );
}
SEVCHK ( ca_flush_io(), NULL );
/*
* raise the priority of the current thread hoping to improve our
* likelyhood of detecting a bug
*/
priorityOfTestThread = epicsThreadGetPrioritySelf ();
epicsThreadSetPriority ( epicsThreadGetIdSelf(), epicsThreadPriorityHigh );
/*
* wait for the first subscription update to arrive
*/
{
epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
while ( pTestData->m_eventData[0].m_nCallback == 0 ) {
epicsMutexUnlock ( pTestData->m_mutex );
epicsThreadSleep ( 50e-6 );
lockStatus = epicsMutexLock ( pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
}
epicsMutexUnlock ( pTestData->m_mutex );
}
/*
* try to destroy all of the subscriptions at precisely the same time that
* their first callbacks are running
*/
for ( j=0; j < multiSubscrDestroyNoLateCallbackEventCount; j++ ) {
SEVCHK ( ca_clear_event ( pTestData->m_eventData[j].m_id ) , NULL );
epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
pTestData->m_eventData[j].m_callbackIsOk = FALSE;
epicsMutexUnlock ( pTestData->m_mutex );
}
/*
* return to the original priority
*/
epicsThreadSetPriority ( epicsThreadGetIdSelf(), priorityOfTestThread );
if ( i % 1000 == 0 ) {
showProgress ( pTestData->m_interestLevel );
}
}
SEVCHK ( ca_clear_channel ( pTestData->m_chan ), NULL );
ca_context_destroy ();
epicsEventSignal ( pTestData->m_testDoneEvent );
}
/*
* verify that, in a preemtive callback mode client, a subscription callback never
* comes after the subscription is destroyed
*/
static void multiSubscrDestroyNoLateCallbackTest ( const char *pName, unsigned interestLevel )
{
struct MultiSubscrDestroyNoLateCallbackTestData * pTestData;
showProgressBegin ( "multiSubscrDestroyNoLateCallbackTest", interestLevel );
pTestData = calloc ( 1u, sizeof ( struct MultiSubscrDestroyNoLateCallbackTestData ) );
verify ( pTestData );
pTestData->m_mutex = epicsMutexMustCreate ();
pTestData->m_testDoneEvent = epicsEventMustCreate ( epicsEventEmpty );
pTestData->m_pChanName = pName;
pTestData->m_interestLevel = interestLevel;
epicsThreadMustCreate (
"multiSubscrDestroyNoLateCallbackTest",
epicsThreadPriorityLow,
epicsThreadGetStackSize ( epicsThreadStackMedium ),
multiSubscrDestroyNoLateCallbackThread,
pTestData );
/*
* wait for test to complete
*/
epicsEventMustWait ( pTestData->m_testDoneEvent );
/*
* cleanup
*/
epicsMutexDestroy ( pTestData->m_mutex );
epicsEventDestroy ( pTestData->m_testDoneEvent );
free ( pTestData );
showProgressEnd ( interestLevel );
}
/*
* multiSubscriptionDeleteTest
*
@@ -3263,6 +3416,11 @@ int acctst ( const char * pName, unsigned interestLevel, unsigned channelCount,
epicsEnvSet ( "EPICS_CA_MAX_ARRAY_BYTES", tmpString );
}
/*
* this test creates, and then destroys, a private CA context
*/
multiSubscrDestroyNoLateCallbackTest ( pName, interestLevel );
status = ca_context_create ( select );
SEVCHK ( status, NULL );
-7
View File
@@ -332,13 +332,6 @@ void bhe::unregisterIIU (
}
}
void * bhe::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void bhe::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
-1
View File
@@ -87,7 +87,6 @@ private:
const epicsTime & currentTime );
bhe ( const bhe & );
bhe & operator = ( const bhe & );
void * operator new ( size_t size );
epicsShareFunc void operator delete ( void * );
};
+26 -6
View File
@@ -106,7 +106,7 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
{
osiSockIoctl_t yes = true;
int status = socket_ioctl ( this->sock, // X aCC 392
int status = socket_ioctl ( this->sock,
FIONBIO, & yes);
if ( status < 0 ) {
char sockErrBuf[64];
@@ -126,7 +126,7 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
memset ( (char *)&addr, 0 , sizeof ( addr ) );
addr.ia.sin_family = AF_INET;
addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
addr.ia.sin_port = htons ( PORT_ANY ); // X aCC 818
addr.ia.sin_port = htons ( PORT_ANY );
int status = bind (this->sock, &addr.sa, sizeof (addr) );
if ( status < 0 ) {
char sockErrBuf[64];
@@ -159,9 +159,9 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
this->localPort = htons ( tmpAddr.ia.sin_port );
}
epics_auto_ptr < epicsGuard < epicsMutex > > pCBGuard;
epics_auto_ptr < CallbackGuard > pCBGuard;
if ( ! enablePreemptiveCallback ) {
pCBGuard.reset ( new epicsGuard < epicsMutex > ( this->cbMutex ) );
pCBGuard.reset ( new CallbackGuard ( this->cbMutex ) );
}
// multiple steps ensure exception safety
@@ -277,7 +277,7 @@ int ca_client_context :: printFormated (
}
int ca_client_context :: varArgsPrintFormated (
const char *pformat, va_list args ) const // X aCC 361
const char *pformat, va_list args ) const
{
caPrintfFunc * pFunc;
{
@@ -751,6 +751,8 @@ epicsShareFunc int epicsShareAPI ca_clear_subscription ( evid pMon )
{
oldChannelNotify & chan = pMon->channel ();
ca_client_context & cac = chan.getClientCtx ();
// !!!! the order in which we take the mutex here prevents deadlocks
{
epicsGuard < epicsMutex > guard ( cac.mutex );
try {
// if this stalls out on a live circuit then an exception
@@ -761,7 +763,25 @@ epicsShareFunc int epicsShareAPI ca_clear_subscription ( evid pMon )
catch ( cacChannel::notConnected & ) {
// intentionally ignored
}
pMon->cancel ( guard );
}
if ( cac.pCallbackGuard.get() &&
cac.createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( cac.mutex );
pMon->cancel ( *cac.pCallbackGuard.get(), guard );
}
else {
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( cac.cbMutex );
epicsGuard < epicsMutex > guard ( cac.mutex );
pMon->cancel ( cbGuard, guard );
}
return ECA_NORMAL;
}
+7 -6
View File
@@ -568,7 +568,7 @@ bool cac::findOrCreateVirtCircuit (
}
void cac::transferChanToVirtCircuit (
unsigned cid, unsigned sid, // X aCC 431
unsigned cid, unsigned sid,
ca_uint16_t typeCode, arrayElementCount count,
unsigned minorVersionNumber, const osiSockAddr & addr,
const epicsTime & currentTime )
@@ -711,6 +711,7 @@ netReadNotifyIO & cac::readNotifyRequest (
}
bool cac::destroyIO (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & guard,
const cacChannel::ioid & idIn, nciu & chan )
{
@@ -787,7 +788,7 @@ void cac::recycleSubscription (
netSubscription & cac::subscriptionRequest (
epicsGuard < epicsMutex > & guard,
nciu & chan, privateInterfaceForIO & privChan,
unsigned type, // X aCC 361
unsigned type,
arrayElementCount nElem, unsigned mask,
cacStateNotify & notifyIn,
bool chanIsInstalled )
@@ -1021,7 +1022,7 @@ bool cac::readExcep ( callbackManager &, tcpiiu &,
}
bool cac::writeExcep (
callbackManager & mgr, // X aCC 431
callbackManager & mgr,
tcpiiu &, const caHdrLargeArray & hdr,
const char * pCtx, unsigned status )
{
@@ -1093,7 +1094,7 @@ bool cac::exceptionRespAction ( callbackManager & cbMutexIn, tcpiiu & iiu,
}
bool cac::accessRightsRespAction (
callbackManager & mgr, tcpiiu &, // X aCC 431
callbackManager & mgr, tcpiiu &,
const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ )
{
epicsGuard < epicsMutex > guard ( this->mutex );
@@ -1110,7 +1111,7 @@ bool cac::accessRightsRespAction (
}
bool cac::createChannelRespAction (
callbackManager & mgr, tcpiiu & iiu, // X aCC 431
callbackManager & mgr, tcpiiu & iiu,
const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ )
{
epicsGuard < epicsMutex > guard ( this->mutex );
@@ -1157,7 +1158,7 @@ bool cac::verifyAndDisconnectChan (
}
void cac::disconnectChannel (
epicsGuard < epicsMutex > & cbGuard, // X aCC 431
epicsGuard < epicsMutex > & cbGuard,
epicsGuard < epicsMutex > & guard, nciu & chan )
{
guard.assertIdenticalMutex ( this->mutex );
+3 -7
View File
@@ -55,7 +55,7 @@ class netSubscription;
// used to control access to cac's recycle routines which
// should only be indirectly invoked by CAC when its lock
// is applied
class cacRecycle { // X aCC 655
class cacRecycle {
public:
virtual void recycleReadNotifyIO (
epicsGuard < epicsMutex > &, netReadNotifyIO &io ) = 0;
@@ -155,7 +155,8 @@ public:
unsigned type, arrayElementCount nElem, unsigned mask,
cacStateNotify &, bool channelIsInstalled );
bool destroyIO (
epicsGuard < epicsMutex > & guard,
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const cacChannel::ioid & idIn,
nciu & chan );
void disconnectAllIO (
@@ -167,11 +168,6 @@ public:
epicsGuard < epicsMutex > & guard,
const cacChannel::ioid &id, unsigned level ) const;
// sync group routines
CASG * lookupCASG ( epicsGuard < epicsMutex > &, unsigned id );
void installCASG ( epicsGuard < epicsMutex > &, CASG & );
void uninstallCASG ( epicsGuard < epicsMutex > &, CASG & );
// exception generation
void exception (
epicsGuard < epicsMutex > & cbGuard,
+26 -7
View File
@@ -69,7 +69,7 @@ typedef unsigned long arrayElementCount;
// 1) this should not be passing caerr.h status to the exception callback
// 2) needless-to-say the data should be passed here using the new data access API
class epicsShareClass cacWriteNotify { // X aCC 655
class epicsShareClass cacWriteNotify {
public:
virtual ~cacWriteNotify () = 0;
virtual void completion ( epicsGuard < epicsMutex > & ) = 0;
@@ -82,7 +82,7 @@ public:
// 1) this should not be passing caerr.h status to the exception callback
// 2) needless-to-say the data should be passed here using the new data access API
class epicsShareClass cacReadNotify { // X aCC 655
class epicsShareClass cacReadNotify {
public:
virtual ~cacReadNotify () = 0;
virtual void completion (
@@ -97,7 +97,7 @@ public:
// 1) this should not be passing caerr.h status to the exception callback
// 2) needless-to-say the data should be passed here using the new data access API
class epicsShareClass cacStateNotify { // X aCC 655
class epicsShareClass cacStateNotify {
public:
virtual ~cacStateNotify () = 0;
virtual void current (
@@ -131,7 +131,7 @@ private:
bool f_operatorConfirmationRequest:1;
};
class epicsShareClass cacChannelNotify { // X aCC 655
class epicsShareClass cacChannelNotify {
public:
virtual ~cacChannelNotify () = 0;
virtual void connectNotify ( epicsGuard < epicsMutex > & ) = 0;
@@ -152,6 +152,16 @@ public:
unsigned type, arrayElementCount count ) = 0;
};
class CallbackGuard :
public epicsGuard < epicsMutex > {
public:
CallbackGuard ( epicsMutex & mutex ) :
epicsGuard < epicsMutex > ( mutex ) {}
private:
CallbackGuard ( const CallbackGuard & );
CallbackGuard & operator = ( const CallbackGuard & );
};
//
// Notes
// 1) This interface assumes that when a channel is deleted then all
@@ -174,6 +184,7 @@ public:
cacChannel ( cacChannelNotify & );
virtual void destroy (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
cacChannelNotify & notify () const; // required ?????
virtual unsigned getName (
@@ -207,7 +218,15 @@ public:
epicsGuard < epicsMutex > &, unsigned type,
arrayElementCount count, unsigned mask, cacStateNotify &,
ioid * = 0 ) = 0;
// The primary mutex must be released when calling the user's
// callback, and therefore a finite interval exists when we are
// moving forward with the intent to call the users callback
// but the users IO could be deleted during this interval.
// To prevent the user's callback from being called after
// destroying his IO we must past a guard for the callback
// mutex here.
virtual void ioCancel (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const ioid & ) = 0;
virtual void ioShow (
@@ -258,7 +277,7 @@ private:
cacChannel & operator = ( const cacChannel & );
};
class epicsShareClass cacContext { // X aCC 655
class epicsShareClass cacContext {
public:
virtual ~cacContext ();
virtual cacChannel & createChannel (
@@ -277,7 +296,7 @@ public:
epicsGuard < epicsMutex > &, unsigned level ) const = 0;
};
class epicsShareClass cacContextNotify { // X aCC 655
class epicsShareClass cacContextNotify {
public:
virtual ~cacContextNotify () = 0;
virtual cacContext & createNetworkContext (
@@ -297,7 +316,7 @@ public:
// **** Lock Hierarchy ****
// callbackControl must be taken before mutualExclusion if both are held at
// the same time
class epicsShareClass cacService { // X aCC 655
class epicsShareClass cacService {
public:
virtual ~cacService () = 0;
virtual cacContext & contextCreate (
+2 -2
View File
@@ -131,7 +131,7 @@ int main ( int argc, char ** argv )
}
osiSockIoctl_t yes = true;
status = socket_ioctl ( sock, FIONBIO, &yes ); // X aCC 392
status = socket_ioctl ( sock, FIONBIO, &yes );
if ( status < 0 ) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
@@ -166,7 +166,7 @@ int main ( int argc, char ** argv )
}
osiSockIoctl_t no = false;
status = socket_ioctl ( sock, FIONBIO, &no ); // X aCC 392
status = socket_ioctl ( sock, FIONBIO, &no );
if ( status < 0 ) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
+2 -3
View File
@@ -44,7 +44,7 @@ public:
virtual void release ( void * ) = 0;
};
class wireSendAdapter { // X aCC 655
class wireSendAdapter {
public:
virtual unsigned sendBytes ( const void * pBuf,
unsigned nBytesInBuf,
@@ -65,7 +65,7 @@ struct statusWireIO {
swioCircuitState circuitState;
};
class wireRecvAdapter { // X aCC 655
class wireRecvAdapter {
public:
virtual void recvBytes ( void * pBuf,
unsigned nBytesInBuf, statusWireIO & ) = 0;
@@ -114,7 +114,6 @@ private:
unsigned nextWriteIndex;
unsigned nextReadIndex;
epicsUInt8 buf [ comBufSize ];
void * operator new ( size_t size );
void operator delete ( void * );
template < class T >
bool push ( const T * ); // disabled
+1 -1
View File
@@ -155,7 +155,7 @@ epicsUInt32 comQueRecv::multiBufferPopUInt32 ()
unsigned byte3 = this->popUInt8();
unsigned byte4 = this->popUInt8();
tmp = static_cast <epicsUInt32>
( ( byte1 << 24u ) | ( byte2 << 16u ) | //X aCC 392
( ( byte1 << 24u ) | ( byte2 << 16u ) |
( byte3 << 8u ) | byte4 );
}
else {
+1 -1
View File
@@ -368,7 +368,7 @@ void comQueSend::insertRequestWithPayLoad (
// the above checks verify that the total size
// is lest that 0xffffffff
size = static_cast < ca_uint32_t >
( dbr_size_n ( dataType, nElem ) ); // X aCC 392
( dbr_size_n ( dataType, nElem ) );
payloadSize = CA_MESSAGE_ALIGN ( size );
this->insertRequestHeader ( request, payloadSize,
static_cast <ca_uint16_t> ( dataType ),
+1 -1
View File
@@ -65,7 +65,7 @@ void disconnectGovernorTimer::shutdown (
}
epicsTimerNotify::expireStatus disconnectGovernorTimer::expire (
const epicsTime & /* currentTime */ ) // X aCC 361
const epicsTime & /* currentTime */ )
{
epicsGuard < epicsMutex > guard ( this->mutex );
while ( nciu * pChan = chanList.get () ) {
+1 -1
View File
@@ -43,7 +43,7 @@
#include "caProto.h"
#include "netiiu.h"
class disconnectGovernorNotify { // X aCC 655
class disconnectGovernorNotify {
public:
virtual ~disconnectGovernorNotify () = 0;
virtual void govExpireNotify (
-7
View File
@@ -90,13 +90,6 @@ void getCallback::exception (
}
}
void * getCallback::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void getCallback::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
-7
View File
@@ -105,13 +105,6 @@ void getCopy::show ( unsigned level ) const
}
}
void * getCopy::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void getCopy::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
+10 -10
View File
@@ -133,7 +133,7 @@ extern "C" void epicsShareAPI removeDuplicateAddresses
if ( pNode->addr.sa.sa_family == AF_INET ) {
pTmpNode = (osiSockAddrNode *) ellFirst (pDestList); // X aCC 749
pTmpNode = (osiSockAddrNode *) ellFirst (pDestList);
while ( pTmpNode ) {
if (pTmpNode->addr.sa.sa_family == AF_INET) {
if ( pNode->addr.ia.sin_addr.s_addr == pTmpNode->addr.ia.sin_addr.s_addr &&
@@ -149,7 +149,7 @@ extern "C" void epicsShareAPI removeDuplicateAddresses
break;
}
}
pTmpNode = (osiSockAddrNode *) ellNext (&pTmpNode->node); // X aCC 749
pTmpNode = (osiSockAddrNode *) ellNext (&pTmpNode->node);
}
if (pNode) {
ellAdd (pDestList, &pNode->node);
@@ -168,12 +168,12 @@ static void forcePort ( ELLLIST *pList, unsigned short port )
{
osiSockAddrNode *pNode;
pNode = ( osiSockAddrNode * ) ellFirst ( pList ); // X aCC 749
pNode = ( osiSockAddrNode * ) ellFirst ( pList );
while ( pNode ) {
if ( pNode->addr.sa.sa_family == AF_INET ) {
pNode->addr.ia.sin_port = htons ( port );
}
pNode = ( osiSockAddrNode * ) ellNext ( &pNode->node ); // X aCC 749
pNode = ( osiSockAddrNode * ) ellNext ( &pNode->node );
}
}
@@ -192,9 +192,9 @@ extern "C" void epicsShareAPI configureChannelAccessAddressList
/*
* dont load the list twice
*/
assert ( ellCount (pList) == 0 ); // X aCC 392
assert ( ellCount (pList) == 0 );
ellInit ( &tmpList ); // X aCC 392
ellInit ( &tmpList );
/*
* Check to see if the user has disabled
@@ -217,12 +217,12 @@ extern "C" void epicsShareAPI configureChannelAccessAddressList
if (yes) {
ELLLIST bcastList;
osiSockAddr addr;
ellInit ( &bcastList ); // X aCC 392
ellInit ( &bcastList );
addr.ia.sin_family = AF_UNSPEC;
osiSockDiscoverBroadcastAddresses ( &bcastList, sock, &addr );
forcePort ( &bcastList, port );
removeDuplicateAddresses ( &tmpList, &bcastList, 1 );
if ( ellCount ( &tmpList ) == 0 ) { // X aCC 392
if ( ellCount ( &tmpList ) == 0 ) {
osiSockAddrNode *pNewNode;
pNewNode = (osiSockAddrNode *) calloc ( 1, sizeof (*pNewNode) );
if ( pNewNode ) {
@@ -254,11 +254,11 @@ extern "C" void epicsShareAPI printChannelAccessAddressList ( const ELLLIST *pLi
osiSockAddrNode *pNode;
::printf ( "Channel Access Address List\n" );
pNode = (osiSockAddrNode *) ellFirst ( pList ); // X aCC 749
pNode = (osiSockAddrNode *) ellFirst ( pList );
while (pNode) {
char buf[64];
ipAddrToA ( &pNode->addr.ia, buf, sizeof ( buf ) );
::printf ( "%s\n", buf );
pNode = (osiSockAddrNode *) ellNext ( &pNode->node ); // X aCC 749
pNode = (osiSockAddrNode *) ellNext ( &pNode->node );
}
}
-7
View File
@@ -73,13 +73,6 @@ void msgForMultiplyDefinedPV::operator delete ( void *pCadaver,
}
#endif
void * msgForMultiplyDefinedPV::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void msgForMultiplyDefinedPV::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
+1 -2
View File
@@ -39,7 +39,7 @@
# define epicsExportSharedSymbols
#endif
class callbackForMultiplyDefinedPV { // X aCC 655
class callbackForMultiplyDefinedPV {
public:
virtual ~callbackForMultiplyDefinedPV () = 0;
virtual void pvMultiplyDefinedNotify (
@@ -64,7 +64,6 @@ private:
void transactionComplete ( const char * pHostName );
msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & );
msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & );
void * operator new ( size_t size );
void operator delete ( void * );
};
+14 -16
View File
@@ -76,29 +76,24 @@ nciu::~nciu ()
// channels are created by the user, and only destroyed by the user
// using this routine
void nciu::destroy (
epicsGuard < epicsMutex > & guard )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExcusionGuard )
{
while ( baseNMIU * pNetIO = this->eventq.first () ) {
bool success = this->cacCtx.destroyIO ( guard, pNetIO->getId (), *this );
bool success = this->cacCtx.destroyIO ( callbackGuard, mutualExcusionGuard,
pNetIO->getId (), *this );
assert ( success );
}
// if the claim reply has not returned yet then we will issue
// the clear channel request to the server when the claim reply
// arrives and there is no matching nciu in the client
if ( this->channelNode::isInstalledInServer ( guard ) ) {
this->getPIIU(guard)->clearChannelRequest (
guard, this->sid, this->id );
if ( this->channelNode::isInstalledInServer ( mutualExcusionGuard ) ) {
this->getPIIU(mutualExcusionGuard)->clearChannelRequest (
mutualExcusionGuard, this->sid, this->id );
}
this->piiu->uninstallChan ( guard, *this );
this->cacCtx.destroyChannel ( guard, *this );
}
void * nciu::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
this->piiu->uninstallChan ( mutualExcusionGuard, *this );
this->cacCtx.destroyChannel ( mutualExcusionGuard, *this );
}
void nciu::operator delete ( void * )
@@ -387,9 +382,12 @@ void nciu::subscribe (
}
void nciu::ioCancel (
epicsGuard < epicsMutex > & guard, const ioid & idIn )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const ioid & idIn )
{
this->cacCtx.destroyIO ( guard, idIn, *this );
this->cacCtx.destroyIO ( callbackGuard,
mutualExclusionGuard, idIn, *this );
}
void nciu::ioShow (
+10 -2
View File
@@ -121,7 +121,7 @@ private:
friend class disconnectGovernorTimer;
};
class privateInterfaceForIO { // X aCC 655
class privateInterfaceForIO {
public:
virtual void ioCompletionNotify (
epicsGuard < epicsMutex > &, class baseNMIU & ) = 0;
@@ -220,6 +220,7 @@ private:
ca_uint16_t typeCode;
ca_uint8_t priority;
virtual void destroy (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard );
void initiateConnect (
epicsGuard < epicsMutex > & );
@@ -243,7 +244,15 @@ private:
epicsGuard < epicsMutex > & guard,
unsigned type, arrayElementCount nElem,
unsigned mask, cacStateNotify &notify, ioid * );
// The primary mutex must be released when calling the user's
// callback, and therefore a finite interval exists when we are
// moving forward with the intent to call the users callback
// but the users IO could be deleted during this interval.
// To prevent the user's callback from being called after
// destroying his IO we must past a guard for the callback
// mutex here.
virtual void ioCancel (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const ioid & );
void ioShow (
@@ -270,7 +279,6 @@ private:
epicsGuard < epicsMutex > & guard ) const throw ();
nciu ( const nciu & );
nciu & operator = ( const nciu & );
void * operator new ( size_t );
void operator delete ( void * );
};
+5 -8
View File
@@ -42,7 +42,7 @@
class privateInterfaceForIO;
class baseNMIU : public tsDLNode < baseNMIU >, // X aCC 655
class baseNMIU : public tsDLNode < baseNMIU >,
public chronIntIdRes < baseNMIU > {
public:
virtual void destroy (
@@ -106,7 +106,6 @@ private:
const unsigned mask;
bool subscribed;
class netSubscription * isSubscription ();
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class netSubscription, 1024, epicsMutexNOOP > & );
@@ -147,7 +146,6 @@ protected:
private:
cacReadNotify & notify;
class privateInterfaceForIO & privateChanForIO;
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & );
@@ -190,7 +188,6 @@ protected:
private:
cacWriteNotify & notify;
privateInterfaceForIO & privateChanForIO;
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & );
@@ -237,12 +234,12 @@ inline netSubscription * netSubscription::factory (
class privateInterfaceForIO & chan, unsigned type, arrayElementCount count,
unsigned mask, cacStateNotify &notify )
{
return new ( freeList ) netSubscription ( chan, type, // X aCC 930
return new ( freeList ) netSubscription ( chan, type,
count, mask, notify );
}
inline arrayElementCount netSubscription::getCount (
epicsGuard < epicsMutex > & guard, bool allow_zero ) const // X aCC 361
epicsGuard < epicsMutex > & guard, bool allow_zero ) const
{
//guard.assertIdenticalMutex ( this->mutex );
arrayElementCount nativeCount = this->privateChanForIO.nativeElementCount ( guard );
@@ -268,7 +265,7 @@ inline netReadNotifyIO * netReadNotifyIO::factory (
tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & freeList,
privateInterfaceForIO & ioComplNotifIntf, cacReadNotify & notify )
{
return new ( freeList ) netReadNotifyIO ( ioComplNotifIntf, notify ); // X aCC 930
return new ( freeList ) netReadNotifyIO ( ioComplNotifIntf, notify );
}
inline void * netReadNotifyIO::operator new ( size_t size,
@@ -289,7 +286,7 @@ inline netWriteNotifyIO * netWriteNotifyIO::factory (
tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & freeList,
privateInterfaceForIO & ioComplNotifyIntf, cacWriteNotify & notify )
{
return new ( freeList ) netWriteNotifyIO ( ioComplNotifyIntf, notify ); // X aCC 930
return new ( freeList ) netWriteNotifyIO ( ioComplNotifyIntf, notify );
}
inline void * netWriteNotifyIO::operator new ( size_t size,
-7
View File
@@ -119,13 +119,6 @@ void netReadNotifyIO::forceSubscriptionUpdate (
{
}
void * netReadNotifyIO::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void netReadNotifyIO::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
-7
View File
@@ -170,13 +170,6 @@ void netSubscription::forceSubscriptionUpdate (
guard, chan, *this );
}
void * netSubscription::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void netSubscription::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
-8
View File
@@ -117,14 +117,6 @@ void netWriteNotifyIO::forceSubscriptionUpdate (
{
}
void * netWriteNotifyIO::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error (
"why is the compiler calling private operator new" );
}
void netWriteNotifyIO::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
+1 -1
View File
@@ -35,7 +35,7 @@ union osiSockAddr;
class cac;
class nciu;
class netiiu { // X aCC 655
class netiiu {
public:
virtual ~netiiu () = 0;
virtual unsigned getHostName (
+59 -12
View File
@@ -53,7 +53,8 @@ public:
const char * pName, caCh * pConnCallBackIn,
void * pPrivateIn, capri priority );
void destructor (
epicsGuard < epicsMutex > & guard );
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & mutexGuard );
// legacy C API
friend unsigned epicsShareAPI ca_get_host_name (
@@ -122,6 +123,7 @@ public:
unsigned type, arrayElementCount count, const void *pValue,
cacWriteNotify &, cacChannel::ioid *pId = 0 );
void ioCancel (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const cacChannel::ioid & );
void ioShow (
@@ -162,7 +164,6 @@ private:
unsigned type, arrayElementCount count );
oldChannelNotify ( const oldChannelNotify & );
oldChannelNotify & operator = ( const oldChannelNotify & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -195,7 +196,6 @@ private:
const char *pContext, unsigned type, arrayElementCount count );
getCopy ( const getCopy & );
getCopy & operator = ( const getCopy & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -221,7 +221,6 @@ private:
const char * pContext, unsigned type, arrayElementCount count );
getCallback ( const getCallback & );
getCallback & operator = ( const getCallback & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -245,7 +244,6 @@ private:
unsigned type, arrayElementCount count );
putCallback ( const putCallback & );
putCallback & operator = ( const putCallback & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -259,8 +257,16 @@ public:
evid * );
~oldSubscription ();
oldChannelNotify & channel () const;
// The primary mutex must be released when calling the user's
// callback, and therefore a finite interval exists when we are
// moving forward with the intent to call the users callback
// but the users IO could be deleted during this interval.
// To prevent the user's callback from being called after
// destroying his IO we must past a guard for the callback
// mutex here.
void cancel (
epicsGuard < epicsMutex > & guard );
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard );
void * operator new ( size_t size,
tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & );
epicsPlacementDeleteOperator (( void *,
@@ -278,7 +284,6 @@ private:
const char *pContext, unsigned type, arrayElementCount count );
oldSubscription ( const oldSubscription & );
oldSubscription & operator = ( const oldSubscription & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -341,6 +346,8 @@ public:
void destroySubscription ( epicsGuard < epicsMutex > &, oldSubscription & );
epicsMutex & mutexRef () const;
template < class T >
void whenThereIsAnExceptionDestroySyncGroupIO ( epicsGuard < epicsMutex > &, T & );
// legacy C API
friend int epicsShareAPI ca_create_channel (
@@ -368,6 +375,17 @@ public:
friend int epicsShareAPI ca_sg_block ( const CA_SYNC_GID gid, ca_real timeout );
friend int epicsShareAPI ca_sg_reset ( const CA_SYNC_GID gid );
friend int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid );
friend int epicsShareAPI ca_sg_array_get ( const CA_SYNC_GID gid,
chtype type, arrayElementCount count,
chid pChan, void *pValue );
friend int epicsShareAPI ca_sg_array_put ( const CA_SYNC_GID gid,
chtype type, arrayElementCount count,
chid pChan, const void *pValue );
friend int ca_sync_group_destroy ( CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard,
ca_client_context & cac, const CA_SYNC_GID gid );
friend void sync_group_reset ( ca_client_context & client,
CASG & sg );
// exceptions
class noSocket {};
@@ -384,7 +402,7 @@ private:
epicsEvent ioDone;
epicsEvent callbackThreadActivityComplete;
epicsThreadId createdByThread;
epics_auto_ptr < epicsGuard < epicsMutex > > pCallbackGuard;
epics_auto_ptr < CallbackGuard > pCallbackGuard;
epics_auto_ptr < cacContext > pServiceContext;
caExceptionHandler * ca_exception_func;
void * ca_exception_arg;
@@ -444,10 +462,11 @@ inline void oldChannelNotify::initiateConnect (
}
inline void oldChannelNotify::ioCancel (
epicsGuard < epicsMutex > & guard,
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const cacChannel::ioid & id )
{
this->io.ioCancel ( guard, id );
this->io.ioCancel ( callbackGuard, mutualExclusionGuard, id );
}
inline void oldChannelNotify::ioShow (
@@ -492,9 +511,10 @@ inline void oldSubscription::operator delete ( void *pCadaver,
#endif
inline void oldSubscription::cancel (
epicsGuard < epicsMutex > & guard )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard )
{
this->chan.ioCancel ( guard, this->id );
this->chan.ioCancel ( callbackGuard, mutualExclusionGuard, this->id );
}
inline oldChannelNotify & oldSubscription::channel () const
@@ -560,5 +580,32 @@ inline unsigned ca_client_context::sequenceNumberOfOutstandingIO (
// perhaps on SMP systems THERE should be lock/unlock around this
return this->ioSeqNo;
}
template < class T >
void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO (
epicsGuard < epicsMutex > & guard, T & io )
{
if ( this->pCallbackGuard.get() &&
this->createdByThread == epicsThreadGetIdSelf () ) {
io.destroy ( *this->pCallbackGuard.get(), guard );
}
else {
// dont reverse the lock hierarchy
epicsGuardRelease < epicsMutex > guardRelease ();
{
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( this->cbMutex );
epicsGuard < epicsMutex > guard ( this->mutex );
io.destroy ( cbGuard, guard );
}
}
}
#endif // ifndef oldAccessh
+6 -12
View File
@@ -65,14 +65,15 @@ oldChannelNotify::~oldChannelNotify ()
}
void oldChannelNotify::destructor (
epicsGuard < epicsMutex > & guard )
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & mutexGuard )
{
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
this->io.destroy ( guard );
mutexGuard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
this->io.destroy ( cbGuard, mutexGuard );
// no need to worry about a connect preempting here because
// the io (the nciu) has been destroyed above
if ( this->pConnCallBack == 0 && ! this->currentlyConnected ) {
this->cacCtx.decrementOutstandingIO ( guard, this->ioSeqNo );
this->cacCtx.decrementOutstandingIO ( mutexGuard, this->ioSeqNo );
}
this->~oldChannelNotify ();
}
@@ -159,13 +160,6 @@ void oldChannelNotify::writeException (
__FILE__, __LINE__, *this, type, count, CA_OP_PUT );
}
void * oldChannelNotify::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void oldChannelNotify::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
@@ -638,7 +632,7 @@ arrayElementCount epicsShareAPI ca_element_count ( chid pChan )
/*
* ca_state ()
*/
enum channel_state epicsShareAPI ca_state ( chid pChan ) // X aCC 361
enum channel_state epicsShareAPI ca_state ( chid pChan )
{
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
if ( pChan->io.connected ( guard ) ) {
-7
View File
@@ -90,13 +90,6 @@ void putCallback::exception (
}
}
void * putCallback::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void putCallback::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
+3 -10
View File
@@ -178,7 +178,7 @@ bool repeaterClient::connect ()
return true;
}
bool repeaterClient::sendConfirm () // X aCC 361
bool repeaterClient::sendConfirm ()
{
int status;
@@ -204,7 +204,7 @@ bool repeaterClient::sendConfirm () // X aCC 361
}
}
bool repeaterClient::sendMessage ( const void *pBuf, unsigned bufSize ) // X aCC 361
bool repeaterClient::sendMessage ( const void *pBuf, unsigned bufSize )
{
int status;
@@ -245,13 +245,6 @@ repeaterClient::~repeaterClient ()
#endif
}
void * repeaterClient::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void repeaterClient::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
@@ -304,7 +297,7 @@ inline bool repeaterClient::identicalPort ( const osiSockAddr &fromIn )
return false;
}
bool repeaterClient::verify () // X aCC 361
bool repeaterClient::verify ()
{
SOCKET tmpSock;
bool success = makeSocket ( this->port (), false, & tmpSock );
-1
View File
@@ -64,7 +64,6 @@ private:
osiSockAddr from;
SOCKET sock;
unsigned short port () const;
void * operator new ( size_t size );
void operator delete ( void * );
};
+1 -1
View File
@@ -64,7 +64,7 @@ void repeaterSubscribeTimer::shutdown (
}
epicsTimerNotify::expireStatus repeaterSubscribeTimer::
expire ( const epicsTime & /* currentTime */ ) // X aCC 361
expire ( const epicsTime & /* currentTime */ )
{
static const unsigned nTriesToMsg = 50;
if ( this->attempts > nTriesToMsg && ! this->once ) {
+1 -1
View File
@@ -43,7 +43,7 @@
class epicsMutex;
class cacContextNotify;
class repeaterTimerNotify { // X aCC 655
class repeaterTimerNotify {
public:
virtual ~repeaterTimerNotify () = 0;
virtual void repeaterRegistrationMessage (
+1 -1
View File
@@ -124,7 +124,7 @@ void searchTimer::moveChannels (
// searchTimer::expire ()
//
epicsTimerNotify::expireStatus searchTimer::expire (
const epicsTime & currentTime ) // X aCC 361
const epicsTime & currentTime )
{
epicsGuard < epicsMutex > guard ( this->mutex );
+1 -1
View File
@@ -43,7 +43,7 @@
#include "caProto.h"
#include "netiiu.h"
class searchTimerNotify { // X aCC 655
class searchTimerNotify {
public:
virtual ~searchTimerNotify () = 0;
virtual void boostChannel (
+10 -11
View File
@@ -29,8 +29,7 @@
template < class T >
class sgAutoPtr {
public:
sgAutoPtr ( epicsGuard < epicsMutex > &,
struct CASG &, tsDLList < syncGroupNotify > & );
sgAutoPtr ( epicsGuard < epicsMutex > &, struct CASG & );
~sgAutoPtr ();
sgAutoPtr < T > & operator = ( T * );
T * operator -> ();
@@ -38,7 +37,6 @@ public:
T * get ();
T * release ();
private:
tsDLList < syncGroupNotify > & list;
T * pNotify;
struct CASG & sg;
epicsGuard < epicsMutex > & guard;
@@ -47,9 +45,8 @@ private:
template < class T >
inline sgAutoPtr < T > :: sgAutoPtr (
epicsGuard < epicsMutex > & guardIn,
struct CASG & sgIn, tsDLList < syncGroupNotify > & listIn ) :
list ( listIn ), pNotify ( 0 ), sg ( sgIn ), guard ( guardIn )
epicsGuard < epicsMutex > & guardIn, struct CASG & sgIn ) :
pNotify ( 0 ), sg ( sgIn ), guard ( guardIn )
{
}
@@ -57,8 +54,9 @@ template < class T >
inline sgAutoPtr < T > :: ~sgAutoPtr ()
{
if ( this->pNotify ) {
list.remove ( *this->pNotify );
pNotify->destroy ( this->guard, this->sg );
this->sg.ioPendingList.remove ( *this->pNotify );
this->sg.client.
whenThereIsAnExceptionDestroySyncGroupIO ( this->guard, *this->pNotify );
}
}
@@ -66,11 +64,12 @@ template < class T >
inline sgAutoPtr < T > & sgAutoPtr < T > :: operator = ( T * pNotifyIn )
{
if ( this->pNotify ) {
list.remove ( *this->pNotify );
pNotify->destroy ( this->guard, this->sg );
this->sg.ioPendingList.remove ( *this->pNotify );
this->sg.client.
whenThereIsAnExceptionDestroySyncGroupIO ( this->guard, *this->pNotify );
}
this->pNotify = pNotifyIn;
list.add ( *this->pNotify );
this->sg.ioPendingList.add ( *this->pNotify );
return *this;
}
+35 -35
View File
@@ -46,29 +46,17 @@
static const unsigned CASG_MAGIC = 0xFAB4CAFE;
// used to control access to CASG's recycle routines which
// should only be indirectly invoked by CASG when its lock
// is applied
class casgRecycle { // X aCC 655
public:
virtual void recycleSyncGroupWriteNotify (
epicsGuard < epicsMutex > &, class syncGroupWriteNotify & io ) = 0;
virtual void recycleSyncGroupReadNotify (
epicsGuard < epicsMutex > &, class syncGroupReadNotify & io ) = 0;
protected:
virtual ~casgRecycle ();
};
class syncGroupNotify : public tsDLNode < syncGroupNotify > {
public:
syncGroupNotify ();
virtual void destroy (
epicsGuard < epicsMutex > & guard,
casgRecycle & ) = 0;
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard ) = 0;
virtual bool ioPending (
epicsGuard < epicsMutex > & guard ) = 0;
virtual void cancel (
epicsGuard < epicsMutex > & guard ) = 0;
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
virtual void show (
epicsGuard < epicsMutex > &,
unsigned level ) const = 0;
@@ -78,33 +66,38 @@ protected:
syncGroupNotify & operator = ( const syncGroupNotify & );
};
struct CASG;
class syncGroupReadNotify : public syncGroupNotify, public cacReadNotify {
public:
typedef void ( CASG :: * PRecycleFunc )
( epicsGuard < epicsMutex > &, syncGroupReadNotify & );
static syncGroupReadNotify * factory (
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &,
struct CASG &, chid, void *pValueIn );
CASG &, PRecycleFunc, chid, void *pValueIn );
void destroy (
epicsGuard < epicsMutex > & guard,
casgRecycle & );
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
bool ioPending (
epicsGuard < epicsMutex > & guard );
void begin ( epicsGuard < epicsMutex > &,
unsigned type, arrayElementCount count );
void cancel (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
protected:
syncGroupReadNotify ( struct CASG & sgIn, chid, void * pValueIn );
syncGroupReadNotify ( CASG & sgIn, PRecycleFunc, chid, void * pValueIn );
virtual ~syncGroupReadNotify ();
private:
chid chan;
struct CASG & sg;
PRecycleFunc pRecycleFunc;
CASG & sg;
void * pValue;
const unsigned magic;
cacChannel::ioid id;
bool idIsValid;
bool ioComplete;
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & );
@@ -122,30 +115,33 @@ private:
class syncGroupWriteNotify : public syncGroupNotify, public cacWriteNotify {
public:
typedef void ( CASG :: * PRecycleFunc )
( epicsGuard < epicsMutex > &, syncGroupWriteNotify & );
static syncGroupWriteNotify * factory (
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &,
struct CASG &, chid );
CASG &, PRecycleFunc, chid );
void destroy (
epicsGuard < epicsMutex > & guard,
casgRecycle & );
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
bool ioPending (
epicsGuard < epicsMutex > & guard );
void begin ( epicsGuard < epicsMutex > &, unsigned type,
arrayElementCount count, const void * pValueIn );
void cancel (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
protected:
syncGroupWriteNotify ( struct CASG &, chid );
syncGroupWriteNotify ( struct CASG &, PRecycleFunc, chid );
virtual ~syncGroupWriteNotify (); // allocate only from pool
private:
chid chan;
struct CASG & sg;
PRecycleFunc pRecycleFunc;
CASG & sg;
const unsigned magic;
cacChannel::ioid id;
bool idIsValid;
bool ioComplete;
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & );
@@ -163,17 +159,19 @@ struct ca_client_context;
template < class T > class sgAutoPtr;
struct CASG : public chronIntIdRes < CASG >, private casgRecycle {
struct CASG : public chronIntIdRes < CASG > {
public:
CASG ( epicsGuard < epicsMutex > &, ca_client_context & cacIn );
void destructor (
CallbackGuard &,
epicsGuard < epicsMutex > & guard );
bool ioComplete (
CallbackGuard &,
epicsGuard < epicsMutex > & guard );
bool verify ( epicsGuard < epicsMutex > & ) const;
int block ( epicsGuard < epicsMutex > * pcbGuard,
epicsGuard < epicsMutex > & guard, double timeout );
void reset ( epicsGuard < epicsMutex > & guard );
void reset ( CallbackGuard &, epicsGuard < epicsMutex > & );
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
void show ( unsigned level ) const;
void get ( epicsGuard < epicsMutex > &, chid pChan,
@@ -194,6 +192,7 @@ public:
tsFreeList < struct CASG, 128, epicsMutexNOOP > & );
epicsPlacementDeleteOperator (( void *,
tsFreeList < struct CASG, 128, epicsMutexNOOP > & ))
private:
tsDLList < syncGroupNotify > ioPendingList;
tsDLList < syncGroupNotify > ioCompletedList;
@@ -202,20 +201,21 @@ private:
unsigned magic;
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > freeListReadOP;
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > freeListWriteOP;
void recycleSyncGroupWriteNotify (
epicsGuard < epicsMutex > &, syncGroupWriteNotify & io );
void recycleSyncGroupReadNotify (
epicsGuard < epicsMutex > &, syncGroupReadNotify & io );
void destroyPendingIO (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
void destroyCompletedIO (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
void recycleReadNotifyIO ( epicsGuard < epicsMutex > &,
syncGroupReadNotify & );
void recycleWriteNotifyIO ( epicsGuard < epicsMutex > &,
syncGroupWriteNotify & );
CASG ( const CASG & );
CASG & operator = ( const CASG & );
void * operator new ( size_t size );
void operator delete ( void * );
~CASG ();
+14 -16
View File
@@ -27,8 +27,10 @@
#include "oldAccess.h"
syncGroupReadNotify::syncGroupReadNotify (
CASG & sgIn, chid pChan, void * pValueIn ) :
chan ( pChan ), sg ( sgIn ), pValue ( pValueIn ),
CASG & sgIn, PRecycleFunc pRecycleFuncIn,
chid pChan, void * pValueIn ) :
chan ( pChan ), pRecycleFunc ( pRecycleFuncIn ),
sg ( sgIn ), pValue ( pValueIn ),
magic ( CASG_MAGIC ), id ( 0u ),
idIsValid ( false ), ioComplete ( false )
{
@@ -46,27 +48,30 @@ void syncGroupReadNotify::begin (
}
void syncGroupReadNotify::cancel (
epicsGuard < epicsMutex > & guard )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExcusionGuard )
{
if ( this->idIsValid ) {
this->chan->ioCancel ( guard, this->id );
this->chan->ioCancel ( callbackGuard, mutualExcusionGuard, this->id );
this->idIsValid = false;
}
}
syncGroupReadNotify * syncGroupReadNotify::factory (
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & freeList,
struct CASG & sg, chid chan, void * pValueIn )
struct CASG & sg, PRecycleFunc pRecycleFunc, chid chan, void * pValueIn )
{
return new ( freeList ) // X aCC 930
syncGroupReadNotify ( sg, chan, pValueIn );
return new ( freeList )
syncGroupReadNotify ( sg, pRecycleFunc, chan, pValueIn );
}
void syncGroupReadNotify::destroy (
epicsGuard < epicsMutex > & guard, casgRecycle & recycle )
CallbackGuard &,
epicsGuard < epicsMutex > & guard )
{
CASG & sgRef ( this->sg );
this->~syncGroupReadNotify ();
recycle.recycleSyncGroupReadNotify ( guard, *this );
( sgRef.*pRecycleFunc ) ( guard, *this );
}
syncGroupReadNotify::~syncGroupReadNotify ()
@@ -122,13 +127,6 @@ void syncGroupReadNotify::show (
}
}
void * syncGroupReadNotify::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void syncGroupReadNotify::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
+13 -15
View File
@@ -26,8 +26,10 @@
#include "syncGroup.h"
#include "oldAccess.h"
syncGroupWriteNotify::syncGroupWriteNotify ( CASG & sgIn, chid pChan ) :
chan ( pChan ), sg ( sgIn ), magic ( CASG_MAGIC ),
syncGroupWriteNotify::syncGroupWriteNotify ( CASG & sgIn,
PRecycleFunc pRecycleFuncIn, chid pChan ) :
chan ( pChan ), pRecycleFunc ( pRecycleFuncIn ),
sg ( sgIn ), magic ( CASG_MAGIC ),
id ( 0u ), idIsValid ( false ), ioComplete ( false )
{
}
@@ -45,26 +47,29 @@ void syncGroupWriteNotify::begin (
}
void syncGroupWriteNotify::cancel (
epicsGuard < epicsMutex > & guard )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExcusionGuard )
{
if ( this->idIsValid ) {
this->chan->ioCancel ( guard, this->id );
this->chan->ioCancel ( callbackGuard, mutualExcusionGuard, this->id );
this->idIsValid = false;
}
}
syncGroupWriteNotify * syncGroupWriteNotify::factory (
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &freeList,
struct CASG & sg, chid chan )
struct CASG & sg, PRecycleFunc pRecycleFunc, chid chan )
{
return new ( freeList ) syncGroupWriteNotify ( sg, chan );
return new ( freeList ) syncGroupWriteNotify ( sg, pRecycleFunc, chan );
}
void syncGroupWriteNotify::destroy (
epicsGuard < epicsMutex > & guard, casgRecycle & recycle )
CallbackGuard &,
epicsGuard < epicsMutex > & guard )
{
CASG & sgRef ( this->sg );
this->~syncGroupWriteNotify ();
recycle.recycleSyncGroupWriteNotify ( guard, *this );
( sgRef.*pRecycleFunc ) ( guard, *this );
}
syncGroupWriteNotify::~syncGroupWriteNotify ()
@@ -112,13 +117,6 @@ void syncGroupWriteNotify::show (
}
}
void * syncGroupWriteNotify::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void syncGroupWriteNotify::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
+97 -26
View File
@@ -23,7 +23,7 @@
/*
* ca_sg_create()
*/
extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid ) // X aCC 361
extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid )
{
ca_client_context * pcac;
int caStatus;
@@ -48,6 +48,22 @@ extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid ) // X aCC 361
}
}
int ca_sync_group_destroy ( CallbackGuard & cbGuard, epicsGuard < epicsMutex > & guard,
ca_client_context & cac, const CA_SYNC_GID gid )
{
int caStatus;
CASG * pcasg = cac.lookupCASG ( guard, gid );
if ( pcasg ) {
pcasg->destructor ( cbGuard, guard );
cac.casgFreeList.release ( pcasg );
caStatus = ECA_NORMAL;
}
else {
caStatus = ECA_BADSYNCGRP;
}
return caStatus;
}
/*
* ca_sg_delete()
*/
@@ -56,19 +72,51 @@ extern "C" int epicsShareAPI ca_sg_delete ( const CA_SYNC_GID gid )
ca_client_context * pcac;
int caStatus = fetchClientContext ( & pcac );
if ( caStatus == ECA_NORMAL ) {
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
if ( pcasg ) {
pcasg->destructor ( guard );
pcac->casgFreeList.release ( pcasg );
if ( pcac->pCallbackGuard.get() &&
pcac->createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( pcac->mutex );
caStatus = ca_sync_group_destroy ( *pcac->pCallbackGuard.get(),
guard, *pcac, gid );
}
else {
caStatus = ECA_BADSYNCGRP;
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( pcac->cbMutex );
epicsGuard < epicsMutex > guard ( pcac->mutex );
caStatus = ca_sync_group_destroy ( cbGuard, guard, *pcac, gid );
}
}
return caStatus;
}
void sync_group_reset ( ca_client_context & client, CASG & sg )
{
if ( client.pCallbackGuard.get() &&
client.createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( client.mutex );
sg.reset ( *client.pCallbackGuard.get(), guard );
}
else {
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( client.cbMutex );
epicsGuard < epicsMutex > guard ( client.mutex );
sg.reset ( cbGuard, guard );
}
}
//
// ca_sg_block ()
//
@@ -84,14 +132,20 @@ extern "C" int epicsShareAPI ca_sg_block (
ca_client_context *pcac;
int status = fetchClientContext ( &pcac );
if ( status == ECA_NORMAL ) {
CASG * pcasg;
{
epicsGuard < epicsMutex > guard ( pcac->mutex );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
status = ECA_BADSYNCGRP;
}
else {
pcasg = pcac->lookupCASG ( guard, gid );
if ( pcasg ) {
status = pcasg->block (
pcac->pCallbackGuard.get (), guard, timeout );
}
else {
status = ECA_BADSYNCGRP;
}
}
if ( pcasg ) {
sync_group_reset ( *pcac, *pcasg );
}
}
return status;
@@ -105,10 +159,14 @@ extern "C" int epicsShareAPI ca_sg_reset ( const CA_SYNC_GID gid )
ca_client_context *pcac;
int caStatus = fetchClientContext (&pcac);
if ( caStatus == ECA_NORMAL ) {
CASG * pcasg;
{
epicsGuard < epicsMutex > guard ( pcac->mutex );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
pcasg = pcac->lookupCASG ( guard, gid );
}
if ( pcasg ) {
pcasg->reset ( guard );
sync_group_reset ( *pcac, *pcasg );
caStatus = ECA_NORMAL;
}
else {
caStatus = ECA_BADSYNCGRP;
@@ -143,7 +201,7 @@ extern "C" int epicsShareAPI ca_sg_stat ( const CA_SYNC_GID gid )
/*
* ca_sg_test
*/
extern "C" int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid ) // X aCC 361
extern "C" int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid )
{
ca_client_context * pcac;
int caStatus = fetchClientContext ( &pcac );
@@ -151,7 +209,26 @@ extern "C" int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid ) // X aCC 361
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
if ( pcasg ) {
if ( pcasg->ioComplete ( guard ) ) {
bool isComplete;
if ( pcac->pCallbackGuard.get() &&
pcac->createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( pcac->mutex );
isComplete = pcasg->ioComplete ( *pcac->pCallbackGuard.get(), guard );
}
else {
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( pcac->cbMutex );
epicsGuard < epicsMutex > guard ( pcac->mutex );
isComplete = pcasg->ioComplete ( cbGuard, guard );
}
if ( isComplete ) {
caStatus = ECA_IODONE;
}
else{
@@ -172,17 +249,14 @@ extern "C" int epicsShareAPI ca_sg_array_put ( const CA_SYNC_GID gid, chtype typ
arrayElementCount count, chid pChan, const void *pValue )
{
ca_client_context *pcac;
CASG *pcasg;
int caStatus;
caStatus = fetchClientContext ( &pcac );
int caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
pcasg = pcac->lookupCASG ( guard, gid );
CASG * const pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
return ECA_BADSYNCGRP;
}
@@ -237,17 +311,14 @@ extern "C" int epicsShareAPI ca_sg_array_get ( const CA_SYNC_GID gid, chtype typ
arrayElementCount count, chid pChan, void *pValue )
{
ca_client_context *pcac;
CASG *pcasg;
int caStatus;
caStatus = fetchClientContext ( &pcac );
int caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
pcasg = pcac->lookupCASG ( guard, gid );
CASG * const pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
return ECA_BADSYNCGRP;
}
+1 -1
View File
@@ -45,7 +45,7 @@ tcpRecvWatchdog::~tcpRecvWatchdog ()
}
epicsTimerNotify::expireStatus
tcpRecvWatchdog::expire ( const epicsTime & /* currentTime */ ) // X aCC 361
tcpRecvWatchdog::expire ( const epicsTime & /* currentTime */ )
{
epicsGuard < epicsMutex > guard ( this->mutex );
if ( this->shuttingDown ) {
+16 -19
View File
@@ -1135,7 +1135,7 @@ void tcpiiu::show ( unsigned level ) const
}
}
bool tcpiiu::setEchoRequestPending ( epicsGuard < epicsMutex > & guard ) // X aCC 361
bool tcpiiu::setEchoRequestPending ( epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1275,12 +1275,9 @@ bool tcpiiu::processIncoming (
this->msgHeaderAvailable = false;
this->curDataBytes = 0u;
}
# if defined ( __HP_aCC ) && _HP_aCC <= 033300
return false; // to make hpux compiler happy...
# endif
}
void tcpiiu::hostNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 431
void tcpiiu::hostNameSetRequest ( epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1310,7 +1307,7 @@ void tcpiiu::hostNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 4
/*
* tcpiiu::userNameSetRequest ()
*/
void tcpiiu::userNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 431
void tcpiiu::userNameSetRequest ( epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1338,7 +1335,7 @@ void tcpiiu::userNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 4
}
void tcpiiu::disableFlowControlRequest (
epicsGuard < epicsMutex > & guard ) // X aCC 431
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1354,7 +1351,7 @@ void tcpiiu::disableFlowControlRequest (
}
void tcpiiu::enableFlowControlRequest (
epicsGuard < epicsMutex > & guard ) // X aCC 431
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1369,7 +1366,7 @@ void tcpiiu::enableFlowControlRequest (
minder.commit ();
}
void tcpiiu::versionMessage ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::versionMessage ( epicsGuard < epicsMutex > & guard,
const cacChannel::priLev & priority )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1389,7 +1386,7 @@ void tcpiiu::versionMessage ( epicsGuard < epicsMutex > & guard, // X aCC 431
minder.commit ();
}
void tcpiiu::echoRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 431
void tcpiiu::echoRequest ( epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1410,7 +1407,7 @@ void tcpiiu::echoRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 431
minder.commit ();
}
void tcpiiu::writeRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::writeRequest ( epicsGuard < epicsMutex > & guard,
nciu &chan, unsigned type, arrayElementCount nElem, const void *pValue )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1425,7 +1422,7 @@ void tcpiiu::writeRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
}
void tcpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard,
nciu &chan, netWriteNotifyIO &io, unsigned type,
arrayElementCount nElem, const void *pValue )
{
@@ -1444,7 +1441,7 @@ void tcpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 43
minder.commit ();
}
void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard,
nciu & chan, netReadNotifyIO & io,
unsigned dataType, arrayElementCount nElem )
{
@@ -1477,7 +1474,7 @@ void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
}
void tcpiiu::createChannelRequest (
nciu & chan, epicsGuard < epicsMutex > & guard ) // X aCC 431
nciu & chan, epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1525,7 +1522,7 @@ void tcpiiu::createChannelRequest (
minder.commit ();
}
void tcpiiu::clearChannelRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::clearChannelRequest ( epicsGuard < epicsMutex > & guard,
ca_uint32_t sid, ca_uint32_t cid )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1547,7 +1544,7 @@ void tcpiiu::clearChannelRequest ( epicsGuard < epicsMutex > & guard, // X aCC 4
// is to try again the next time that we reconnect
//
void tcpiiu::subscriptionRequest (
epicsGuard < epicsMutex > & guard, // X aCC 431
epicsGuard < epicsMutex > & guard,
nciu & chan, netSubscription & subscr )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1599,7 +1596,7 @@ void tcpiiu::subscriptionRequest (
// is to try again the next time that we reconnect
//
void tcpiiu::subscriptionUpdateRequest (
epicsGuard < epicsMutex > & guard, // X aCC 431
epicsGuard < epicsMutex > & guard,
nciu & chan, netSubscription & subscr )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1634,7 +1631,7 @@ void tcpiiu::subscriptionUpdateRequest (
minder.commit ();
}
void tcpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard,
nciu & chan, netSubscription & subscr )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -2052,7 +2049,7 @@ bool tcpiiu::bytesArePendingInOS () const
return false;
#else
osiSockIoctl_t bytesPending = 0; /* shut up purifys yapping */
int status = socket_ioctl ( this->sock, // X aCC 392
int status = socket_ioctl ( this->sock,
FIONREAD, & bytesPending );
if ( status >= 0 ) {
if ( bytesPending > 0 ) {
+2 -2
View File
@@ -78,7 +78,7 @@ extern "C" void epicsShareAPI ca_dump_dbr (
dbr_short_t *pvalue = (dbr_short_t *)pbuffer;
for (i = 0; i < count; i++,pvalue++){
if(count!=1 && (i%10 == 0)) printf("\n");
printf("%d ",* (short *)pvalue); // X aCC 392
printf("%d ",* (short *)pvalue);
}
break;
}
@@ -96,7 +96,7 @@ extern "C" void epicsShareAPI ca_dump_dbr (
dbr_float_t *pvalue = (dbr_float_t *)pbuffer;
for (i = 0; i < count; i++,pvalue++){
if(count!=1 && (i%10 == 0)) printf("\n");
printf("%6.4f ",*(float *)pvalue); // X aCC 392
printf("%6.4f ",*(float *)pvalue);
}
break;
}
+2 -2
View File
@@ -201,7 +201,7 @@ udpiiu::udpiiu (
memset ( (char *)&addr, 0 , sizeof (addr) );
addr.ia.sin_family = AF_INET;
addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
addr.ia.sin_port = htons ( PORT_ANY ); // X aCC 818
addr.ia.sin_port = htons ( PORT_ANY );
status = bind (this->sock, &addr.sa, sizeof (addr) );
if ( status < 0 ) {
char sockErrBuf[64];
@@ -471,7 +471,7 @@ void epicsShareAPI caRepeaterRegistrationMessage (
}
memset ( (char *) &msg, 0, sizeof (msg) );
AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = REPEATER_REGISTER; // X aCC 818
AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = REPEATER_REGISTER;
msg.m_available = saddr.ia.sin_addr.s_addr;
/*
+1 -2
View File
@@ -335,7 +335,6 @@ private:
tcpiiu ( const tcpiiu & );
tcpiiu & operator = ( const tcpiiu & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -372,7 +371,7 @@ inline bool tcpiiu::ca_v49_ok (
}
inline bool tcpiiu::alive (
epicsGuard < epicsMutex > & ) const // X aCC 361
epicsGuard < epicsMutex > & ) const
{
return ( this->state == iiucs_connecting ||
this->state == iiucs_connected );
+7 -8
View File
@@ -62,7 +62,7 @@ class dbChannelIO;
class dbPutNotifyBlocker;
class dbSubscriptionIO;
class dbBaseIO // X aCC 655
class dbBaseIO
: public chronIntIdRes < dbBaseIO > {
public:
virtual dbSubscriptionIO * isSubscription () = 0;
@@ -86,9 +86,9 @@ public:
epicsGuard < epicsMutex > &, epicsMutex &,
dbContext &, dbChannelIO &, struct dbAddr &, cacStateNotify &,
unsigned type, unsigned long count, unsigned mask, dbEventCtx );
void destructor ( epicsGuard < epicsMutex > & );
void unsubscribe ( epicsGuard < epicsMutex > & );
void channelDeleteException ( epicsGuard < epicsMutex > & );
void destructor ( CallbackGuard &, epicsGuard < epicsMutex > & );
void unsubscribe ( CallbackGuard &, epicsGuard < epicsMutex > & );
void channelDeleteException ( CallbackGuard &, epicsGuard < epicsMutex > & );
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
void show ( unsigned level ) const;
void * operator new ( size_t size,
@@ -110,7 +110,6 @@ private:
dbSubscriptionIO ( const dbSubscriptionIO & );
dbSubscriptionIO & operator = ( const dbSubscriptionIO & );
virtual ~dbSubscriptionIO ();
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -165,7 +164,7 @@ public:
dbContext ( epicsMutex & cbMutex, epicsMutex & mutex,
cacContextNotify & notify );
virtual ~dbContext ();
void destroyChannel ( epicsGuard < epicsMutex > &, dbChannelIO & );
void destroyChannel ( CallbackGuard &,epicsGuard < epicsMutex > &, dbChannelIO & );
void callReadNotify ( epicsGuard < epicsMutex > &,
struct dbAddr & addr, unsigned type, unsigned long count,
cacReadNotify & notify );
@@ -182,9 +181,9 @@ public:
cacWriteNotify & notify, cacChannel::ioid * pId );
void show ( unsigned level ) const;
void showAllIO ( const dbChannelIO & chan, unsigned level ) const;
void destroyAllIO (
void destroyAllIO ( CallbackGuard & cbGuard,
epicsGuard < epicsMutex > &, dbChannelIO & chan );
void ioCancel ( epicsGuard < epicsMutex > &,
void ioCancel ( CallbackGuard &, epicsGuard < epicsMutex > &,
dbChannelIO & chan, const cacChannel::ioid &id );
void ioShow ( epicsGuard < epicsMutex > &,
const cacChannel::ioid & id, unsigned level ) const;
+8 -12
View File
@@ -61,19 +61,21 @@ dbChannelIO::~dbChannelIO ()
{
}
void dbChannelIO::destructor ( epicsGuard < epicsMutex > & guard )
void dbChannelIO::destructor ( CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
this->serviceIO.destroyAllIO ( guard, *this );
this->serviceIO.destroyAllIO ( cbGuard, guard, *this );
this->~dbChannelIO ();
}
void dbChannelIO::destroy (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
this->serviceIO.destroyChannel ( guard, *this );
// dont access this pointer after above call because
this->serviceIO.destroyChannel ( cbGuard, guard, *this );
// don't access this pointer after above call because
// object nolonger exists
}
@@ -132,11 +134,12 @@ void dbChannelIO::subscribe (
}
void dbChannelIO::ioCancel (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const ioid & id )
{
mutualExclusionGuard.assertIdenticalMutex ( this->mutex );
this->serviceIO.ioCancel ( mutualExclusionGuard, *this, id );
this->serviceIO.ioCancel ( cbGuard, mutualExclusionGuard, *this, id );
}
void dbChannelIO::ioShow (
@@ -204,13 +207,6 @@ void * dbChannelIO::operator new ( size_t size,
return freeList.allocate ( size );
}
void * dbChannelIO::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
#ifdef CXX_PLACEMENT_DELETE
void dbChannelIO::operator delete ( void *pCadaver,
tsFreeList < dbChannelIO, 256, epicsMutexNOOP > & freeList )
+4 -2
View File
@@ -48,8 +48,10 @@ public:
epicsMutex &, cacChannelNotify &,
const dbAddr &, dbContext & );
void destructor (
CallbackGuard &,
epicsGuard < epicsMutex > & );
void destroy (
CallbackGuard &,
epicsGuard < epicsMutex > & mutualExclusionGuard );
void callReadNotify (
epicsGuard < epicsMutex > &,
@@ -100,7 +102,8 @@ private:
unsigned type, unsigned long count,
unsigned mask, cacStateNotify &notify, ioid * );
void ioCancel (
epicsGuard < epicsMutex > & mutualExclusionGuard,
CallbackGuard &,
epicsGuard < epicsMutex > &,
const ioid & );
void ioShow (
epicsGuard < epicsMutex > &,
@@ -111,7 +114,6 @@ private:
epicsGuard < epicsMutex > & ) const;
dbChannelIO ( const dbChannelIO & );
dbChannelIO & operator = ( const dbChannelIO & );
void * operator new ( size_t size );
void operator delete ( void * );
};
+19 -15
View File
@@ -83,7 +83,7 @@ dbContext::~dbContext ()
}
}
cacChannel & dbContext::createChannel ( // X aCC 361
cacChannel & dbContext::createChannel (
epicsGuard < epicsMutex > & guard, const char * pName,
cacChannelNotify & notifyIn, cacChannel::priLev priority )
{
@@ -119,18 +119,20 @@ cacChannel & dbContext::createChannel ( // X aCC 361
}
void dbContext::destroyChannel (
epicsGuard < epicsMutex > & guard, dbChannelIO & chan )
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard,
dbChannelIO & chan )
{
guard.assertIdenticalMutex ( this->mutex );
if ( chan.dbContextPrivateListOfIO::pBlocker ) {
this->ioTable.remove ( *chan.dbContextPrivateListOfIO::pBlocker );
chan.dbContextPrivateListOfIO::pBlocker->destructor ( guard );
chan.dbContextPrivateListOfIO::pBlocker->destructor ( cbGuard, guard );
this->dbPutNotifyBlockerFreeList.release ( chan.dbContextPrivateListOfIO::pBlocker );
chan.dbContextPrivateListOfIO::pBlocker = 0;
}
chan.destructor ( guard );
chan.destructor ( cbGuard, guard );
this->dbChannelIOFreeList.release ( & chan );
}
@@ -269,7 +271,9 @@ void dbContext::initiatePutNotify (
}
void dbContext::destroyAllIO (
epicsGuard < epicsMutex > & guard, dbChannelIO & chan )
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard,
dbChannelIO & chan )
{
guard.assertIdenticalMutex ( this->mutex );
dbSubscriptionIO * pIO;
@@ -286,24 +290,24 @@ void dbContext::destroyAllIO (
while ( ( pIO = tmp.get() ) ) {
// This prevents a db event callback from coming
// through after the notify IO is deleted
pIO->unsubscribe ( guard );
pIO->unsubscribe ( cbGuard, guard );
// If they call ioCancel() here it will be ignored
// because the IO has been unregistered above.
pIO->channelDeleteException ( guard );
pIO->destructor ( guard );
pIO->channelDeleteException ( cbGuard, guard );
pIO->destructor ( cbGuard, guard );
this->dbSubscriptionIOFreeList.release ( pIO );
}
if ( chan.dbContextPrivateListOfIO::pBlocker ) {
chan.dbContextPrivateListOfIO::pBlocker->destructor ( guard );
chan.dbContextPrivateListOfIO::pBlocker->destructor ( cbGuard, guard );
this->dbPutNotifyBlockerFreeList.release ( chan.dbContextPrivateListOfIO::pBlocker );
chan.dbContextPrivateListOfIO::pBlocker = 0;
}
}
void dbContext::ioCancel (
epicsGuard < epicsMutex > & guard, dbChannelIO & chan,
const cacChannel::ioid &id )
CallbackGuard & cbGuard, epicsGuard < epicsMutex > & guard,
dbChannelIO & chan, const cacChannel::ioid &id )
{
guard.assertIdenticalMutex ( this->mutex );
dbBaseIO * pIO = this->ioTable.remove ( id );
@@ -311,13 +315,13 @@ void dbContext::ioCancel (
dbSubscriptionIO *pSIO = pIO->isSubscription ();
if ( pSIO ) {
chan.dbContextPrivateListOfIO::eventq.remove ( *pSIO );
pSIO->unsubscribe ( guard );
pSIO->channelDeleteException ( guard );
pSIO->destructor ( guard );
pSIO->unsubscribe ( cbGuard, guard );
pSIO->channelDeleteException ( cbGuard, guard );
pSIO->destructor ( cbGuard, guard );
this->dbSubscriptionIOFreeList.release ( pSIO );
}
else if ( pIO == chan.dbContextPrivateListOfIO::pBlocker ) {
chan.dbContextPrivateListOfIO::pBlocker->cancel ( guard );
chan.dbContextPrivateListOfIO::pBlocker->cancel ( cbGuard, guard );
}
else {
errlogPrintf ( "dbContext::ioCancel() unrecognized IO was probably leaked or not canceled\n" );
+4 -9
View File
@@ -59,10 +59,11 @@ dbPutNotifyBlocker::~dbPutNotifyBlocker ()
{
}
void dbPutNotifyBlocker::destructor ( epicsGuard < epicsMutex > & guard )
void dbPutNotifyBlocker::destructor ( CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
this->cancel ( guard );
this->cancel ( cbGuard, guard );
if ( this->maxValueSize > sizeof ( this->dbrScalarValue ) ) {
char * pBuf = static_cast < char * > ( this->pn.pbuffer );
delete [] pBuf;
@@ -71,6 +72,7 @@ void dbPutNotifyBlocker::destructor ( epicsGuard < epicsMutex > & guard )
}
void dbPutNotifyBlocker::cancel (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -212,13 +214,6 @@ void * dbPutNotifyBlocker::operator new ( size_t size,
return freeList.allocate ( size );
}
void * dbPutNotifyBlocker::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
#ifdef CXX_PLACEMENT_DELETE
void dbPutNotifyBlocker::operator delete ( void *pCadaver,
tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP > & freeList )
+2 -3
View File
@@ -42,11 +42,11 @@
class dbPutNotifyBlocker : public dbBaseIO {
public:
dbPutNotifyBlocker ( epicsMutex & );
void destructor ( epicsGuard < epicsMutex > & );
void destructor ( CallbackGuard &, epicsGuard < epicsMutex > & );
void initiatePutNotify ( epicsGuard < epicsMutex > &,
cacWriteNotify &, struct dbAddr &,
unsigned type, unsigned long count, const void * pValue );
void cancel ( epicsGuard < epicsMutex > & );
void cancel ( CallbackGuard &, epicsGuard < epicsMutex > & );
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
void show ( unsigned level ) const;
void * operator new ( size_t size,
@@ -82,7 +82,6 @@ private:
dbPutNotifyBlocker ( const dbPutNotifyBlocker & );
dbPutNotifyBlocker & operator = ( const dbPutNotifyBlocker & );
virtual ~dbPutNotifyBlocker ();
void * operator new ( size_t size );
void operator delete ( void * );
};
+4 -9
View File
@@ -66,13 +66,14 @@ dbSubscriptionIO::~dbSubscriptionIO ()
{
}
void dbSubscriptionIO::destructor ( epicsGuard < epicsMutex > & guard )
void dbSubscriptionIO::destructor ( CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
this->~dbSubscriptionIO ();
}
void dbSubscriptionIO::unsubscribe (
void dbSubscriptionIO::unsubscribe ( CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -87,6 +88,7 @@ void dbSubscriptionIO::unsubscribe (
}
void dbSubscriptionIO::channelDeleteException (
CallbackGuard &,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -94,13 +96,6 @@ void dbSubscriptionIO::channelDeleteException (
this->chan.pName(guard), this->type, this->count );
}
void * dbSubscriptionIO::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void dbSubscriptionIO::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if