From 8ba3da20af42634a3c52ff547cf90c54f3921166 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Fri, 9 Feb 2001 17:41:23 +0000 Subject: [PATCH] improved interface to CAC --- src/db/dbCAC.h | 53 ++++++++++++++++++----------------- src/db/dbChannelIO.cpp | 33 +++++++++++++--------- src/db/dbChannelIOIL.h | 2 +- src/db/dbPutNotifyBlocker.cpp | 4 +++ src/db/dbPutNotifyIO.cpp | 17 +++++++---- src/db/dbServiceIO.cpp | 21 ++++++++------ src/db/dbSubscriptionIO.cpp | 3 +- 7 files changed, 77 insertions(+), 56 deletions(-) diff --git a/src/db/dbCAC.h b/src/db/dbCAC.h index 5f52c0797..aa3c4f2ac 100644 --- a/src/db/dbCAC.h +++ b/src/db/dbCAC.h @@ -33,19 +33,20 @@ class dbPutNotifyBlocker; class dbPutNotifyIO : public cacNotifyIO { public: - dbPutNotifyIO ( cacNotify ¬ify, dbPutNotifyBlocker &blocker ); + dbPutNotifyIO ( cacNotify &, dbPutNotifyBlocker & ); int initiate ( struct dbAddr &addr, unsigned type, unsigned long count, const void *pValue); void completion (); void destroy (); + cacChannelIO & channelIO () const; void * operator new ( size_t size ); void operator delete ( void *pCadaver, size_t size ); +protected: + ~dbPutNotifyIO (); // must allocate out of pool private: putNotify pn; dbPutNotifyBlocker &blocker; static tsFreeList < dbPutNotifyIO > freeList; - ~dbPutNotifyIO (); // must allocate out of pool - void uninstall (); }; extern "C" void dbSubscriptionEventCallback ( void *pPrivate, struct dbAddr *paddr, @@ -57,16 +58,17 @@ public: int begin ( struct dbAddr &addr, unsigned mask ); void destroy (); void show ( unsigned level ) const; + cacChannelIO & channelIO () const; void * operator new ( size_t size ); void operator delete ( void *pCadaver, size_t size ); +protected: + ~dbSubscriptionIO (); // must be allocated from pool private: dbChannelIO &chan; dbEventSubscription es; unsigned type; unsigned long count; static tsFreeList < dbSubscriptionIO > freeList; - ~dbSubscriptionIO (); // must be allocated from pool - void uninstall (); friend void dbSubscriptionEventCallback ( void *pPrivate, struct dbAddr *paddr, int eventsRemaining, struct db_field_log *pfl ); }; @@ -77,35 +79,38 @@ class dbPutNotifyBlocker { public: dbPutNotifyBlocker ( dbChannelIO &chanIn ); void destroy (); - int initiatePutNotify (cacNotify ¬ify, struct dbAddr &addr, - unsigned type, unsigned long count, const void *pValue); + int initiatePutNotify ( cacNotify ¬ify, struct dbAddr &addr, + unsigned type, unsigned long count, const void *pValue ); void putNotifyDestroyNotify (); + dbChannelIO & channel () const; void show ( unsigned level ) const; void * operator new ( size_t size ); void operator delete ( void *pCadaver, size_t size ); +protected: + ~dbPutNotifyBlocker (); // must allocate out of pool private: epicsEvent block; dbPutNotifyIO *pPN; dbChannelIO &chan; - - static tsFreeList < dbPutNotifyBlocker > freeList; - ~dbPutNotifyBlocker (); // must allocate out of pool void lock () const; void unlock () const; + static tsFreeList < dbPutNotifyBlocker > freeList; friend void putNotifyCompletion ( putNotify *ppn ); }; -class dbChannelIO : public cacLocalChannelIO { +class dbChannelIO : public cacChannelIO { public: - dbChannelIO ( cac &, cacChannel &chan, const dbAddr &addr, dbServiceIO &serviceIO ); + dbChannelIO ( cacChannelNotify ¬ify, + const dbAddr &addr, dbServiceIO &serviceIO ); void destroy (); void subscriptionUpdate ( unsigned type, unsigned long count, - const struct db_field_log *pfl, cacNotifyIO ¬ify ); + const struct db_field_log *pfl, dbSubscriptionIO ¬ify ); dbEventSubscription subscribe ( dbSubscriptionIO &subscr, unsigned mask ); void show ( unsigned level ) const; void * operator new ( size_t size); void operator delete ( void *pCadaver, size_t size ); - +protected: + ~dbChannelIO (); // allocate only from pool private: dbServiceIO &serviceIO; char *pGetCallbackCache; @@ -113,28 +118,24 @@ private: unsigned long getCallbackCacheSize; tsDLList < dbSubscriptionIO > eventq; dbAddr addr; - - static tsFreeList < dbChannelIO > freeList; - - ~dbChannelIO (); // allocate only from pool - const char *pName () const; + void initiateConnect (); int read ( unsigned type, unsigned long count, void *pValue ); int read ( unsigned type, unsigned long count, cacNotify & ); int write ( unsigned type, unsigned long count, const void *pvalue ); int write ( unsigned type, unsigned long count, const void *pvalue, cacNotify & ); - int subscribe ( unsigned type, unsigned long count, unsigned mask, cacNotify ¬ify ); + int subscribe ( unsigned type, unsigned long count, + unsigned mask, cacNotify ¬ify, cacNotifyIO *& ); short nativeType () const; unsigned long nativeElementCount () const; - void lock () const; void unlock () const; void lockOutstandingIO () const; void unlockOutstandingIO () const; - - friend dbSubscriptionIO::dbSubscriptionIO ( dbChannelIO &chanIO, cacNotify &, unsigned type, unsigned long count ); + static tsFreeList < dbChannelIO > freeList; + friend dbSubscriptionIO::dbSubscriptionIO ( dbChannelIO &chanIO, + cacNotify &, unsigned type, unsigned long count ); friend dbSubscriptionIO::~dbSubscriptionIO (); - friend void dbPutNotifyBlocker::lock () const; friend void dbPutNotifyBlocker::unlock () const; }; @@ -143,9 +144,9 @@ class dbServiceIO : public cacServiceIO { public: dbServiceIO (); virtual ~dbServiceIO (); - cacLocalChannelIO *createChannelIO ( const char *pName, cac &, cacChannel & ); + cacChannelIO *createChannelIO ( const char *pName, cac &, cacChannelNotify & ); void subscriptionUpdate ( struct dbAddr &addr, unsigned type, unsigned long count, - const struct db_field_log *pfl, cacNotifyIO ¬ify ); + const struct db_field_log *pfl, dbSubscriptionIO ¬ify ); dbEventSubscription subscribe ( struct dbAddr &addr, dbSubscriptionIO &subscr, unsigned mask ); void show ( unsigned level ) const; private: diff --git a/src/db/dbChannelIO.cpp b/src/db/dbChannelIO.cpp index 08a6d103e..a63714fc1 100644 --- a/src/db/dbChannelIO.cpp +++ b/src/db/dbChannelIO.cpp @@ -30,20 +30,21 @@ tsFreeList < dbChannelIO > dbChannelIO::freeList; -dbChannelIO::dbChannelIO ( cac &cacCtx, cacChannel &chan, const dbAddr &addrIn, dbServiceIO &serviceIO ) : - cacLocalChannelIO ( cacCtx, chan ), serviceIO ( serviceIO ), pGetCallbackCache ( 0 ), - pBlocker ( 0 ), getCallbackCacheSize ( 0ul ), addr ( addrIn ) +dbChannelIO::dbChannelIO ( cacChannelNotify ¬ify, + const dbAddr &addrIn, dbServiceIO &serviceIO ) : + cacChannelIO ( notify ), serviceIO ( serviceIO ), + pGetCallbackCache ( 0 ), pBlocker ( 0 ), + getCallbackCacheSize ( 0ul ), addr ( addrIn ) { - chan.attachIO ( *this ); - this->connectNotify (); +} + +void dbChannelIO::initiateConnect () +{ + this->notify ().connectNotify ( *this ); } dbChannelIO::~dbChannelIO () { - // this must go in the derived class's destructor because - // this calls virtual functions in the cacChannelIO base - this->ioReleaseNotify (); - this->lock (); /* @@ -111,13 +112,14 @@ int dbChannelIO::read ( unsigned type, unsigned long count, cacNotify ¬ify ) int status = db_get_field ( &this->addr, static_cast ( type ), this->pGetCallbackCache, static_cast ( count ), 0); if ( status ) { - notify.exceptionNotify ( ECA_GETFAIL, "db_get_field () completed unsuccessfuly" ); + notify.exceptionNotify ( *this, ECA_GETFAIL, + "db_get_field () completed unsuccessfuly" ); } else { - notify.completionNotify ( type, count, this->pGetCallbackCache ); + notify.completionNotify ( *this, type, count, this->pGetCallbackCache ); } this->unlock (); - notify.destroy (); + notify.release (); return ECA_NORMAL; } @@ -164,7 +166,7 @@ int dbChannelIO::write ( unsigned type, unsigned long count, } int dbChannelIO::subscribe ( unsigned type, unsigned long count, - unsigned mask, cacNotify ¬ify ) + unsigned mask, cacNotify ¬ify, cacNotifyIO *&pReturnIO ) { dbSubscriptionIO *pIO = new dbSubscriptionIO ( *this, notify, type, count ); if ( ! pIO ) { @@ -172,7 +174,10 @@ int dbChannelIO::subscribe ( unsigned type, unsigned long count, } int status = pIO->begin ( this->addr, mask ); - if ( status != ECA_NORMAL ) { + if ( status == ECA_NORMAL ) { + pReturnIO = pIO; + } + else { pIO->destroy (); } return status; diff --git a/src/db/dbChannelIOIL.h b/src/db/dbChannelIOIL.h index b1641c129..d646688df 100644 --- a/src/db/dbChannelIOIL.h +++ b/src/db/dbChannelIOIL.h @@ -53,7 +53,7 @@ inline short dbChannelIO::nativeType () const } inline void dbChannelIO::subscriptionUpdate ( unsigned type, unsigned long count, - const struct db_field_log *pfl, cacNotifyIO ¬ify ) + const struct db_field_log *pfl, dbSubscriptionIO ¬ify ) { this->serviceIO.subscriptionUpdate ( this->addr, type, count, pfl, notify ); } diff --git a/src/db/dbPutNotifyBlocker.cpp b/src/db/dbPutNotifyBlocker.cpp index 93246710e..0ef727652 100644 --- a/src/db/dbPutNotifyBlocker.cpp +++ b/src/db/dbPutNotifyBlocker.cpp @@ -59,6 +59,10 @@ void dbPutNotifyBlocker::putNotifyDestroyNotify () this->unlock (); } +dbChannelIO & dbPutNotifyBlocker::channel () const +{ + return this->chan; +} int dbPutNotifyBlocker::initiatePutNotify ( cacNotify ¬ify, struct dbAddr &addr, unsigned type, unsigned long count, diff --git a/src/db/dbPutNotifyIO.cpp b/src/db/dbPutNotifyIO.cpp index 43eb37d2c..6cd4f9a3d 100644 --- a/src/db/dbPutNotifyIO.cpp +++ b/src/db/dbPutNotifyIO.cpp @@ -51,8 +51,9 @@ dbPutNotifyIO::~dbPutNotifyIO () this->blocker.putNotifyDestroyNotify (); } -void dbPutNotifyIO::uninstall () +cacChannelIO & dbPutNotifyIO::channelIO () const { + return this->blocker.channel (); } int dbPutNotifyIO::initiate ( struct dbAddr &addr, unsigned type, @@ -69,7 +70,8 @@ int dbPutNotifyIO::initiate ( struct dbAddr &addr, unsigned type, this->pn.pbuffer = const_cast ( pValue ); this->pn.nRequest = static_cast ( count ); this->pn.paddr = &addr; - status = this->pn.dbrType = dbPutNotifyMapType ( &this->pn, static_cast ( type ) ); + status = this->pn.dbrType = dbPutNotifyMapType ( + &this->pn, static_cast ( type ) ); if (status) { this->pn.paddr = 0; return ECA_BADTYPE; @@ -79,7 +81,8 @@ int dbPutNotifyIO::initiate ( struct dbAddr &addr, unsigned type, if ( status && status != S_db_Pending ) { this->pn.paddr = 0; this->pn.status = status; - this->cacNotifyIO::exceptionNotify ( ECA_PUTFAIL, "dbPutNotify() returned failure"); + this->notify ().exceptionNotify ( this->blocker.channel (), + ECA_PUTFAIL, "dbPutNotify() returned failure" ); } return ECA_NORMAL; } @@ -92,14 +95,16 @@ void dbPutNotifyIO::completion () this->pn.paddr = 0; if ( this->pn.status ) { if ( this->pn.status == S_db_Blocked ) { - this->cacNotifyIO::exceptionNotify ( ECA_PUTCBINPROG, "put notify blocked" ); + this->notify ().exceptionNotify ( this->blocker.channel (), + ECA_PUTCBINPROG, "put notify blocked" ); } else { - this->cacNotifyIO::exceptionNotify ( ECA_PUTFAIL, "put notify unsuccessful"); + this->notify ().exceptionNotify ( this->blocker.channel (), + ECA_PUTFAIL, "put notify unsuccessful"); } } else { - this->cacNotifyIO::completionNotify (); + this->notify ().completionNotify ( this->blocker.channel () ); } } diff --git a/src/db/dbServiceIO.cpp b/src/db/dbServiceIO.cpp index 17210187a..6c43b7d09 100644 --- a/src/db/dbServiceIO.cpp +++ b/src/db/dbServiceIO.cpp @@ -61,21 +61,23 @@ dbServiceIO::~dbServiceIO () } } -cacLocalChannelIO *dbServiceIO::createChannelIO ( const char *pName, cac &cacCtx, cacChannel &chan ) +cacChannelIO *dbServiceIO::createChannelIO ( + const char *pName, cac &cacCtx, cacChannelNotify ¬ify ) { struct dbAddr addr; int status = db_name_to_addr ( pName, &addr ); - if (status) { + if ( status ) { return 0; } else { - return new dbChannelIO ( cacCtx, chan, addr, *this ); + return new dbChannelIO ( notify, addr, *this ); } } -void dbServiceIO::subscriptionUpdate ( struct dbAddr &addr, unsigned type, unsigned long count, - const struct db_field_log *pfl, cacNotifyIO ¬ify ) +void dbServiceIO::subscriptionUpdate ( struct dbAddr &addr, + unsigned type, unsigned long count, + const struct db_field_log *pfl, dbSubscriptionIO &io ) { unsigned long size = dbr_size_n ( type, count ); @@ -88,7 +90,8 @@ void dbServiceIO::subscriptionUpdate ( struct dbAddr &addr, unsigned type, unsig if ( ! this->pEventCallbackCache ) { this->eventCallbackCacheSize = 0ul; this->mutex.unlock (); - notify.exceptionNotify ( ECA_ALLOCMEM, "unable to allocate callback cache" ); + io.notify ().exceptionNotify ( io.channelIO (), ECA_ALLOCMEM, + "unable to allocate callback cache" ); return; } this->eventCallbackCacheSize = size; @@ -97,10 +100,12 @@ void dbServiceIO::subscriptionUpdate ( struct dbAddr &addr, unsigned type, unsig int status = db_get_field ( &addr, static_cast ( type ), this->pEventCallbackCache, static_cast ( count ), pvfl ); if ( status ) { - notify.exceptionNotify ( ECA_GETFAIL, "subscription update db_get_field () completed unsuccessfuly" ); + io.notify ().exceptionNotify ( io.channelIO (), ECA_GETFAIL, + "subscription update db_get_field () completed unsuccessfuly" ); } else { - notify.completionNotify ( type, count, this->pEventCallbackCache ); + io.notify ().completionNotify ( io.channelIO (), type, + count, this->pEventCallbackCache ); } this->mutex.unlock (); } diff --git a/src/db/dbSubscriptionIO.cpp b/src/db/dbSubscriptionIO.cpp index 69c76e4ef..c05c04869 100644 --- a/src/db/dbSubscriptionIO.cpp +++ b/src/db/dbSubscriptionIO.cpp @@ -55,8 +55,9 @@ void dbSubscriptionIO::destroy () delete this; } -void dbSubscriptionIO::uninstall () +cacChannelIO & dbSubscriptionIO::channelIO () const { + return this->chan; } void * dbSubscriptionIO::operator new ( size_t size )