improved interface to CAC

This commit is contained in:
Jeff Hill
2001-02-09 17:41:23 +00:00
parent 7bc172f355
commit 8ba3da20af
7 changed files with 77 additions and 56 deletions
+27 -26
View File
@@ -33,19 +33,20 @@ class dbPutNotifyBlocker;
class dbPutNotifyIO : public cacNotifyIO {
public:
dbPutNotifyIO ( cacNotify &notify, 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 &notify, struct dbAddr &addr,
unsigned type, unsigned long count, const void *pValue);
int initiatePutNotify ( cacNotify &notify, 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 &notify,
const dbAddr &addr, dbServiceIO &serviceIO );
void destroy ();
void subscriptionUpdate ( unsigned type, unsigned long count,
const struct db_field_log *pfl, cacNotifyIO &notify );
const struct db_field_log *pfl, dbSubscriptionIO &notify );
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 &notify );
int subscribe ( unsigned type, unsigned long count,
unsigned mask, cacNotify &notify, 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 &notify );
const struct db_field_log *pfl, dbSubscriptionIO &notify );
dbEventSubscription subscribe ( struct dbAddr &addr, dbSubscriptionIO &subscr, unsigned mask );
void show ( unsigned level ) const;
private:
+19 -14
View File
@@ -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 &notify,
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 &notify )
int status = db_get_field ( &this->addr, static_cast <int> ( type ),
this->pGetCallbackCache, static_cast <int> ( 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 &notify )
unsigned mask, cacNotify &notify, 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;
+1 -1
View File
@@ -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 &notify )
const struct db_field_log *pfl, dbSubscriptionIO &notify )
{
this->serviceIO.subscriptionUpdate ( this->addr, type, count, pfl, notify );
}
+4
View File
@@ -59,6 +59,10 @@ void dbPutNotifyBlocker::putNotifyDestroyNotify ()
this->unlock ();
}
dbChannelIO & dbPutNotifyBlocker::channel () const
{
return this->chan;
}
int dbPutNotifyBlocker::initiatePutNotify ( cacNotify &notify,
struct dbAddr &addr, unsigned type, unsigned long count,
+11 -6
View File
@@ -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 <void *> ( pValue );
this->pn.nRequest = static_cast <unsigned> ( count );
this->pn.paddr = &addr;
status = this->pn.dbrType = dbPutNotifyMapType ( &this->pn, static_cast <short> ( type ) );
status = this->pn.dbrType = dbPutNotifyMapType (
&this->pn, static_cast <short> ( 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 () );
}
}
+13 -8
View File
@@ -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 &notify )
{
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 &notify )
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 <int> ( type ),
this->pEventCallbackCache, static_cast <int> ( 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 ();
}
+2 -1
View File
@@ -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 )