improved interface to CAC
This commit is contained in:
+27
-26
@@ -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:
|
||||
|
||||
+19
-14
@@ -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 <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 ¬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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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 <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 ();
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
|
||||
Reference in New Issue
Block a user