redesigned class hierarchy
This commit is contained in:
@@ -49,7 +49,7 @@ CASG::~CASG ()
|
||||
this->mutex.lock ();
|
||||
tsDLIterBD <syncGroupNotify> notify ( this->ioList.first () );
|
||||
while ( notify.valid () ) {
|
||||
notify->destroy ();
|
||||
notify->release ();
|
||||
notify = this->ioList.first ();
|
||||
}
|
||||
this->mutex.unlock ();
|
||||
@@ -85,12 +85,12 @@ int CASG::block ( double timeout )
|
||||
/*
|
||||
* dont allow recursion
|
||||
*/
|
||||
void *p = epicsThreadPrivateGet (cacRecursionLock);
|
||||
void *p = epicsThreadPrivateGet ( cacRecursionLock );
|
||||
if ( p ) {
|
||||
return ECA_EVDISALLOW;
|
||||
}
|
||||
|
||||
epicsThreadPrivateSet (cacRecursionLock, &cacRecursionLock);
|
||||
epicsThreadPrivateSet ( cacRecursionLock, &cacRecursionLock );
|
||||
|
||||
cur_time = epicsTime::getCurrent ();
|
||||
|
||||
@@ -189,7 +189,11 @@ int CASG::put (chid pChan, unsigned type, unsigned long count, const void *pValu
|
||||
if ( ! pNotify ) {
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
return pChan->write ( type, count, pValue, *pNotify );
|
||||
int status = pChan->write ( type, count, pValue, *pNotify );
|
||||
if ( status != ECA_NORMAL ) {
|
||||
pNotify->release ();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int CASG::get (chid pChan, unsigned type, unsigned long count, void *pValue)
|
||||
@@ -198,6 +202,10 @@ int CASG::get (chid pChan, unsigned type, unsigned long count, void *pValue)
|
||||
if ( ! pNotify ) {
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
return pChan->read ( type, count, *pNotify );
|
||||
int status = pChan->read ( type, count, *pNotify );
|
||||
if ( status != ECA_NORMAL ) {
|
||||
pNotify->release ();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ INC += db_access.h
|
||||
INC += addrList.h
|
||||
INC += cacIO.h
|
||||
|
||||
LIBSRCS += cacChannel.cpp
|
||||
LIBSRCS += cacChannelIO.cpp
|
||||
LIBSRCS += cacChannelNotify.cpp
|
||||
LIBSRCS += cacNotify.cpp
|
||||
LIBSRCS += cacNotifyIO.cpp
|
||||
LIBSRCS += cacServiceList.cpp
|
||||
@@ -40,7 +40,7 @@ LIBSRCS += cac.cpp
|
||||
LIBSRCS += tcpSendWatchdog.cpp
|
||||
LIBSRCS += tcpRecvWatchdog.cpp
|
||||
LIBSRCS += bhe.cpp
|
||||
LIBSRCS += oldChannel.cpp
|
||||
LIBSRCS += oldChannelNotify.cpp
|
||||
LIBSRCS += oldSubscription.cpp
|
||||
LIBSRCS += getCallback.cpp
|
||||
LIBSRCS += putCallback.cpp
|
||||
@@ -79,6 +79,7 @@ caRepeater_SRCS = caRepeater.cpp
|
||||
PROD += caRepeater
|
||||
|
||||
PROD_DEFAULT += catime acctst caConnTest casw caEventRate
|
||||
OBJS_IOC += catime acctst caConnTest casw caEventRate
|
||||
catime_SRCS = catimeMain.c catime.c
|
||||
acctst_SRCS = acctstMain.c acctst.c
|
||||
caEventRate_SRCS = caEventRateMain.cpp caEventRate.cpp
|
||||
|
||||
@@ -15,47 +15,8 @@
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
cacChannelIO::cacChannelIO ( cacChannel &chanIn ) :
|
||||
chan ( chanIn )
|
||||
{
|
||||
}
|
||||
|
||||
cacChannelIO::~cacChannelIO ()
|
||||
{
|
||||
this->chan.pChannelIO = 0;
|
||||
}
|
||||
|
||||
cacLocalChannelIO::cacLocalChannelIO ( cac &cacCtxIn, cacChannel &chan ) :
|
||||
cacChannelIO ( chan ), cacCtx ( cacCtxIn ) {};
|
||||
|
||||
cacLocalChannelIO::~cacLocalChannelIO ()
|
||||
{
|
||||
this->cacCtx.uninstallLocalChannel ( *this );
|
||||
}
|
||||
|
||||
void cacChannelIO::connectNotify ()
|
||||
{
|
||||
this->chan.connectNotify ();
|
||||
}
|
||||
|
||||
void cacChannelIO::disconnectNotify ()
|
||||
{
|
||||
this->chan.disconnectNotify ();
|
||||
}
|
||||
|
||||
void cacChannelIO::connectTimeoutNotify ()
|
||||
{
|
||||
this->chan.connectTimeoutNotify ();
|
||||
}
|
||||
|
||||
void cacChannelIO::accessRightsNotify ( caar ar )
|
||||
{
|
||||
this->chan.accessRightsNotify ( ar );
|
||||
}
|
||||
|
||||
void cacChannelIO::ioReleaseNotify ()
|
||||
{
|
||||
this->chan.ioReleaseNotify ();
|
||||
}
|
||||
|
||||
channel_state cacChannelIO::state () const
|
||||
@@ -71,6 +32,10 @@ caar cacChannelIO::accessRights () const
|
||||
return ar;
|
||||
}
|
||||
|
||||
void cacChannelIO::notifyStateChangeFirstConnectInCountOfOutstandingIO ()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned cacChannelIO::searchAttempts () const
|
||||
{
|
||||
return 0u;
|
||||
@@ -91,15 +56,10 @@ bool cacChannelIO::connected () const
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned cacChannelIO::readSequence () const
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
void cacChannelIO::hostName ( char *pBuf, unsigned bufLength ) const
|
||||
{
|
||||
if ( bufLength ) {
|
||||
localHostNameAtLoadTime.copy (pBuf, bufLength );
|
||||
localHostNameAtLoadTime.copy ( pBuf, bufLength );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,20 +69,4 @@ const char * cacChannelIO::pHostName () const
|
||||
return localHostNameAtLoadTime.pointer ();
|
||||
}
|
||||
|
||||
void cacChannelIO::incrementOutstandingIO ()
|
||||
{
|
||||
}
|
||||
|
||||
void cacChannelIO::decrementOutstandingIO ()
|
||||
{
|
||||
}
|
||||
|
||||
void cacChannelIO::lockOutstandingIO () const
|
||||
{
|
||||
}
|
||||
|
||||
void cacChannelIO::unlockOutstandingIO () const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
219
src/ca/cacIO.h
219
src/ca/cacIO.h
@@ -15,147 +15,105 @@
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
//
|
||||
// Notes
|
||||
// 1) these routines should be changed to throw exceptions and not return
|
||||
// ECA_XXXX style status in the future.
|
||||
//
|
||||
|
||||
#include "tsDLList.h"
|
||||
#include "epicsMutex.h"
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
class cacNotifyIO;
|
||||
class cac;
|
||||
struct cacChannelIO;
|
||||
struct cacNotifyIO;
|
||||
|
||||
class epicsShareClass cacNotify {
|
||||
class cacNotify {
|
||||
public:
|
||||
cacNotify ();
|
||||
virtual ~cacNotify () = 0;
|
||||
virtual void destroy () = 0;
|
||||
virtual void completionNotify ();
|
||||
virtual void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
virtual void exceptionNotify ( int status, const char *pContext );
|
||||
virtual void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
private:
|
||||
cacNotifyIO *pIO;
|
||||
friend class cacNotifyIO;
|
||||
};
|
||||
|
||||
class epicsShareClass cacNotifyIO {
|
||||
public:
|
||||
cacNotifyIO ( cacNotify & );
|
||||
virtual ~cacNotifyIO () = 0;
|
||||
virtual void uninstall () = 0;
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
private:
|
||||
cacNotify ¬ify;
|
||||
friend class cacNotify;
|
||||
};
|
||||
|
||||
class epicsShareClass cacChannel {
|
||||
public:
|
||||
cacChannel ();
|
||||
virtual ~cacChannel () = 0;
|
||||
virtual void destroy () = 0;
|
||||
|
||||
void attachIO ( class cacChannelIO &io );
|
||||
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 ¬ify );
|
||||
int subscribe ( unsigned type, unsigned long count, unsigned mask, cacNotify ¬ify );
|
||||
void hostName ( char *pBuf, unsigned bufLength ) const;
|
||||
short nativeType () const;
|
||||
unsigned long nativeElementCount () const;
|
||||
channel_state state () const;
|
||||
bool readAccess () const;
|
||||
bool writeAccess () const;
|
||||
const char *pName () const;
|
||||
unsigned searchAttempts () const;
|
||||
double beaconPeriod () const;
|
||||
bool ca_v42_ok () const;
|
||||
bool connected () const;
|
||||
caar accessRights () const;
|
||||
unsigned readSequence () const;
|
||||
void incrementOutstandingIO ();
|
||||
void decrementOutstandingIO ();
|
||||
void decrementOutstandingIO ( unsigned seqNumber );
|
||||
|
||||
const char * pHostName () const; // deprecated - please do not use
|
||||
|
||||
epicsShareFunc virtual void release () = 0;
|
||||
epicsShareFunc virtual void completionNotify ( cacChannelIO & );
|
||||
epicsShareFunc virtual void completionNotify ( cacChannelIO &, unsigned type,
|
||||
unsigned long count, const void *pData );
|
||||
epicsShareFunc virtual void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext );
|
||||
epicsShareFunc virtual void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext, unsigned type, unsigned long count );
|
||||
protected:
|
||||
class cacChannelIO *pChannelIO;
|
||||
|
||||
void lockOutstandingIO () const;
|
||||
void unlockOutstandingIO () const;
|
||||
|
||||
private:
|
||||
virtual void ioAttachNotify ();
|
||||
virtual void ioReleaseNotify ();
|
||||
virtual void connectNotify ();
|
||||
virtual void disconnectNotify ();
|
||||
virtual void accessRightsNotify ( caar );
|
||||
virtual void exceptionNotify ( int status, const char *pContext );
|
||||
virtual void connectTimeoutNotify ();
|
||||
|
||||
friend class cacChannelIO;
|
||||
epicsShareFunc virtual ~cacNotify () = 0;
|
||||
};
|
||||
|
||||
class epicsShareClass cacChannelIO {
|
||||
struct cacNotifyIO {
|
||||
public:
|
||||
cacChannelIO ( cacChannel &chan );
|
||||
virtual ~cacChannelIO () = 0;
|
||||
virtual void destroy () = 0;
|
||||
|
||||
void connectNotify ();
|
||||
void disconnectNotify ();
|
||||
void connectTimeoutNotify ();
|
||||
void accessRightsNotify ( caar );
|
||||
void ioReleaseNotify ();
|
||||
|
||||
virtual const char *pName () const = 0;
|
||||
|
||||
virtual void lockOutstandingIO () const = 0;
|
||||
virtual void unlockOutstandingIO () const = 0;
|
||||
|
||||
virtual void show ( unsigned level ) const = 0;
|
||||
|
||||
epicsShareFunc cacNotifyIO ( cacNotify & );
|
||||
epicsShareFunc cacNotify & notify () const;
|
||||
epicsShareFunc virtual void destroy () = 0; // also uninstalls
|
||||
epicsShareFunc virtual cacChannelIO & channelIO () const = 0;
|
||||
protected:
|
||||
epicsShareFunc virtual ~cacNotifyIO () = 0;
|
||||
private:
|
||||
virtual int read ( unsigned type, unsigned long count, void *pValue) = 0;
|
||||
virtual int read ( unsigned type, unsigned long count, cacNotify ¬ify ) = 0;
|
||||
virtual int write ( unsigned type, unsigned long count, const void *pValue ) = 0;
|
||||
virtual int write ( unsigned type, unsigned long count, const void *pValue, cacNotify ¬ify ) = 0;
|
||||
virtual int subscribe ( unsigned type, unsigned long count, unsigned mask, cacNotify ¬ify ) = 0;
|
||||
virtual short nativeType () const = 0;
|
||||
virtual unsigned long nativeElementCount () const = 0;
|
||||
virtual void hostName (char *pBuf, unsigned bufLength) const; // defaults to local host name
|
||||
virtual channel_state state () const; // defaults to always connected
|
||||
virtual caar accessRights () const; // defaults to unrestricted access
|
||||
virtual unsigned searchAttempts () const; // defaults to zero
|
||||
virtual double beaconPeriod () const; // defaults to negative DBL_MAX
|
||||
virtual bool ca_v42_ok () const; // defaults to true
|
||||
virtual bool connected () const; // defaults to true
|
||||
virtual unsigned readSequence () const; // defaults to always zero
|
||||
virtual void incrementOutstandingIO ();
|
||||
virtual void decrementOutstandingIO ();
|
||||
virtual const char * pHostName () const; // deprecated - please do not use
|
||||
|
||||
cacChannel &chan;
|
||||
|
||||
friend class cacChannel;
|
||||
cacNotify &callback;
|
||||
};
|
||||
|
||||
class cacLocalChannelIO :
|
||||
public cacChannelIO, public tsDLNode < cacLocalChannelIO > {
|
||||
class cacChannelNotify {
|
||||
public:
|
||||
epicsShareFunc cacLocalChannelIO ( cac&, cacChannel &chan );
|
||||
epicsShareFunc virtual ~cacLocalChannelIO ();
|
||||
private:
|
||||
cac &cacCtx;
|
||||
epicsShareFunc virtual void release () = 0;
|
||||
epicsShareFunc virtual void connectNotify ( cacChannelIO & );
|
||||
epicsShareFunc virtual void disconnectNotify ( cacChannelIO & );
|
||||
epicsShareFunc virtual void accessRightsNotify ( cacChannelIO &, const caar & );
|
||||
epicsShareFunc virtual void exceptionNotify ( cacChannelIO &, int status, const char *pContext );
|
||||
|
||||
// not for public consumption
|
||||
epicsShareFunc virtual bool includeFirstConnectInCountOfOutstandingIO () const;
|
||||
epicsShareFunc virtual class oldChannelNotify * pOldChannelNotify ();
|
||||
protected:
|
||||
epicsShareFunc virtual ~cacChannelNotify () = 0;
|
||||
};
|
||||
|
||||
struct cacChannelIO {
|
||||
public:
|
||||
epicsShareFunc cacChannelIO ( cacChannelNotify &chan );
|
||||
epicsShareFunc cacChannelNotify & notify () const;
|
||||
|
||||
epicsShareFunc virtual void destroy () = 0;
|
||||
epicsShareFunc virtual const char *pName () const = 0;
|
||||
epicsShareFunc virtual void show ( unsigned level ) const = 0;
|
||||
epicsShareFunc virtual void initiateConnect () = 0;
|
||||
epicsShareFunc virtual int read ( unsigned type,
|
||||
unsigned long count, void *pValue) = 0;
|
||||
epicsShareFunc virtual int read ( unsigned type,
|
||||
unsigned long count, cacNotify ¬ify ) = 0;
|
||||
epicsShareFunc virtual int write ( unsigned type,
|
||||
unsigned long count, const void *pValue ) = 0;
|
||||
epicsShareFunc virtual int write ( unsigned type,
|
||||
unsigned long count, const void *pValue,
|
||||
cacNotify ¬ify ) = 0;
|
||||
epicsShareFunc virtual int subscribe ( unsigned type,
|
||||
unsigned long count, unsigned mask,
|
||||
cacNotify ¬ify, cacNotifyIO *& ) = 0;
|
||||
epicsShareFunc virtual short nativeType () const = 0;
|
||||
epicsShareFunc virtual unsigned long nativeElementCount () const = 0;
|
||||
epicsShareFunc virtual channel_state state () const; // defaults to always connected
|
||||
epicsShareFunc virtual caar accessRights () const; // defaults to unrestricted access
|
||||
epicsShareFunc virtual unsigned searchAttempts () const; // defaults to zero
|
||||
epicsShareFunc virtual double beaconPeriod () const; // defaults to negative DBL_MAX
|
||||
epicsShareFunc virtual bool ca_v42_ok () const; // defaults to true
|
||||
epicsShareFunc virtual bool connected () const; // defaults to true
|
||||
epicsShareFunc virtual void hostName (char *pBuf, unsigned bufLength) const; // defaults to local host name
|
||||
epicsShareFunc virtual const char * pHostName () const; // deprecated - please do not use
|
||||
epicsShareFunc virtual void notifyStateChangeFirstConnectInCountOfOutstandingIO ();
|
||||
protected:
|
||||
epicsShareFunc virtual ~cacChannelIO () = 0;
|
||||
private:
|
||||
cacChannelNotify &chan;
|
||||
};
|
||||
|
||||
class cac;
|
||||
|
||||
struct cacServiceIO : public tsDLNode < cacServiceIO > {
|
||||
public:
|
||||
epicsShareFunc virtual cacLocalChannelIO *createChannelIO ( const char *pName, cac &, cacChannel & ) = 0;
|
||||
epicsShareFunc virtual cacChannelIO *createChannelIO (
|
||||
const char *pName, cac &, cacChannelNotify & ) = 0;
|
||||
epicsShareFunc virtual void show ( unsigned level ) const = 0;
|
||||
private:
|
||||
};
|
||||
@@ -164,7 +122,8 @@ class cacServiceList : private epicsMutex {
|
||||
public:
|
||||
epicsShareFunc cacServiceList ();
|
||||
epicsShareFunc void registerService ( cacServiceIO &service );
|
||||
epicsShareFunc cacLocalChannelIO * createChannelIO ( const char *pName, cac &, cacChannel & );
|
||||
epicsShareFunc cacChannelIO * createChannelIO (
|
||||
const char *pName, cac &, cacChannelNotify & );
|
||||
epicsShareFunc void show ( unsigned level ) const;
|
||||
private:
|
||||
tsDLList < cacServiceIO > services;
|
||||
@@ -174,23 +133,21 @@ epicsShareExtern cacServiceList cacGlobalServiceList;
|
||||
|
||||
epicsShareFunc int epicsShareAPI ca_register_service ( struct cacServiceIO *pService );
|
||||
|
||||
inline void cacNotifyIO::completionNotify ()
|
||||
inline cacNotifyIO::cacNotifyIO ( cacNotify ¬ifyIn ) : callback ( notifyIn )
|
||||
{
|
||||
this->notify.completionNotify ();
|
||||
}
|
||||
|
||||
inline void cacNotifyIO::completionNotify ( unsigned type, unsigned long count, const void *pData )
|
||||
inline cacNotify & cacNotifyIO::notify () const
|
||||
{
|
||||
this->notify.completionNotify ( type, count, pData );
|
||||
return this->callback;
|
||||
}
|
||||
|
||||
inline void cacNotifyIO::exceptionNotify ( int status, const char *pContext )
|
||||
inline cacChannelIO::cacChannelIO ( cacChannelNotify &chanIn ) : chan ( chanIn )
|
||||
{
|
||||
this->notify.exceptionNotify ( status, pContext );
|
||||
}
|
||||
|
||||
inline void cacNotifyIO::exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count )
|
||||
inline cacChannelNotify & cacChannelIO::notify () const
|
||||
{
|
||||
this->notify.exceptionNotify ( status, pContext, type, count );
|
||||
return this->chan;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,40 +12,32 @@
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
cacNotify::cacNotify () : pIO (0)
|
||||
{
|
||||
}
|
||||
|
||||
cacNotify::~cacNotify ()
|
||||
{
|
||||
cacNotifyIO *pTmpIO = this->pIO;
|
||||
if ( pTmpIO ) {
|
||||
this->pIO = 0;
|
||||
// the code fits together better in iother places
|
||||
// if the delete and the uninstall are speparate steps
|
||||
pTmpIO->uninstall ();
|
||||
delete pTmpIO;
|
||||
}
|
||||
}
|
||||
|
||||
void cacNotify::completionNotify ()
|
||||
void cacNotify::completionNotify ( cacChannelIO &chan )
|
||||
{
|
||||
ca_printf ("CAC: IO completion with no handler installed?\n");
|
||||
ca_printf ( "CAC: IO completion for channel %s with no handler installed?\n",
|
||||
chan.pName () );
|
||||
}
|
||||
|
||||
void cacNotify::completionNotify ( unsigned type, unsigned long count, const void *pData )
|
||||
void cacNotify::completionNotify ( cacChannelIO &chan,
|
||||
unsigned type, unsigned long count, const void *pData )
|
||||
{
|
||||
ca_printf ("CAC: IO completion with no handler installed? type=%u count=%u data pointer=%p\n",
|
||||
type, count, pData);
|
||||
ca_printf ( "CAC: IO completion with no handler installed? channel=%s type=%u count=%u data pointer=%p\n",
|
||||
chan.pName (), type, count, pData );
|
||||
}
|
||||
|
||||
void cacNotify::exceptionNotify ( int status, const char *pContext )
|
||||
void cacNotify::exceptionNotify ( cacChannelIO &chan, int status, const char *pContext )
|
||||
{
|
||||
ca_signal (status, pContext);
|
||||
ca_signal_formated ( status, __FILE__, __LINE__, "%s channel=%s\n",
|
||||
pContext, chan.pName () );
|
||||
}
|
||||
|
||||
void cacNotify::exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count )
|
||||
void cacNotify::exceptionNotify ( cacChannelIO &chan, int status,
|
||||
const char *pContext, unsigned type, unsigned long count )
|
||||
{
|
||||
ca_signal_formated (status, __FILE__, __LINE__, "%s type=%d count=%ld\n",
|
||||
pContext, type, count);
|
||||
ca_signal_formated ( status, __FILE__, __LINE__, "%s channel=%s type=%d count=%ld\n",
|
||||
chan.pName (), pContext, type, count );
|
||||
}
|
||||
|
||||
@@ -12,17 +12,8 @@
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
cacNotifyIO::cacNotifyIO ( cacNotify ¬ifyIn ) : notify ( notifyIn )
|
||||
{
|
||||
assert ( ! this->notify.pIO );
|
||||
this->notify.pIO = this;
|
||||
}
|
||||
|
||||
cacNotifyIO::~cacNotifyIO ()
|
||||
{
|
||||
if ( this->notify.pIO == this ) {
|
||||
this->notify.pIO = 0;
|
||||
this->notify.destroy ();
|
||||
}
|
||||
this->callback.release ();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,13 @@ void cacServiceList::registerService ( cacServiceIO &service )
|
||||
this->unlock ();
|
||||
}
|
||||
|
||||
cacLocalChannelIO * cacServiceList::createChannelIO (const char *pName, cac &cacCtx, cacChannel &chan)
|
||||
cacChannelIO * cacServiceList::createChannelIO ( const char *pName,
|
||||
cac &cacCtx, cacChannelNotify &chan )
|
||||
{
|
||||
cacLocalChannelIO *pChanIO = 0;
|
||||
cacChannelIO *pChanIO = 0;
|
||||
|
||||
this->lock ();
|
||||
tsDLIterBD <cacServiceIO> iter ( this->services.first () );
|
||||
tsDLIterBD < cacServiceIO > iter ( this->services.first () );
|
||||
while ( iter.valid () ) {
|
||||
pChanIO = iter->createChannelIO ( pName, cacCtx, chan );
|
||||
if ( pChanIO ) {
|
||||
|
||||
@@ -47,10 +47,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct oldChannel *chid;
|
||||
typedef struct cacChannelIO *chid;
|
||||
typedef chid chanId; /* for when the structures field name is "chid" */
|
||||
typedef long chtype;
|
||||
typedef struct oldSubscription *evid;
|
||||
typedef struct cacNotifyIO *evid;
|
||||
typedef double ca_real;
|
||||
|
||||
/* Format for the arguments to user connection handlers */
|
||||
@@ -869,26 +869,6 @@ ca_sg_array_put (gid, type, 1u, chan, pValue)
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI ca_sg_stat (CA_SYNC_GID gid);
|
||||
|
||||
/*
|
||||
* ca_modify_user_name()
|
||||
*
|
||||
* Modify or override the default
|
||||
* client user name.
|
||||
*
|
||||
* pUserName R new user name string copied from this location
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI ca_modify_user_name ( const char *pUserName );
|
||||
|
||||
/*
|
||||
* CA_MODIFY_HOST_NAME()
|
||||
*
|
||||
* Modify or override the default
|
||||
* client host name.
|
||||
*
|
||||
* pHostName R new host name string copied from this location
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI ca_modify_host_name ( const char *pHostName );
|
||||
|
||||
/*
|
||||
* ca_v42_ok()
|
||||
*
|
||||
@@ -950,6 +930,11 @@ epicsShareFunc int epicsShareAPI ca_client_status (unsigned level);
|
||||
epicsShareFunc int epicsShareAPI ca_import (epicsThreadId tid);
|
||||
epicsShareFunc int epicsShareAPI ca_import_cancel (epicsThreadId tid);
|
||||
|
||||
/*
|
||||
* defunct
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI ca_modify_user_name ( const char *pUserName );
|
||||
epicsShareFunc int epicsShareAPI ca_modify_host_name ( const char *pHostName );
|
||||
|
||||
#else /* CAC_ANSI_FUNC_PROTO */
|
||||
epicsShareFunc short epicsShareAPI ca_get_field_type ();
|
||||
|
||||
@@ -20,61 +20,52 @@
|
||||
|
||||
tsFreeList < class getCallback, 1024 > getCallback::freeList;
|
||||
|
||||
getCallback::getCallback (oldChannel &chanIn, caEventCallBackFunc *pFuncIn, void *pPrivateIn) :
|
||||
chan (chanIn), pFunc (pFuncIn), pPrivate (pPrivateIn)
|
||||
{
|
||||
}
|
||||
|
||||
getCallback::~getCallback ()
|
||||
{
|
||||
}
|
||||
|
||||
void getCallback::destroy ()
|
||||
void getCallback::release ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void getCallback::completionNotify ()
|
||||
{
|
||||
cacNotify::completionNotify ();
|
||||
}
|
||||
|
||||
void getCallback::completionNotify ( unsigned type, unsigned long count, const void *pData )
|
||||
void getCallback::completionNotify ( cacChannelIO &io,
|
||||
unsigned type, unsigned long count, const void *pData )
|
||||
{
|
||||
struct event_handler_args args;
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = &this->chan;
|
||||
args.chid = & io;
|
||||
args.type = type;
|
||||
args.count = count;
|
||||
args.status = ECA_NORMAL;
|
||||
args.dbr = pData;
|
||||
(*this->pFunc) (args);
|
||||
( *this->pFunc ) ( args );
|
||||
}
|
||||
|
||||
void getCallback::exceptionNotify (int status, const char * /* pContext */)
|
||||
void getCallback::exceptionNotify ( cacChannelIO &io, int status,
|
||||
const char * /* pContext */)
|
||||
{
|
||||
struct event_handler_args args;
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = &this->chan;
|
||||
args.type = 0;
|
||||
args.chid = & io;
|
||||
args.type = TYPENOTCONN;
|
||||
args.count = 0;
|
||||
args.status = status;
|
||||
args.dbr = 0;
|
||||
(*this->pFunc) (args);
|
||||
( *this->pFunc ) ( args );
|
||||
}
|
||||
|
||||
void getCallback::exceptionNotify ( int status, const char *pContext,
|
||||
void getCallback::exceptionNotify ( cacChannelIO &io,
|
||||
int status, const char *pContext,
|
||||
unsigned type, unsigned long count )
|
||||
{
|
||||
cacNotify::exceptionNotify ( status, pContext, type, count);
|
||||
struct event_handler_args args;
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = & io;
|
||||
args.type = type;
|
||||
args.count = count;
|
||||
args.status = status;
|
||||
args.dbr = 0;
|
||||
( *this->pFunc ) ( args );
|
||||
}
|
||||
|
||||
void * getCallback::operator new ( size_t size )
|
||||
{
|
||||
return getCallback::freeList.allocate ( size );
|
||||
}
|
||||
|
||||
void getCallback::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
getCallback::freeList.release ( pCadaver, size );
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
#ifndef ioCounter_ILh
|
||||
#define ioCounter_ILh
|
||||
|
||||
inline ioCounter::ioCounter () : pndrecvcnt ( 0u ), readSeq ( 0u )
|
||||
{
|
||||
}
|
||||
@@ -26,16 +29,23 @@ inline void ioCounter::incrementOutstandingIO ()
|
||||
if ( this->pndrecvcnt < UINT_MAX ) {
|
||||
this->pndrecvcnt++;
|
||||
}
|
||||
else {
|
||||
throwWithLocation ( caErrorCode (ECA_INTERNAL) );
|
||||
}
|
||||
this->mutex.unlock ();
|
||||
}
|
||||
|
||||
inline void ioCounter::lockOutstandingIO () const
|
||||
inline void ioCounter::incrementOutstandingIO ( unsigned readSeqIn )
|
||||
{
|
||||
this->mutex.lock ();
|
||||
}
|
||||
|
||||
inline void ioCounter::unlockOutstandingIO () const
|
||||
{
|
||||
if ( readSeqIn == this->readSeq ) {
|
||||
if ( this->pndrecvcnt < UINT_MAX ) {
|
||||
this->pndrecvcnt++;
|
||||
}
|
||||
else {
|
||||
throwWithLocation ( caErrorCode (ECA_INTERNAL) );
|
||||
}
|
||||
}
|
||||
this->mutex.unlock ();
|
||||
}
|
||||
|
||||
@@ -64,4 +74,4 @@ inline void ioCounter::cleanUpOutstandingIO ()
|
||||
this->mutex.unlock ();
|
||||
}
|
||||
|
||||
|
||||
#endif // ioCounter_ILh
|
||||
|
||||
226
src/ca/iocinf.h
226
src/ca/iocinf.h
@@ -28,7 +28,7 @@
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined (epicsExportSharedSymbols)
|
||||
#if defined ( epicsExportSharedSymbols )
|
||||
# error suspect that libCom was not imported
|
||||
#endif
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#include "epicsThread.h"
|
||||
#include "osiTimer.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "resourceLib.h"
|
||||
#include "localHostName.h"
|
||||
#include "ipAddrToAsciiAsynchronous.h"
|
||||
@@ -108,9 +107,6 @@
|
||||
|
||||
static const unsigned comBufSize = 0x4000;
|
||||
|
||||
class gnuWarningEliminate {
|
||||
};
|
||||
|
||||
class wireSendAdapter {
|
||||
public:
|
||||
virtual unsigned sendBytes ( const void *pBuf,
|
||||
@@ -150,16 +146,14 @@ public:
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
bool flushToWire ( wireSendAdapter & );
|
||||
unsigned fillFromWire ( wireRecvAdapter & );
|
||||
private:
|
||||
static tsFreeList < class comBuf, 0x20 > freeList;
|
||||
|
||||
protected:
|
||||
~comBuf ();
|
||||
private:
|
||||
unsigned nextWriteIndex;
|
||||
unsigned nextReadIndex;
|
||||
unsigned char buf [ comBufSize ]; // optimal for 100 Mb Ethernet LAN MTU
|
||||
|
||||
unsigned clipNElem ( unsigned elemSize, unsigned nElem );
|
||||
friend class gnuWarningEliminate;
|
||||
static tsFreeList < class comBuf, 0x20 > freeList;
|
||||
};
|
||||
|
||||
struct msgDescriptor {
|
||||
@@ -262,14 +256,15 @@ class nciu : public cacChannelIO, public tsDLNode < nciu >,
|
||||
public chronIntIdRes < nciu >, public tcpiiuPrivateListOfIO {
|
||||
public:
|
||||
nciu ( class cac &, netiiu &,
|
||||
cacChannel &, const char *pNameIn );
|
||||
cacChannelNotify &, const char *pNameIn );
|
||||
bool fullyConstructed () const;
|
||||
void destroy ();
|
||||
void cacDestroy ();
|
||||
void connect ( unsigned nativeType,
|
||||
unsigned long nativeCount, unsigned sid );
|
||||
void connect ();
|
||||
void disconnect ( netiiu &newiiu );
|
||||
int createChannelRequest ();
|
||||
void initiateConnect ();
|
||||
int read ( unsigned type,
|
||||
unsigned long count, void *pValue );
|
||||
int read ( unsigned type,
|
||||
@@ -278,8 +273,9 @@ public:
|
||||
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 nElem,
|
||||
unsigned mask, cacNotify ¬ify,
|
||||
cacNotifyIO *&pNotifyIO );
|
||||
void hostName ( char *pBuf, unsigned bufLength ) const;
|
||||
bool ca_v42_ok () const;
|
||||
short nativeType () const;
|
||||
@@ -291,13 +287,8 @@ public:
|
||||
unsigned searchAttempts () const;
|
||||
double beaconPeriod () const;
|
||||
bool connected () const;
|
||||
unsigned readSequence () const;
|
||||
void incrementOutstandingIO ();
|
||||
void decrementOutstandingIO ();
|
||||
void decrementOutstandingIO ( unsigned seqNumber );
|
||||
bool searchMsg ( unsigned short retrySeqNumber,
|
||||
unsigned &retryNoForThisChannel );
|
||||
bool fullyConstructed () const;
|
||||
bool isAttachedToVirtaulCircuit ( const osiSockAddr & );
|
||||
bool identifierEquivelence ( unsigned idToMatch );
|
||||
void * operator new ( size_t size );
|
||||
@@ -308,12 +299,17 @@ public:
|
||||
ca_uint32_t getSID () const;
|
||||
ca_uint32_t getCID () const;
|
||||
netiiu * getPIIU ();
|
||||
cac & getCAC ();
|
||||
void searchReplySetUp ( netiiu &iiu, unsigned sidIn,
|
||||
unsigned typeIn, unsigned long countIn );
|
||||
void show ( unsigned level ) const;
|
||||
bool verifyIIU ( netiiu & );
|
||||
bool verifyConnected ( netiiu & );
|
||||
|
||||
void decrementOutstandingIO ( unsigned seqNumber );
|
||||
void incrementOutstandingIO ( unsigned seqNumber );
|
||||
void connectTimeoutNotify ();
|
||||
protected:
|
||||
~nciu (); // force pool allocation
|
||||
private:
|
||||
cac &cacCtx;
|
||||
caar ar; // access rights
|
||||
@@ -329,16 +325,13 @@ private:
|
||||
unsigned f_fullyConstructed:1;
|
||||
unsigned f_previousConn:1; // T if connected in the past
|
||||
unsigned f_claimSent:1;
|
||||
|
||||
static tsFreeList < class nciu, 1024 > freeList;
|
||||
|
||||
~nciu (); // force pool allocation
|
||||
unsigned f_firstConnectDecrementsOutstandingIO:1;
|
||||
unsigned f_connectTimeOutSeen:1;
|
||||
void lock () const;
|
||||
void unlock () const;
|
||||
void lockOutstandingIO () const;
|
||||
void unlockOutstandingIO () const;
|
||||
const char * pHostName () const; // deprecated - please do not use
|
||||
friend class gnuWarningEliminate;
|
||||
void notifyStateChangeFirstConnectInCountOfOutstandingIO ();
|
||||
static tsFreeList < class nciu, 1024 > freeList;
|
||||
};
|
||||
|
||||
class baseNMIU : public tsDLNode < baseNMIU >,
|
||||
@@ -347,12 +340,15 @@ public:
|
||||
baseNMIU ( nciu &chan );
|
||||
virtual ~baseNMIU () = 0;
|
||||
virtual void completionNotify () = 0;
|
||||
virtual void completionNotify ( unsigned type, unsigned long count, const void *pData ) = 0;
|
||||
virtual void exceptionNotify ( int status, const char *pContext ) = 0;
|
||||
virtual void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count ) = 0;
|
||||
virtual void completionNotify ( unsigned type,
|
||||
unsigned long count, const void *pData ) = 0;
|
||||
virtual void exceptionNotify ( int status,
|
||||
const char *pContext ) = 0;
|
||||
virtual void exceptionNotify ( int status,
|
||||
const char *pContext, unsigned type,
|
||||
unsigned long count ) = 0;
|
||||
virtual class netSubscription * isSubscription ();
|
||||
virtual void show ( unsigned level ) const;
|
||||
virtual void uninstall () = 0;
|
||||
ca_uint32_t getID () const;
|
||||
nciu & channel () const;
|
||||
void destroy ();
|
||||
@@ -360,30 +356,36 @@ protected:
|
||||
nciu &chan;
|
||||
};
|
||||
|
||||
class netSubscription : private cacNotifyIO, public baseNMIU {
|
||||
class netSubscription : public cacNotifyIO, public baseNMIU {
|
||||
public:
|
||||
netSubscription ( nciu &chan, unsigned type, unsigned long count,
|
||||
unsigned mask, cacNotify ¬ify );
|
||||
void destroy ();
|
||||
void show ( unsigned level ) const;
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
unsigned long getCount () const;
|
||||
unsigned getType () const;
|
||||
unsigned getMask () const;
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
|
||||
protected:
|
||||
~netSubscription ();
|
||||
|
||||
private:
|
||||
unsigned long count;
|
||||
unsigned type;
|
||||
unsigned mask;
|
||||
|
||||
void uninstall ();
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
void completionNotify ( unsigned type,
|
||||
unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status,
|
||||
const char *pContext );
|
||||
void exceptionNotify ( int status,
|
||||
const char *pContext, unsigned type, unsigned long count );
|
||||
cacChannelIO & channelIO () const;
|
||||
class netSubscription * isSubscription ();
|
||||
~netSubscription ();
|
||||
static tsFreeList < class netSubscription, 1024 > freeList;
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
class netReadCopyIO : public baseNMIU {
|
||||
@@ -393,53 +395,61 @@ public:
|
||||
void show ( unsigned level ) const;
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
protected:
|
||||
~netReadCopyIO (); // must be allocated from pool
|
||||
private:
|
||||
unsigned type;
|
||||
unsigned long count;
|
||||
void *pValue;
|
||||
unsigned seqNumber;
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
void completionNotify ( );
|
||||
void completionNotify ( unsigned type,
|
||||
unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
void uninstall ();
|
||||
~netReadCopyIO (); // must be allocated from pool
|
||||
void exceptionNotify ( int status,
|
||||
const char *pContext, unsigned type, unsigned long count );
|
||||
cacChannelIO & channelIO () const;
|
||||
static tsFreeList < class netReadCopyIO, 1024 > freeList;
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
class netReadNotifyIO : public cacNotifyIO, public baseNMIU {
|
||||
public:
|
||||
netReadNotifyIO ( nciu &chan, cacNotify ¬ify );
|
||||
void destroy ();
|
||||
void show ( unsigned level ) const;
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
private:
|
||||
void uninstall ();
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
protected:
|
||||
~netReadNotifyIO ();
|
||||
private:
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type,
|
||||
unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status,
|
||||
const char *pContext, unsigned type, unsigned long count );
|
||||
cacChannelIO & channelIO () const;
|
||||
static tsFreeList < class netReadNotifyIO, 1024 > freeList;
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
class netWriteNotifyIO : public cacNotifyIO, public baseNMIU {
|
||||
public:
|
||||
netWriteNotifyIO ( nciu &chan, cacNotify ¬ify );
|
||||
void destroy ();
|
||||
void show ( unsigned level ) const;
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
private:
|
||||
void uninstall ();
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
protected:
|
||||
~netWriteNotifyIO ();
|
||||
private:
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type,
|
||||
unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status,
|
||||
const char *pContext, unsigned type, unsigned long count );
|
||||
cacChannelIO & channelIO () const;
|
||||
static tsFreeList < class netWriteNotifyIO, 1024 > freeList;
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -497,7 +507,6 @@ public:
|
||||
void show ( unsigned level ) const;
|
||||
unsigned channelCount () const;
|
||||
void disconnectAllChan ( netiiu & newiiu );
|
||||
void destroyAllIO ( nciu &chan );
|
||||
void connectTimeoutNotify ();
|
||||
bool searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThisChannel );
|
||||
void resetChannelRetryCounts ();
|
||||
@@ -518,9 +527,10 @@ public:
|
||||
virtual void connectAllIO ( nciu &chan );
|
||||
virtual void disconnectAllIO ( nciu &chan );
|
||||
virtual int clearChannelRequest ( nciu & );
|
||||
virtual void uninstallIO ( baseNMIU & );
|
||||
virtual bool uninstallIO ( baseNMIU & );
|
||||
virtual void subscriptionCancelRequest ( netSubscription &subscr, bool userThread );
|
||||
virtual double beaconPeriod () const;
|
||||
virtual bool destroyAllIO ( nciu &chan );
|
||||
|
||||
protected:
|
||||
cac * pCAC () const;
|
||||
@@ -605,7 +615,7 @@ public:
|
||||
char *pInBuf, unsigned long blockSize );
|
||||
void repeaterRegistrationMessage ( unsigned attemptNumber );
|
||||
void flush ();
|
||||
SOCKET getSock () const;
|
||||
unsigned getPort () const;
|
||||
void show ( unsigned level ) const;
|
||||
bool isCurrentThread () const;
|
||||
|
||||
@@ -622,6 +632,7 @@ private:
|
||||
SOCKET sock;
|
||||
unsigned short repeaterPort;
|
||||
unsigned short serverPort;
|
||||
unsigned short localPort;
|
||||
bool shutdownCmd;
|
||||
bool sockCloseCompleted;
|
||||
|
||||
@@ -711,12 +722,11 @@ public:
|
||||
void hostName ( char *pBuf, unsigned bufLength ) const;
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
protected:
|
||||
~hostNameCache ();
|
||||
private:
|
||||
bool ioComplete;
|
||||
char hostNameBuf [128];
|
||||
~hostNameCache ();
|
||||
friend class gnuWarningEliminate;
|
||||
|
||||
static tsFreeList < class hostNameCache, 16 > freeList;
|
||||
};
|
||||
|
||||
@@ -743,7 +753,6 @@ public:
|
||||
void flush ();
|
||||
virtual void show ( unsigned level ) const;
|
||||
//osiSockAddr address () const;
|
||||
SOCKET getSock () const;
|
||||
bool setEchoRequestPending ();
|
||||
|
||||
void processIncoming ();
|
||||
@@ -794,6 +803,7 @@ private:
|
||||
unsigned sendBytes ( const void *pBuf, unsigned nBytesInBuf );
|
||||
unsigned recvBytes ( void *pBuf, unsigned nBytesInBuf );
|
||||
bool flushToWire ( bool userThread );
|
||||
bool threadContextSensitiveFlushToWire ( bool userThread );
|
||||
|
||||
friend void cacSendThreadTCP ( void *pParam );
|
||||
friend void cacRecvThreadTCP ( void *pParam );
|
||||
@@ -842,7 +852,8 @@ private:
|
||||
int status, const char *pContext, unsigned type, unsigned long count );
|
||||
void connectAllIO ( nciu &chan );
|
||||
void disconnectAllIO ( nciu &chan );
|
||||
void uninstallIO ( baseNMIU & );
|
||||
bool uninstallIO ( baseNMIU & );
|
||||
bool destroyAllIO ( nciu &chan );
|
||||
|
||||
int subscriptionRequest ( netSubscription &subscr, bool userThread );
|
||||
void subscriptionCancelRequest ( netSubscription &subscr, bool userThread );
|
||||
@@ -851,25 +862,6 @@ private:
|
||||
static const pProtoStubTCP tcpJumpTableCAC [];
|
||||
};
|
||||
|
||||
#if 0
|
||||
class claimMsgCache {
|
||||
public:
|
||||
claimMsgCache ( bool v44 );
|
||||
~claimMsgCache ();
|
||||
int deliverMsg ( netiiu &iiu );
|
||||
void connectChannel ( cac & );
|
||||
private:
|
||||
char *pStr;
|
||||
unsigned clientId;
|
||||
unsigned serverId;
|
||||
unsigned currentStrLen;
|
||||
unsigned bufLen;
|
||||
bool v44;
|
||||
|
||||
friend bool nciu::setClaimMsgCache ( class claimMsgCache & );
|
||||
};
|
||||
#endif
|
||||
|
||||
class inetAddrID {
|
||||
public:
|
||||
inetAddrID ( const struct sockaddr_in &addrIn );
|
||||
@@ -892,15 +884,13 @@ public:
|
||||
epicsShareFunc void show ( unsigned level) const;
|
||||
epicsShareFunc void * operator new ( size_t size );
|
||||
epicsShareFunc void operator delete ( void *pCadaver, size_t size );
|
||||
|
||||
protected:
|
||||
epicsShareFunc ~bhe (); // force allocation from freeList
|
||||
private:
|
||||
tcpiiu *piiu;
|
||||
epicsTime timeStamp;
|
||||
double averagePeriod;
|
||||
|
||||
static tsFreeList < class bhe, 1024 > freeList;
|
||||
epicsShareFunc ~bhe (); // force allocation from freeList
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
class caErrorCode {
|
||||
@@ -959,28 +949,26 @@ static const unsigned CASG_MAGIC = 0xFAB4CAFE;
|
||||
class syncGroupNotify : public cacNotify, public tsDLNode < syncGroupNotify > {
|
||||
public:
|
||||
syncGroupNotify ( struct CASG &sgIn, void *pValue );
|
||||
void destroy ();
|
||||
void show (unsigned level) const;
|
||||
void release ();
|
||||
void show ( unsigned level ) const;
|
||||
|
||||
void * operator new (size_t size);
|
||||
void operator delete (void *pCadaver, size_t size);
|
||||
|
||||
private:
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
void lock () const;
|
||||
void unlock () const;
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
protected:
|
||||
virtual ~syncGroupNotify (); // allocate only from pool
|
||||
|
||||
private:
|
||||
struct CASG &sg;
|
||||
unsigned magic;
|
||||
void *pValue;
|
||||
unsigned long seqNo;
|
||||
|
||||
void completionNotify ( cacChannelIO & );
|
||||
void completionNotify ( cacChannelIO &,
|
||||
unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext );
|
||||
void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext, unsigned type, unsigned long count );
|
||||
static tsFreeList < class syncGroupNotify, 1024 > freeList;
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1022,8 +1010,7 @@ public:
|
||||
void decrementOutstandingIO ();
|
||||
void decrementOutstandingIO ( unsigned seqNumber );
|
||||
void incrementOutstandingIO ();
|
||||
void lockOutstandingIO () const;
|
||||
void unlockOutstandingIO () const;
|
||||
void incrementOutstandingIO ( unsigned seqNumber );
|
||||
unsigned readSequenceOfOutstandingIO () const;
|
||||
unsigned currentOutstandingIOCount () const;
|
||||
void cleanUpOutstandingIO ();
|
||||
@@ -1065,9 +1052,6 @@ public:
|
||||
|
||||
// beacon management
|
||||
void beaconNotify ( const inetAddrID &addr );
|
||||
bhe *lookupBeaconInetAddr ( const inetAddrID &ina );
|
||||
bhe *createBeaconHashEntry ( const inetAddrID &ina,
|
||||
const epicsTime &initialTimeStamp );
|
||||
void repeaterSubscribeConfirmNotify ();
|
||||
|
||||
// IIU routines
|
||||
@@ -1090,15 +1074,14 @@ public:
|
||||
void connectChannel ( unsigned id );
|
||||
void connectChannel ( bool v44Ok, unsigned id,
|
||||
unsigned nativeType, unsigned long nativeCount, unsigned sid );
|
||||
void channelDestroy ( unsigned id );
|
||||
void disconnectChannel ( unsigned id );
|
||||
bool createChannelIO ( const char *name_str, cacChannel &chan );
|
||||
cacChannelIO * createChannelIO ( const char *name_str, cacChannelNotify &chan );
|
||||
void installNetworkChannel ( nciu &, netiiu *&piiu );
|
||||
void lookupChannelAndTransferToTCP ( unsigned cid, unsigned sid,
|
||||
unsigned typeCode, unsigned long count, unsigned minorVersionNumber,
|
||||
const osiSockAddr & );
|
||||
void accessRightsNotify ( unsigned id, caar );
|
||||
void uninstallLocalChannel ( cacLocalChannelIO & );
|
||||
void destroyNCIU ( nciu & );
|
||||
void accessRightsNotify ( unsigned id, const caar & );
|
||||
void uninstallChannel ( nciu & );
|
||||
|
||||
// sync group routines
|
||||
CASG * lookupCASG ( unsigned id );
|
||||
@@ -1109,9 +1092,8 @@ public:
|
||||
void registerForFileDescriptorCallBack ( CAFDHANDLER *pFunc, void *pArg );
|
||||
void enableCallbackPreemption ();
|
||||
void disableCallbackPreemption ();
|
||||
void notifySearchResponse ( unsigned short retrySeqNo );
|
||||
bool flushPermit () const;
|
||||
const char * userNamePointer ();
|
||||
const char * userNamePointer () const;
|
||||
|
||||
// diagnostics
|
||||
unsigned connectionCount () const;
|
||||
@@ -1121,13 +1103,13 @@ public:
|
||||
void replaceErrLogHandler ( caPrintfFunc *ca_printf_func );
|
||||
void ipAddrToAsciiAsynchronousRequestInstall ( ipAddrToAsciiAsynchronous & request );
|
||||
|
||||
void getFDRegCallback ( CAFDHANDLER *&fdRegFunc, void *&fdRegArg ) const;
|
||||
|
||||
private:
|
||||
ipAddrToAsciiEngine ipToAEngine;
|
||||
cacServiceList services;
|
||||
tsDLList <tcpiiu> iiuList;
|
||||
tsDLList <tcpiiu> iiuListLimbo;
|
||||
tsDLList
|
||||
<cacLocalChannelIO> localChanList;
|
||||
chronIntIdResTable
|
||||
< nciu > chanTable;
|
||||
chronIntIdResTable
|
||||
@@ -1154,10 +1136,6 @@ private:
|
||||
unsigned initializingThreadsPriority;
|
||||
bool enablePreemptiveCallback;
|
||||
|
||||
// IIU routines
|
||||
tcpiiu * constructTCPIIU ( const osiSockAddr &, unsigned minorVersion );
|
||||
double connectionTimeout () const;
|
||||
|
||||
int pendPrivate ( double timeout, int early );
|
||||
bool setupUDP ();
|
||||
};
|
||||
|
||||
130
src/ca/nciu.cpp
130
src/ca/nciu.cpp
@@ -10,13 +10,13 @@
|
||||
* Author: Jeff Hill
|
||||
*
|
||||
* Notes:
|
||||
* 1) This class has a pointer to the IIU. Since it is possible
|
||||
* for the channel to exist when no IIU exists (because the user
|
||||
* created the channel), and because an IIU can disconnect and be
|
||||
* destroyed at any time, then it is necessary to hold a mutex while
|
||||
* the IIU pointer is in use. This mutex can not be the IIU's mutex
|
||||
* because the IIU's lock must not be held while waiting for a
|
||||
* message to be sent (otherwise a push pull deadlock can occur).
|
||||
* 1) This class has a pointer to the IIU. This pointer always points at
|
||||
* a valid IIU. If the client is deleted then the channel points at a
|
||||
* static file scope IIU. IIU's that disconnect go into an inactive state
|
||||
* and are stored on a list for later reuse. When the channel calls a
|
||||
* member function of the IIU, the IIU verifies that the channel's IIU
|
||||
* pointer is still pointing at itself only after it has acquired the IIU
|
||||
* lock.
|
||||
*/
|
||||
|
||||
#include "iocinf.h"
|
||||
@@ -33,7 +33,7 @@ tsFreeList < class nciu, 1024 > nciu::freeList;
|
||||
|
||||
static const caar defaultAccessRights = { false, false };
|
||||
|
||||
nciu::nciu ( cac &cacIn, netiiu &iiuIn, cacChannel &chanIn,
|
||||
nciu::nciu ( cac &cacIn, netiiu &iiuIn, cacChannelNotify &chanIn,
|
||||
const char *pNameIn ) :
|
||||
cacChannelIO ( chanIn ),
|
||||
cacCtx ( cacIn ),
|
||||
@@ -48,7 +48,9 @@ nciu::nciu ( cac &cacIn, netiiu &iiuIn, cacChannel &chanIn,
|
||||
f_connected ( false ),
|
||||
f_fullyConstructed ( true ),
|
||||
f_previousConn ( false ),
|
||||
f_claimSent ( false )
|
||||
f_claimSent ( false ),
|
||||
f_firstConnectDecrementsOutstandingIO ( false ),
|
||||
f_connectTimeOutSeen ( false )
|
||||
{
|
||||
// second constraint is imposed by size field in protocol header
|
||||
if ( this->nameLength > MAX_UDP_SEND - sizeof ( caHdr ) || this->nameLength > 0xffff ) {
|
||||
@@ -67,13 +69,16 @@ void nciu::destroy ()
|
||||
{
|
||||
// this occurs here so that it happens when
|
||||
// a lock is not applied
|
||||
this->piiu->destroyAllIO ( *this );
|
||||
unsigned i = 0u;
|
||||
while ( ! this->piiu->destroyAllIO ( *this ) ) {
|
||||
if ( i++ > 1000u ) {
|
||||
this->cacCtx.printf (
|
||||
"CAC: unable to destroy IO when channel destroyed?\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->piiu->clearChannelRequest ( *this );
|
||||
this->cacCtx.destroyNCIU ( *this );
|
||||
}
|
||||
|
||||
void nciu::cacDestroy ()
|
||||
{
|
||||
this->cacCtx.uninstallChannel ( *this );
|
||||
delete this;
|
||||
}
|
||||
|
||||
@@ -83,9 +88,11 @@ nciu::~nciu ()
|
||||
return;
|
||||
}
|
||||
|
||||
// this must go in the derived class's destructor because
|
||||
// this calls virtual functions in the cacChannelIO base
|
||||
this->ioReleaseNotify ();
|
||||
if ( ! this->f_connectTimeOutSeen && ! this->f_previousConn ) {
|
||||
if ( this->f_firstConnectDecrementsOutstandingIO ) {
|
||||
this->cacCtx.decrementOutstandingIO ();
|
||||
}
|
||||
}
|
||||
|
||||
delete [] this->pNameStr;
|
||||
}
|
||||
@@ -217,6 +224,12 @@ int nciu::write ( unsigned type, unsigned long countIn, const void *pValue, cacN
|
||||
return this->piiu->writeNotifyRequest ( *this, notify, type, countIn, pValue );
|
||||
}
|
||||
|
||||
void nciu::initiateConnect ()
|
||||
{
|
||||
this->notifyStateChangeFirstConnectInCountOfOutstandingIO ();
|
||||
this->cacCtx.installNetworkChannel ( *this, this->piiu );
|
||||
}
|
||||
|
||||
void nciu::connect ( unsigned nativeType,
|
||||
unsigned long nativeCount, unsigned sidIn )
|
||||
{
|
||||
@@ -235,6 +248,13 @@ void nciu::connect ( unsigned nativeType,
|
||||
}
|
||||
|
||||
this->lock ();
|
||||
|
||||
if ( ! this->f_connectTimeOutSeen && ! this->f_previousConn ) {
|
||||
if ( this->f_firstConnectDecrementsOutstandingIO ) {
|
||||
this->cacCtx.decrementOutstandingIO ();
|
||||
}
|
||||
}
|
||||
|
||||
bool v41Ok;
|
||||
if ( this->piiu ) {
|
||||
v41Ok = this->piiu->ca_v41_ok ();
|
||||
@@ -263,7 +283,7 @@ void nciu::connect ( unsigned nativeType,
|
||||
// resubscribe for monitors from this channel
|
||||
this->piiu->connectAllIO ( *this );
|
||||
|
||||
this->connectNotify ();
|
||||
this->notify ().connectNotify ( *this );
|
||||
|
||||
/*
|
||||
* if less than v4.1 then the server will never
|
||||
@@ -272,7 +292,16 @@ void nciu::connect ( unsigned nativeType,
|
||||
* their call back here
|
||||
*/
|
||||
if ( ! v41Ok ) {
|
||||
this->accessRightsNotify ( this->ar );
|
||||
this->notify ().accessRightsNotify ( *this, this->ar );
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::connectTimeoutNotify ()
|
||||
{
|
||||
if ( ! this->f_connectTimeOutSeen ) {
|
||||
this->lock ();
|
||||
this->f_connectTimeOutSeen = true;
|
||||
this->unlock ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,8 +338,8 @@ void nciu::disconnect ( netiiu &newiiu )
|
||||
/*
|
||||
* look for events that have an event cancel in progress
|
||||
*/
|
||||
this->disconnectNotify ();
|
||||
this->accessRightsNotify ( this->ar );
|
||||
this->notify ().disconnectNotify ( *this );
|
||||
this->notify ().accessRightsNotify ( *this, this->ar );
|
||||
}
|
||||
|
||||
this->resetRetryCount ();
|
||||
@@ -352,36 +381,6 @@ bool nciu::searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThisCh
|
||||
return status;
|
||||
}
|
||||
|
||||
void nciu::incrementOutstandingIO ()
|
||||
{
|
||||
this->cacCtx.incrementOutstandingIO ();
|
||||
}
|
||||
|
||||
void nciu::decrementOutstandingIO ()
|
||||
{
|
||||
this->cacCtx.decrementOutstandingIO ();
|
||||
}
|
||||
|
||||
void nciu::decrementOutstandingIO ( unsigned seqNumber )
|
||||
{
|
||||
this->cacCtx.decrementOutstandingIO ( seqNumber );
|
||||
}
|
||||
|
||||
void nciu::lockOutstandingIO () const
|
||||
{
|
||||
this->cacCtx.lockOutstandingIO ();
|
||||
}
|
||||
|
||||
void nciu::unlockOutstandingIO () const
|
||||
{
|
||||
this->cacCtx.unlockOutstandingIO ();
|
||||
}
|
||||
|
||||
unsigned nciu::readSequence () const
|
||||
{
|
||||
return this->cacCtx.readSequenceOfOutstandingIO ();
|
||||
}
|
||||
|
||||
void nciu::hostName ( char *pBuf, unsigned bufLength ) const
|
||||
{
|
||||
this->piiu->hostName ( pBuf, bufLength );
|
||||
@@ -499,7 +498,8 @@ int nciu::createChannelRequest ()
|
||||
}
|
||||
|
||||
int nciu::subscribe ( unsigned type, unsigned long nElem,
|
||||
unsigned mask, cacNotify ¬ify )
|
||||
unsigned mask, cacNotify ¬ify,
|
||||
cacNotifyIO *&pNotifyIO )
|
||||
{
|
||||
netSubscription *pSubcr = new netSubscription ( *this,
|
||||
type, nElem, mask, notify );
|
||||
@@ -508,6 +508,9 @@ int nciu::subscribe ( unsigned type, unsigned long nElem,
|
||||
if ( status != ECA_NORMAL ) {
|
||||
pSubcr->destroy ();
|
||||
}
|
||||
else {
|
||||
pNotifyIO = pSubcr;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else {
|
||||
@@ -515,6 +518,27 @@ int nciu::subscribe ( unsigned type, unsigned long nElem,
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::notifyStateChangeFirstConnectInCountOfOutstandingIO ()
|
||||
{
|
||||
this->lock ();
|
||||
// test is performed via a callback so that locking is correct
|
||||
if ( ! this->f_connectTimeOutSeen && ! this->f_previousConn ) {
|
||||
if ( this->notify ().includeFirstConnectInCountOfOutstandingIO () ) {
|
||||
if ( ! this->f_firstConnectDecrementsOutstandingIO ) {
|
||||
this->cacCtx.incrementOutstandingIO ();
|
||||
this->f_firstConnectDecrementsOutstandingIO = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( this->f_firstConnectDecrementsOutstandingIO ) {
|
||||
this->cacCtx.decrementOutstandingIO ();
|
||||
this->f_firstConnectDecrementsOutstandingIO = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->unlock ();
|
||||
}
|
||||
|
||||
void nciu::show ( unsigned level ) const
|
||||
{
|
||||
if ( this->f_connected ) {
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
// nciu inline member functions
|
||||
//
|
||||
|
||||
#include "ioCounter_IL.h"
|
||||
|
||||
inline void * nciu::operator new ( size_t size )
|
||||
{
|
||||
return nciu::freeList.allocate ( size );
|
||||
@@ -58,7 +60,7 @@ inline void nciu::resetRetryCount ()
|
||||
inline void nciu::accessRightsStateChange ( const caar &arIn )
|
||||
{
|
||||
this->ar = arIn;
|
||||
this->accessRightsNotify ( this->ar );
|
||||
this->notify ().accessRightsNotify ( *this, this->ar );
|
||||
}
|
||||
|
||||
inline ca_uint32_t nciu::getSID () const
|
||||
@@ -127,3 +129,19 @@ inline netiiu * nciu::getPIIU ()
|
||||
return this->piiu;
|
||||
}
|
||||
|
||||
inline cac & nciu::getCAC ()
|
||||
{
|
||||
return this->cacCtx;
|
||||
}
|
||||
|
||||
|
||||
inline void nciu::incrementOutstandingIO ( unsigned seqNumber )
|
||||
{
|
||||
this->cacCtx.incrementOutstandingIO ( seqNumber );
|
||||
}
|
||||
|
||||
inline void nciu::decrementOutstandingIO ( unsigned seqNumber )
|
||||
{
|
||||
this->cacCtx.decrementOutstandingIO ( seqNumber );
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "iocinf.h"
|
||||
#include "netReadCopyIO_IL.h"
|
||||
#include "nciu_IL.h"
|
||||
#include "baseNMIU_IL.h"
|
||||
|
||||
tsFreeList < class netReadCopyIO, 1024 > netReadCopyIO::freeList;
|
||||
|
||||
@@ -21,17 +22,11 @@ netReadCopyIO::netReadCopyIO ( nciu &chanIn, unsigned typeIn, unsigned long coun
|
||||
baseNMIU ( chanIn ), type ( typeIn ), count ( countIn ),
|
||||
pValue ( pValueIn ), seqNumber ( seqNumberIn )
|
||||
{
|
||||
chanIn.incrementOutstandingIO ();
|
||||
this->chan.incrementOutstandingIO ( seqNumberIn );
|
||||
}
|
||||
|
||||
netReadCopyIO::~netReadCopyIO ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void netReadCopyIO::uninstall ()
|
||||
{
|
||||
this->chan.getPIIU ()->uninstallIO ( *this );
|
||||
}
|
||||
|
||||
void netReadCopyIO::completionNotify ()
|
||||
@@ -59,14 +54,22 @@ void netReadCopyIO::completionNotify ( unsigned typeIn,
|
||||
|
||||
void netReadCopyIO::exceptionNotify ( int status, const char *pContext )
|
||||
{
|
||||
ca_signal (status, pContext);
|
||||
ca_signal_formated ( status, __FILE__, __LINE__,
|
||||
"%s chan=%s\n", pContext, this->channelIO ().pName () );
|
||||
|
||||
}
|
||||
|
||||
void netReadCopyIO::exceptionNotify ( int status,
|
||||
const char *pContextIn, unsigned typeIn, unsigned long countIn )
|
||||
{
|
||||
ca_signal_formated (status, __FILE__, __LINE__,
|
||||
"%s type=%d count=%ld\n", pContextIn, typeIn, countIn);
|
||||
ca_signal_formated ( status, __FILE__, __LINE__,
|
||||
"%s chan=%s type=%d count=%ld\n", pContextIn,
|
||||
this->channelIO ().pName (), typeIn, countIn);
|
||||
}
|
||||
|
||||
cacChannelIO & netReadCopyIO::channelIO () const
|
||||
{
|
||||
return this->channel ();
|
||||
}
|
||||
|
||||
void netReadCopyIO::show ( unsigned level ) const
|
||||
|
||||
@@ -13,40 +13,47 @@
|
||||
#include "iocinf.h"
|
||||
#include "netReadNotifyIO_IL.h"
|
||||
#include "nciu_IL.h"
|
||||
#include "baseNMIU_IL.h"
|
||||
|
||||
tsFreeList < class netReadNotifyIO, 1024 > netReadNotifyIO::freeList;
|
||||
|
||||
netReadNotifyIO::netReadNotifyIO ( nciu &chan, cacNotify ¬ifyIn ) :
|
||||
cacNotifyIO ( notifyIn ), baseNMIU ( chan ) {}
|
||||
|
||||
// private NOOP forces pool allocation
|
||||
netReadNotifyIO::~netReadNotifyIO () {}
|
||||
|
||||
void netReadNotifyIO::uninstall ()
|
||||
netReadNotifyIO::~netReadNotifyIO ()
|
||||
{
|
||||
this->chan.getPIIU ()->uninstallIO ( *this );
|
||||
}
|
||||
|
||||
void netReadNotifyIO::destroy ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void netReadNotifyIO::completionNotify ()
|
||||
{
|
||||
this->cacNotifyIO::exceptionNotify ( ECA_INTERNAL, "no data returned ?" );
|
||||
this->notify ().exceptionNotify ( this->channelIO (), ECA_INTERNAL, "no data returned ?" );
|
||||
}
|
||||
|
||||
void netReadNotifyIO::completionNotify ( unsigned type,
|
||||
unsigned long count, const void *pData )
|
||||
{
|
||||
this->cacNotifyIO::completionNotify ( type, count, pData );
|
||||
this->notify ().completionNotify ( this->channelIO (), type, count, pData );
|
||||
}
|
||||
|
||||
void netReadNotifyIO::exceptionNotify ( int status, const char *pContext )
|
||||
{
|
||||
this->cacNotifyIO::exceptionNotify ( status, pContext );
|
||||
this->notify ().exceptionNotify ( this->channelIO (), status, pContext );
|
||||
}
|
||||
|
||||
void netReadNotifyIO::exceptionNotify ( int status, const char *pContext,
|
||||
unsigned type, unsigned long count )
|
||||
{
|
||||
this->cacNotifyIO::exceptionNotify ( status, pContext, type ,count );
|
||||
this->notify ().exceptionNotify ( this->channelIO (), status, pContext, type ,count );
|
||||
}
|
||||
|
||||
cacChannelIO & netReadNotifyIO::channelIO () const
|
||||
{
|
||||
return this->channel ();
|
||||
}
|
||||
|
||||
void netReadNotifyIO::show ( unsigned level ) const
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "iocinf.h"
|
||||
#include "netSubscription_IL.h"
|
||||
#include "nciu_IL.h"
|
||||
#include "baseNMIU_IL.h"
|
||||
|
||||
tsFreeList < class netSubscription, 1024 > netSubscription::freeList;
|
||||
|
||||
@@ -25,14 +26,21 @@ netSubscription::netSubscription ( nciu &chan, unsigned typeIn, unsigned long co
|
||||
|
||||
netSubscription::~netSubscription ()
|
||||
{
|
||||
// o netiiu lock must _not_ be applied when calling this
|
||||
// o uninstall from channel and IIU occur in uninstall method
|
||||
// netiiu lock must _not_ be applied when calling this
|
||||
this->chan.getPIIU ()->subscriptionCancelRequest ( *this, true );
|
||||
}
|
||||
|
||||
void netSubscription::uninstall ()
|
||||
void netSubscription::destroy ()
|
||||
{
|
||||
this->chan.getPIIU ()->uninstallIO ( *this );
|
||||
unsigned i = 0u;
|
||||
while ( ! this->chan.getPIIU ()->uninstallIO ( *this ) ) {
|
||||
if ( i++ > 1000u ) {
|
||||
this->chan.getCAC ().printf (
|
||||
"CAC: unable to destroy IO\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
class netSubscription * netSubscription::isSubscription ()
|
||||
@@ -42,27 +50,32 @@ class netSubscription * netSubscription::isSubscription ()
|
||||
|
||||
void netSubscription::completionNotify ()
|
||||
{
|
||||
this->cacNotifyIO::completionNotify ();
|
||||
this->notify ().completionNotify ( this->channel () );
|
||||
}
|
||||
|
||||
void netSubscription::completionNotify ( unsigned typeIn,
|
||||
unsigned long countIn, const void *pDataIn )
|
||||
{
|
||||
this->cacNotifyIO::completionNotify ( typeIn, countIn, pDataIn );
|
||||
this->notify ().completionNotify ( this->channel (), typeIn, countIn, pDataIn );
|
||||
}
|
||||
|
||||
void netSubscription::exceptionNotify ( int status, const char *pContext )
|
||||
{
|
||||
this->cacNotifyIO::exceptionNotify ( status, pContext );
|
||||
this->notify ().exceptionNotify ( this->channel (), status, pContext );
|
||||
}
|
||||
|
||||
void netSubscription::exceptionNotify ( int statusIn,
|
||||
const char *pContextIn, unsigned typeIn, unsigned long countIn )
|
||||
{
|
||||
this->cacNotifyIO::exceptionNotify ( statusIn,
|
||||
this->notify ().exceptionNotify ( this->channel (), statusIn,
|
||||
pContextIn, typeIn, countIn );
|
||||
}
|
||||
|
||||
cacChannelIO & netSubscription::channelIO () const
|
||||
{
|
||||
return this->channel ();
|
||||
}
|
||||
|
||||
void netSubscription::show ( unsigned level ) const
|
||||
{
|
||||
printf ( "event subscription IO at %p, type %s, element count %lu, mask %u\n",
|
||||
|
||||
@@ -13,44 +13,51 @@
|
||||
#include "iocinf.h"
|
||||
#include "netWriteNotifyIO_IL.h"
|
||||
#include "nciu_IL.h"
|
||||
#include "baseNMIU_IL.h"
|
||||
|
||||
tsFreeList < class netWriteNotifyIO, 1024 > netWriteNotifyIO::freeList;
|
||||
|
||||
netWriteNotifyIO::netWriteNotifyIO (nciu &chan, cacNotify ¬ifyIn) :
|
||||
cacNotifyIO (notifyIn), baseNMIU (chan)
|
||||
netWriteNotifyIO::netWriteNotifyIO ( nciu &chan, cacNotify ¬ifyIn ) :
|
||||
cacNotifyIO ( notifyIn ), baseNMIU ( chan )
|
||||
{
|
||||
}
|
||||
|
||||
netWriteNotifyIO::~netWriteNotifyIO ()
|
||||
{
|
||||
// private NOOP forces pool allocation
|
||||
}
|
||||
|
||||
void netWriteNotifyIO::uninstall ()
|
||||
void netWriteNotifyIO::destroy ()
|
||||
{
|
||||
this->chan.getPIIU ()->uninstallIO ( *this );
|
||||
delete this;
|
||||
}
|
||||
|
||||
void netWriteNotifyIO::completionNotify ()
|
||||
{
|
||||
this->cacNotifyIO::completionNotify ();
|
||||
this->notify ().completionNotify ( this->channelIO () );
|
||||
}
|
||||
|
||||
void netWriteNotifyIO::completionNotify (
|
||||
unsigned /* type */, unsigned long /* count */,
|
||||
const void * /* pData */ )
|
||||
{
|
||||
this->cacNotifyIO::completionNotify ();
|
||||
this->notify ().completionNotify ( this->channelIO () );
|
||||
}
|
||||
|
||||
void netWriteNotifyIO::exceptionNotify ( int status, const char *pContext )
|
||||
void netWriteNotifyIO::exceptionNotify ( int status,
|
||||
const char *pContext )
|
||||
{
|
||||
this->cacNotifyIO::exceptionNotify (status, pContext);
|
||||
this->notify ().exceptionNotify ( this->channelIO (), status, pContext );
|
||||
}
|
||||
|
||||
void netWriteNotifyIO::exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count )
|
||||
void netWriteNotifyIO::exceptionNotify ( int status,
|
||||
const char *pContext, unsigned type, unsigned long count )
|
||||
{
|
||||
this->cacNotifyIO::exceptionNotify (status, pContext, type, count);
|
||||
this->notify ().exceptionNotify ( this->channelIO (), status, pContext, type, count );
|
||||
}
|
||||
|
||||
cacChannelIO & netWriteNotifyIO::channelIO () const
|
||||
{
|
||||
return this->channel ();
|
||||
}
|
||||
|
||||
void netWriteNotifyIO::show ( unsigned level ) const
|
||||
|
||||
@@ -24,7 +24,6 @@ netiiu::netiiu ( cac *pClientCtxIn ) : pClientCtx ( pClientCtxIn )
|
||||
|
||||
netiiu::~netiiu ()
|
||||
{
|
||||
assert ( this->channelList.count () == 0u );
|
||||
}
|
||||
|
||||
void netiiu::show ( unsigned level ) const
|
||||
@@ -99,23 +98,26 @@ void netiiu::disconnectAllChan ( netiiu & newiiu )
|
||||
//
|
||||
// netiiu::destroyAllIO ()
|
||||
//
|
||||
// care is taken not to not hold the lock while sending event
|
||||
// subscription delete ( when the IO is deleted )
|
||||
// care is taken to not hold the lock while deleting the
|
||||
// IO so that subscription delete request (sent by the
|
||||
// IO's destructor) do not deadlock
|
||||
//
|
||||
void netiiu::destroyAllIO ( nciu &chan )
|
||||
bool netiiu::destroyAllIO ( nciu &chan )
|
||||
{
|
||||
baseNMIU *pIO;
|
||||
while ( true ) {
|
||||
{
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
pIO = chan.tcpiiuPrivateListOfIO::eventq.first ();
|
||||
if ( ! pIO ) {
|
||||
break;
|
||||
}
|
||||
pIO->uninstall ();
|
||||
tsDLList < baseNMIU > eventQ;
|
||||
{
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
if ( chan.verifyIIU ( *this ) ) {
|
||||
eventQ.add ( chan.tcpiiuPrivateListOfIO::eventq );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while ( baseNMIU *pIO = eventQ.get () ) {
|
||||
pIO->destroy ();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void netiiu::connectTimeoutNotify ()
|
||||
@@ -260,13 +262,17 @@ void netiiu::connectAllIO ( nciu & )
|
||||
{
|
||||
}
|
||||
|
||||
void netiiu::uninstallIO ( baseNMIU &io )
|
||||
bool netiiu::uninstallIO ( baseNMIU &io )
|
||||
{
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
if ( ! io.channel ().verifyIIU ( *this ) ) {
|
||||
return false;
|
||||
}
|
||||
io.channel ().tcpiiuPrivateListOfIO::eventq.remove ( io );
|
||||
return true;
|
||||
}
|
||||
|
||||
double netiiu::beaconPeriod () const
|
||||
{
|
||||
return - DBL_MAX;
|
||||
return ( - DBL_MAX );
|
||||
}
|
||||
|
||||
@@ -15,105 +15,133 @@
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
extern "C" void cacNoConnHandler ( struct connection_handler_args args );
|
||||
|
||||
class gnuOldAccessWarningEliminate {
|
||||
};
|
||||
|
||||
struct oldChannel : public cacChannel {
|
||||
class oldChannelNotify : public cacChannelNotify {
|
||||
public:
|
||||
oldChannel (caCh *pConnCallBack, void *pPrivate);
|
||||
void destroy ();
|
||||
void setPrivatePointer (void *);
|
||||
oldChannelNotify ( caCh *pConnCallBackIn, void *pPrivateIn );
|
||||
void release ();
|
||||
void setPrivatePointer ( void * );
|
||||
void * privatePointer () const;
|
||||
int changeConnCallBack (caCh *pfunc);
|
||||
int replaceAccessRightsEvent (caArh *pfunc);
|
||||
void ioAttachNotify ();
|
||||
void ioReleaseNotify ();
|
||||
|
||||
void * operator new (size_t size);
|
||||
void operator delete (void *pCadaver, size_t size);
|
||||
int changeConnCallBack ( cacChannelIO &, caCh *pfunc );
|
||||
int replaceAccessRightsEvent ( cacChannelIO &chan, caArh *pfunc );
|
||||
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
protected:
|
||||
~oldChannelNotify (); // must allocate from pool
|
||||
private:
|
||||
caCh *pConnCallBack;
|
||||
void *pPrivate;
|
||||
caArh *pAccessRightsFunc;
|
||||
|
||||
~oldChannel (); // must allocate from pool
|
||||
void connectTimeoutNotify ();
|
||||
void connectNotify ();
|
||||
void disconnectNotify ();
|
||||
void accessRightsNotify ( caar );
|
||||
static tsFreeList < struct oldChannel, 1024 > freeList;
|
||||
|
||||
friend int epicsShareAPI ca_array_get (chtype type, unsigned long count, chid pChan, void *pValue);
|
||||
friend void cacNoConnHandler ( struct connection_handler_args args );
|
||||
void connectNotify ( cacChannelIO &chan );
|
||||
void disconnectNotify ( cacChannelIO &chan );
|
||||
void accessRightsNotify ( cacChannelIO &chan, const caar & );
|
||||
bool includeFirstConnectInCountOfOutstandingIO () const;
|
||||
class oldChannelNotify * pOldChannelNotify ();
|
||||
static tsFreeList < class oldChannelNotify, 1024 > freeList;
|
||||
};
|
||||
|
||||
class getCallback : public cacNotify {
|
||||
public:
|
||||
getCallback (oldChannel &chan, caEventCallBackFunc *pFunc, void *pPrivate);
|
||||
void destroy ();
|
||||
|
||||
getCallback ( caEventCallBackFunc *pFunc, void *pPrivate );
|
||||
void release ();
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
|
||||
protected:
|
||||
~getCallback (); // allocate only out of pool
|
||||
private:
|
||||
oldChannel &chan;
|
||||
caEventCallBackFunc *pFunc;
|
||||
void *pPrivate;
|
||||
~getCallback (); // allocate only out of pool
|
||||
void completionNotify ();
|
||||
void completionNotify (unsigned type, unsigned long count, const void *pData);
|
||||
void exceptionNotify (int status, const char *pContext);
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
void completionNotify ( cacChannelIO &,
|
||||
unsigned type, unsigned long count, const void *pData);
|
||||
void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext);
|
||||
void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext, unsigned type, unsigned long count );
|
||||
static tsFreeList < class getCallback, 1024 > freeList;
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
class putCallback : public cacNotify {
|
||||
public:
|
||||
putCallback (oldChannel &chan, caEventCallBackFunc *pFunc, void *pPrivate );
|
||||
void destroy ();
|
||||
|
||||
putCallback ( caEventCallBackFunc *pFunc, void *pPrivate );
|
||||
void release ();
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
|
||||
protected:
|
||||
~putCallback (); // allocate only out of pool
|
||||
private:
|
||||
oldChannel &chan;
|
||||
caEventCallBackFunc *pFunc;
|
||||
void *pPrivate;
|
||||
~putCallback (); // allocate only out of pool
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
void completionNotify ( cacChannelIO & );
|
||||
void completionNotify ( cacChannelIO &,
|
||||
unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext );
|
||||
void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext, unsigned type, unsigned long count );
|
||||
static tsFreeList < class putCallback, 1024 > freeList;
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
struct oldSubscription : public cacNotify {
|
||||
public:
|
||||
oldSubscription ( oldChannel &chan, caEventCallBackFunc *pFunc, void *pPrivate );
|
||||
void destroy ();
|
||||
oldChannel &channel ();
|
||||
|
||||
oldSubscription ( caEventCallBackFunc *pFunc, void *pPrivate );
|
||||
void release ();
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void *pCadaver, size_t size );
|
||||
|
||||
protected:
|
||||
~oldSubscription (); // must allocate from pool
|
||||
private:
|
||||
oldChannel &chan;
|
||||
|
||||
caEventCallBackFunc *pFunc;
|
||||
void *pPrivate;
|
||||
|
||||
void completionNotify ();
|
||||
void completionNotify ( unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( int status, const char *pContext );
|
||||
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
|
||||
|
||||
~oldSubscription (); // must allocate from pool
|
||||
void completionNotify ( cacChannelIO &,
|
||||
unsigned type, unsigned long count, const void *pData );
|
||||
void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext );
|
||||
void exceptionNotify ( cacChannelIO &,
|
||||
int status, const char *pContext, unsigned type, unsigned long count );
|
||||
static tsFreeList < struct oldSubscription, 1024 > freeList;
|
||||
friend class gnuWarningEliminate;
|
||||
};
|
||||
|
||||
inline getCallback::getCallback ( caEventCallBackFunc *pFuncIn, void *pPrivateIn ) :
|
||||
pFunc ( pFuncIn ), pPrivate ( pPrivateIn )
|
||||
{
|
||||
}
|
||||
|
||||
inline void * getCallback::operator new ( size_t size )
|
||||
{
|
||||
return getCallback::freeList.allocate ( size );
|
||||
}
|
||||
|
||||
inline void getCallback::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
getCallback::freeList.release ( pCadaver, size );
|
||||
}
|
||||
|
||||
inline putCallback::putCallback ( caEventCallBackFunc *pFuncIn, void *pPrivateIn ) :
|
||||
pFunc ( pFuncIn ), pPrivate ( pPrivateIn )
|
||||
{
|
||||
}
|
||||
|
||||
inline void * putCallback::operator new ( size_t size )
|
||||
{
|
||||
return putCallback::freeList.allocate ( size );
|
||||
}
|
||||
|
||||
inline void putCallback::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
putCallback::freeList.release ( pCadaver, size );
|
||||
}
|
||||
|
||||
inline oldSubscription::oldSubscription ( caEventCallBackFunc *pFuncIn, void *pPrivateIn ) :
|
||||
pFunc ( pFuncIn ), pPrivate ( pPrivateIn )
|
||||
{
|
||||
}
|
||||
|
||||
inline void * oldSubscription::operator new ( size_t size )
|
||||
{
|
||||
return oldSubscription::freeList.allocate ( size );
|
||||
}
|
||||
|
||||
inline void oldSubscription::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
oldSubscription::freeList.release ( pCadaver, size );
|
||||
}
|
||||
|
||||
@@ -1,196 +1,2 @@
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
#include "iocinf.h"
|
||||
#include "oldAccess.h"
|
||||
|
||||
tsFreeList < struct oldChannel, 1024 > oldChannel::freeList;
|
||||
|
||||
/*
|
||||
* cacAlreadyConnHandler ()
|
||||
* This is installed into channels which dont have
|
||||
* a connection handler when ca_pend_io() times
|
||||
* out so that we will not decrement the pending
|
||||
* recv count in the future.
|
||||
*/
|
||||
extern "C" void cacAlreadyConnHandler ( struct connection_handler_args )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* cacNoConnHandler ()
|
||||
* This is installed into channels which dont have
|
||||
* a connection handler before ca_pend_io() times
|
||||
* out so that we will properly decrement the pending
|
||||
* recv count in the future.
|
||||
*/
|
||||
extern "C" void cacNoConnHandler ( struct connection_handler_args args )
|
||||
{
|
||||
args.chid->lockOutstandingIO ();
|
||||
if ( args.chid->pConnCallBack == cacNoConnHandler ) {
|
||||
args.chid->pConnCallBack = cacAlreadyConnHandler;
|
||||
if ( args.op == CA_OP_CONN_UP ) {
|
||||
args.chid->decrementOutstandingIO ();
|
||||
}
|
||||
}
|
||||
args.chid->unlockOutstandingIO ();
|
||||
}
|
||||
|
||||
extern "C" void cacNoopAccesRightsHandler ( struct access_rights_handler_args )
|
||||
{
|
||||
}
|
||||
|
||||
oldChannel::oldChannel (caCh *pConnCallBackIn, void *pPrivateIn) :
|
||||
pPrivate ( pPrivateIn ), pAccessRightsFunc ( cacNoopAccesRightsHandler )
|
||||
{
|
||||
if ( ! pConnCallBackIn ) {
|
||||
this->pConnCallBack = cacNoConnHandler;
|
||||
}
|
||||
else {
|
||||
this->pConnCallBack = pConnCallBackIn;
|
||||
}
|
||||
}
|
||||
|
||||
oldChannel::~oldChannel ()
|
||||
{
|
||||
if ( this->pConnCallBack == cacNoConnHandler ) {
|
||||
this->decrementOutstandingIO ();
|
||||
}
|
||||
}
|
||||
|
||||
void oldChannel::destroy ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void oldChannel::ioAttachNotify ()
|
||||
{
|
||||
this->lockOutstandingIO ();
|
||||
if ( this->pConnCallBack == cacNoConnHandler ) {
|
||||
this->incrementOutstandingIO ();
|
||||
}
|
||||
this->unlockOutstandingIO ();
|
||||
}
|
||||
|
||||
void oldChannel::ioReleaseNotify ()
|
||||
{
|
||||
this->lockOutstandingIO ();
|
||||
if ( this->pConnCallBack == cacNoConnHandler ) {
|
||||
this->decrementOutstandingIO ();
|
||||
}
|
||||
this->unlockOutstandingIO ();
|
||||
}
|
||||
|
||||
void oldChannel::setPrivatePointer ( void *pPrivateIn )
|
||||
{
|
||||
this->pPrivate = pPrivateIn;
|
||||
}
|
||||
|
||||
void * oldChannel::privatePointer () const
|
||||
{
|
||||
return this->pPrivate;
|
||||
}
|
||||
|
||||
void oldChannel::connectTimeoutNotify ()
|
||||
{
|
||||
this->lockOutstandingIO ();
|
||||
if ( this->pConnCallBack == cacNoConnHandler ) {
|
||||
this->pConnCallBack = cacAlreadyConnHandler;
|
||||
}
|
||||
this->unlockOutstandingIO ();
|
||||
}
|
||||
|
||||
void oldChannel::connectNotify ()
|
||||
{
|
||||
this->lockOutstandingIO ();
|
||||
struct connection_handler_args args;
|
||||
args.chid = this;
|
||||
args.op = CA_OP_CONN_UP;
|
||||
(*this->pConnCallBack) (args);
|
||||
this->unlockOutstandingIO ();
|
||||
}
|
||||
|
||||
void oldChannel::disconnectNotify ()
|
||||
{
|
||||
this->lockOutstandingIO ();
|
||||
struct connection_handler_args args;
|
||||
args.chid = this;
|
||||
args.op = CA_OP_CONN_DOWN;
|
||||
(*this->pConnCallBack) ( args );
|
||||
this->unlockOutstandingIO ();
|
||||
}
|
||||
|
||||
int oldChannel::changeConnCallBack ( caCh *pfunc )
|
||||
{
|
||||
this->lockOutstandingIO ();
|
||||
if ( ! pfunc ) {
|
||||
if ( this->pConnCallBack != cacNoConnHandler &&
|
||||
this->pConnCallBack != cacAlreadyConnHandler ) {
|
||||
if ( this->state () == cs_never_conn ) {
|
||||
this->incrementOutstandingIO ();
|
||||
this->pConnCallBack = cacNoConnHandler;
|
||||
}
|
||||
else {
|
||||
this->pConnCallBack = cacAlreadyConnHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( this->pConnCallBack == cacNoConnHandler ) {
|
||||
this->decrementOutstandingIO ();
|
||||
}
|
||||
this->pConnCallBack = pfunc;
|
||||
}
|
||||
this->unlockOutstandingIO ();
|
||||
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
void oldChannel::accessRightsNotify ( caar ar )
|
||||
{
|
||||
struct access_rights_handler_args args;
|
||||
args.chid = this;
|
||||
args.ar = ar;
|
||||
( *this->pAccessRightsFunc ) ( args );
|
||||
}
|
||||
|
||||
int oldChannel::replaceAccessRightsEvent ( caArh *pfunc )
|
||||
{
|
||||
if ( ! pfunc ) {
|
||||
pfunc = cacNoopAccesRightsHandler;
|
||||
}
|
||||
|
||||
this->pAccessRightsFunc = pfunc;
|
||||
if ( this->connected () ) {
|
||||
struct access_rights_handler_args args;
|
||||
args.chid = this;
|
||||
args.ar = this->accessRights ();
|
||||
(*pfunc) (args);
|
||||
}
|
||||
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
void * oldChannel::operator new ( size_t size )
|
||||
{
|
||||
return oldChannel::freeList.allocate ( size );
|
||||
}
|
||||
|
||||
void oldChannel::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
oldChannel::freeList.release ( pCadaver, size );
|
||||
}
|
||||
#error defunct
|
||||
124
src/ca/oldChannelNotify.cpp
Normal file
124
src/ca/oldChannelNotify.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
#include "iocinf.h"
|
||||
#include "oldAccess.h"
|
||||
|
||||
tsFreeList < class oldChannelNotify, 1024 > oldChannelNotify::freeList;
|
||||
|
||||
extern "C" void cacNoopConnHandler ( struct connection_handler_args )
|
||||
{
|
||||
}
|
||||
|
||||
extern "C" void cacNoopAccesRightsHandler ( struct access_rights_handler_args )
|
||||
{
|
||||
}
|
||||
|
||||
oldChannelNotify::oldChannelNotify ( caCh *pConnCallBackIn, void *pPrivateIn ) :
|
||||
pConnCallBack ( pConnCallBackIn ? pConnCallBackIn : cacNoopConnHandler ),
|
||||
pPrivate ( pPrivateIn ), pAccessRightsFunc ( cacNoopAccesRightsHandler )
|
||||
{
|
||||
}
|
||||
|
||||
oldChannelNotify::~oldChannelNotify ()
|
||||
{
|
||||
}
|
||||
|
||||
void oldChannelNotify::release ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void oldChannelNotify::setPrivatePointer ( void *pPrivateIn )
|
||||
{
|
||||
this->pPrivate = pPrivateIn;
|
||||
}
|
||||
|
||||
void * oldChannelNotify::privatePointer () const
|
||||
{
|
||||
return this->pPrivate;
|
||||
}
|
||||
|
||||
int oldChannelNotify::changeConnCallBack ( cacChannelIO &chan, caCh *pfunc )
|
||||
{
|
||||
this->pConnCallBack = pfunc ? pfunc : cacNoopConnHandler;
|
||||
// test for NOOP connection handler does _not_ occur here because the
|
||||
// lock is not applied
|
||||
chan.notifyStateChangeFirstConnectInCountOfOutstandingIO ();
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
int oldChannelNotify::replaceAccessRightsEvent ( cacChannelIO &chan, caArh *pfunc )
|
||||
{
|
||||
// The order of the following is significant to guarantee that the
|
||||
// access rights handler is always gets called even if the channel connects
|
||||
// while this is running. There is some very small chance that the
|
||||
// handler could be called twice here with the same access rights state, but
|
||||
// that will not upset the application.
|
||||
this->pAccessRightsFunc = pfunc ? pfunc : cacNoopAccesRightsHandler;
|
||||
if ( chan.connected () ) {
|
||||
struct access_rights_handler_args args;
|
||||
args.chid = &chan;
|
||||
args.ar = chan.accessRights ();
|
||||
( *pfunc ) ( args );
|
||||
}
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
void oldChannelNotify::connectNotify ( cacChannelIO &chan )
|
||||
{
|
||||
struct connection_handler_args args;
|
||||
args.chid = &chan;
|
||||
args.op = CA_OP_CONN_UP;
|
||||
( *this->pConnCallBack ) ( args );
|
||||
}
|
||||
|
||||
void oldChannelNotify::disconnectNotify ( cacChannelIO &chan )
|
||||
{
|
||||
struct connection_handler_args args;
|
||||
args.chid = &chan;
|
||||
args.op = CA_OP_CONN_DOWN;
|
||||
( *this->pConnCallBack ) ( args );
|
||||
}
|
||||
|
||||
void oldChannelNotify::accessRightsNotify ( cacChannelIO &chan, const caar &ar )
|
||||
{
|
||||
struct access_rights_handler_args args;
|
||||
args.chid = &chan;
|
||||
args.ar = ar;
|
||||
( *this->pAccessRightsFunc ) ( args );
|
||||
}
|
||||
|
||||
bool oldChannelNotify::includeFirstConnectInCountOfOutstandingIO () const
|
||||
{
|
||||
return ( this->pConnCallBack == cacNoopConnHandler );
|
||||
}
|
||||
|
||||
class oldChannelNotify * oldChannelNotify::pOldChannelNotify ()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void * oldChannelNotify::operator new ( size_t size )
|
||||
{
|
||||
return oldChannelNotify::freeList.allocate ( size );
|
||||
}
|
||||
|
||||
void oldChannelNotify::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
oldChannelNotify::freeList.release ( pCadaver, size );
|
||||
}
|
||||
@@ -15,31 +15,17 @@
|
||||
|
||||
tsFreeList < struct oldSubscription, 1024 > oldSubscription::freeList;
|
||||
|
||||
oldSubscription::oldSubscription ( oldChannel &chanIn, caEventCallBackFunc *pFuncIn, void *pPrivateIn ) :
|
||||
chan (chanIn), pFunc (pFuncIn), pPrivate (pPrivateIn)
|
||||
{
|
||||
}
|
||||
|
||||
oldSubscription::~oldSubscription ()
|
||||
{
|
||||
}
|
||||
|
||||
oldChannel &oldSubscription::channel ()
|
||||
{
|
||||
return this->chan;
|
||||
}
|
||||
|
||||
void oldSubscription::completionNotify ()
|
||||
{
|
||||
cacNotify::completionNotify ();
|
||||
}
|
||||
|
||||
void oldSubscription::completionNotify (unsigned type, unsigned long count, const void *pData)
|
||||
void oldSubscription::completionNotify ( cacChannelIO &io,
|
||||
unsigned type, unsigned long count, const void *pData)
|
||||
{
|
||||
struct event_handler_args args;
|
||||
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = &this->chan;
|
||||
args.chid = & io;
|
||||
args.type = type;
|
||||
args.count = count;
|
||||
args.status = ECA_NORMAL;
|
||||
@@ -47,37 +33,38 @@ void oldSubscription::completionNotify (unsigned type, unsigned long count, cons
|
||||
( *this->pFunc ) (args);
|
||||
}
|
||||
|
||||
void oldSubscription::exceptionNotify ( int status, const char * /* pContext */ )
|
||||
void oldSubscription::exceptionNotify ( cacChannelIO &io,
|
||||
int status, const char * /* pContext */ )
|
||||
{
|
||||
struct event_handler_args args;
|
||||
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = &this->chan;
|
||||
args.type = 0;
|
||||
args.chid = & io;
|
||||
args.type = TYPENOTCONN;
|
||||
args.count = 0;
|
||||
args.status = status;
|
||||
args.dbr = 0;
|
||||
( *this->pFunc ) (args);
|
||||
}
|
||||
|
||||
void oldSubscription::exceptionNotify ( int status, const char *pContext,
|
||||
unsigned type, unsigned long count )
|
||||
void oldSubscription::exceptionNotify ( cacChannelIO &io,
|
||||
int status, const char *pContext,
|
||||
unsigned type, unsigned long count )
|
||||
{
|
||||
cacNotify::exceptionNotify ( status, pContext, type, count );
|
||||
struct event_handler_args args;
|
||||
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = & io;
|
||||
args.type = type;
|
||||
args.count = count;
|
||||
args.status = status;
|
||||
args.dbr = 0;
|
||||
( *this->pFunc ) (args);
|
||||
}
|
||||
|
||||
void oldSubscription::destroy ()
|
||||
void oldSubscription::release ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void * oldSubscription::operator new ( size_t size )
|
||||
{
|
||||
return oldSubscription::freeList.allocate ( size );
|
||||
}
|
||||
|
||||
void oldSubscription::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
oldSubscription::freeList.release ( pCadaver, size );
|
||||
}
|
||||
|
||||
|
||||
@@ -20,64 +20,68 @@
|
||||
|
||||
tsFreeList < class putCallback, 1024 > putCallback::freeList;
|
||||
|
||||
putCallback::putCallback (oldChannel &chanIn, caEventCallBackFunc *pFuncIn, void *pPrivateIn ) :
|
||||
chan (chanIn), pFunc (pFuncIn), pPrivate (pPrivateIn)
|
||||
{
|
||||
}
|
||||
|
||||
putCallback::~putCallback ()
|
||||
{
|
||||
}
|
||||
|
||||
void putCallback::destroy ()
|
||||
void putCallback::release ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void putCallback::completionNotify ()
|
||||
void putCallback::completionNotify ( cacChannelIO &io )
|
||||
{
|
||||
struct event_handler_args args;
|
||||
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = &this->chan;
|
||||
args.type = 0;
|
||||
args.count = 0;
|
||||
args.chid = & io;
|
||||
args.type = TYPENOTCONN;
|
||||
args.count = 0;
|
||||
args.status = ECA_NORMAL;
|
||||
args.dbr = 0;
|
||||
(*this->pFunc) (args);
|
||||
}
|
||||
|
||||
void putCallback::completionNotify ( unsigned type,
|
||||
unsigned long count, const void *pData )
|
||||
{
|
||||
cacNotify::completionNotify ( type, count, pData );
|
||||
}
|
||||
|
||||
void putCallback::exceptionNotify (int status, const char * /* pContext */ )
|
||||
void putCallback::completionNotify ( cacChannelIO &io, unsigned type,
|
||||
unsigned long count, const void *pData )
|
||||
{
|
||||
struct event_handler_args args;
|
||||
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = &this->chan;
|
||||
args.type = 0;
|
||||
args.chid = & io;
|
||||
args.type = type;
|
||||
args.count = count;
|
||||
args.status = ECA_NORMAL;
|
||||
args.dbr = 0;
|
||||
(*this->pFunc) (args);
|
||||
}
|
||||
|
||||
void putCallback::exceptionNotify ( cacChannelIO &io,
|
||||
int status, const char * /* pContext */ )
|
||||
{
|
||||
struct event_handler_args args;
|
||||
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = & io;
|
||||
args.type = TYPENOTCONN;
|
||||
args.count = 0;
|
||||
args.status = status;
|
||||
args.dbr = 0;
|
||||
(*this->pFunc) (args);
|
||||
}
|
||||
|
||||
void putCallback::exceptionNotify ( int status,
|
||||
void putCallback::exceptionNotify ( cacChannelIO &io, int status,
|
||||
const char *pContext, unsigned type, unsigned long count )
|
||||
{
|
||||
cacNotify::exceptionNotify ( status, pContext, type, count );
|
||||
struct event_handler_args args;
|
||||
|
||||
args.usr = this->pPrivate;
|
||||
args.chid = & io;
|
||||
args.type = type;
|
||||
args.count = count;
|
||||
args.status = status;
|
||||
args.dbr = 0;
|
||||
(*this->pFunc) (args);
|
||||
}
|
||||
|
||||
void * putCallback::operator new ( size_t size )
|
||||
{
|
||||
return putCallback::freeList.allocate ( size );
|
||||
}
|
||||
|
||||
void putCallback::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
putCallback::freeList.release ( pCadaver, size );
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ syncGroupNotify::syncGroupNotify ( CASG &sgIn, void *pValueIn ) :
|
||||
this->sg.mutex.unlock ();
|
||||
}
|
||||
|
||||
void syncGroupNotify::destroy ()
|
||||
void syncGroupNotify::release ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
@@ -53,8 +53,10 @@ syncGroupNotify::~syncGroupNotify ()
|
||||
this->sg.mutex.unlock ();
|
||||
}
|
||||
|
||||
void syncGroupNotify::completionNotify ()
|
||||
void syncGroupNotify::completionNotify ( cacChannelIO & )
|
||||
{
|
||||
bool done;
|
||||
|
||||
if ( this->magic != CASG_MAGIC ) {
|
||||
ca_printf ("cac: sync group io_complete(): bad sync grp op magic number?\n");
|
||||
return;
|
||||
@@ -64,21 +66,28 @@ void syncGroupNotify::completionNotify ()
|
||||
if ( this->seqNo == this->sg.seqNo ) {
|
||||
assert ( this->sg.opPendCount > 0u );
|
||||
this->sg.opPendCount--;
|
||||
done = this->sg.opPendCount == 0;
|
||||
}
|
||||
else {
|
||||
done = true;
|
||||
}
|
||||
this->sg.mutex.unlock ();
|
||||
|
||||
if ( this->sg.opPendCount == 0 ) {
|
||||
if ( done ) {
|
||||
this->sg.sem.signal ();
|
||||
}
|
||||
}
|
||||
|
||||
void syncGroupNotify::completionNotify ( unsigned type, unsigned long count, const void *pData )
|
||||
void syncGroupNotify::completionNotify ( cacChannelIO &,
|
||||
unsigned type, unsigned long count, const void *pData )
|
||||
{
|
||||
if ( this->magic != CASG_MAGIC ) {
|
||||
ca_printf ("cac: sync group io_complete(): bad sync grp op magic number?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bool complete;
|
||||
|
||||
this->sg.mutex.lock ();
|
||||
if ( this->seqNo == this->sg.seqNo ) {
|
||||
/*
|
||||
@@ -86,14 +95,18 @@ void syncGroupNotify::completionNotify ( unsigned type, unsigned long count, con
|
||||
*/
|
||||
if ( this->pValue ) {
|
||||
size_t size = dbr_size_n ( type, count );
|
||||
memcpy (this->pValue, pData, size);
|
||||
memcpy ( this->pValue, pData, size );
|
||||
}
|
||||
assert ( this->sg.opPendCount > 0u );
|
||||
this->sg.opPendCount--;
|
||||
complete = this->sg.opPendCount == 0;
|
||||
}
|
||||
else {
|
||||
complete = true;
|
||||
}
|
||||
this->sg.mutex.unlock ();
|
||||
|
||||
if ( this->sg.opPendCount == 0 ) {
|
||||
if ( complete ) {
|
||||
this->sg.sem.signal ();
|
||||
}
|
||||
}
|
||||
@@ -104,27 +117,20 @@ void syncGroupNotify::show ( unsigned /* level */ ) const
|
||||
this->pValue, this->magic, this->seqNo, &this->sg);
|
||||
}
|
||||
|
||||
void syncGroupNotify::exceptionNotify ( int status, const char *pContext )
|
||||
void syncGroupNotify::exceptionNotify ( cacChannelIO &io,
|
||||
int status, const char *pContext )
|
||||
{
|
||||
ca_signal_formated ( status, __FILE__, __LINE__,
|
||||
"CA Sync Group request failed because \"%s\"\n", pContext);
|
||||
"CA Sync Group request to channel %s failed because \"%s\"\n",
|
||||
io.pName (), pContext);
|
||||
}
|
||||
|
||||
void syncGroupNotify::exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count )
|
||||
void syncGroupNotify::exceptionNotify ( cacChannelIO &io,
|
||||
int status, const char *pContext, unsigned type, unsigned long count )
|
||||
{
|
||||
ca_signal_formated ( status, __FILE__, __LINE__,
|
||||
"CA Sync Group request failed with type=%d count=%ld because \"%s\"\n",
|
||||
type, count, pContext);
|
||||
}
|
||||
|
||||
void syncGroupNotify::lock () const
|
||||
{
|
||||
this->sg.mutex.lock ();
|
||||
}
|
||||
|
||||
void syncGroupNotify::unlock () const
|
||||
{
|
||||
this->sg.mutex.unlock ();
|
||||
"CA Sync Group request failed with channel=%s type=%d count=%ld because \"%s\"\n",
|
||||
io.pName (), type, count, pContext);
|
||||
}
|
||||
|
||||
void * syncGroupNotify::operator new (size_t size)
|
||||
|
||||
@@ -508,6 +508,14 @@ bool tcpiiu::initiateConnect ( const osiSockAddr &addrIn, unsigned minorVersion,
|
||||
socket_close ( this->sock );
|
||||
return false;
|
||||
}
|
||||
|
||||
CAFDHANDLER *fdRegFunc;
|
||||
void *fdRegArg;
|
||||
this->pCAC ()->getFDRegCallback ( fdRegFunc, fdRegArg );
|
||||
if ( fdRegFunc ) {
|
||||
( *fdRegFunc ) ( fdRegArg, this->sock, TRUE );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -594,7 +602,6 @@ void tcpiiu::cleanShutdown ()
|
||||
else {
|
||||
this->state = iiu_disconnected;
|
||||
}
|
||||
|
||||
}
|
||||
else if ( this->state == iiu_connecting ) {
|
||||
int status = socket_close ( this->sock );
|
||||
@@ -662,6 +669,13 @@ void tcpiiu::disconnect ()
|
||||
this->ioTable.numEntriesInstalled () );
|
||||
}
|
||||
|
||||
CAFDHANDLER *fdRegFunc;
|
||||
void *fdRegArg;
|
||||
this->pCAC ()->getFDRegCallback ( fdRegFunc, fdRegArg );
|
||||
if ( fdRegFunc ) {
|
||||
( *fdRegFunc ) ( fdRegArg, this->sock, FALSE );
|
||||
}
|
||||
|
||||
this->cleanShutdown ();
|
||||
|
||||
// wait for send thread to exit
|
||||
@@ -1157,7 +1171,7 @@ void tcpiiu::readRespAction ()
|
||||
|
||||
void tcpiiu::clearChannelRespAction ()
|
||||
{
|
||||
this->pCAC ()->channelDestroy ( this->curMsg.m_available );
|
||||
// currently a noop
|
||||
}
|
||||
|
||||
void tcpiiu::exceptionRespAction ()
|
||||
@@ -1421,7 +1435,7 @@ int tcpiiu::writeRequest ( nciu &chan, unsigned type, unsigned nElem, const void
|
||||
}
|
||||
|
||||
if ( this->sendQue.flushThreshold ( postcnt + 16u ) ) {
|
||||
this->flushToWire ( true );
|
||||
this->threadContextSensitiveFlushToWire ( true );
|
||||
}
|
||||
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
@@ -1484,7 +1498,7 @@ int tcpiiu::writeNotifyRequest ( nciu &chan, cacNotify ¬ify, unsigned type,
|
||||
}
|
||||
|
||||
if ( this->sendQue.flushThreshold ( postcnt + 16u ) ) {
|
||||
this->flushToWire ( true );
|
||||
this->threadContextSensitiveFlushToWire ( true );
|
||||
}
|
||||
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
@@ -1532,7 +1546,7 @@ int tcpiiu::readCopyRequest ( nciu &chan, unsigned type, unsigned nElem, void *p
|
||||
}
|
||||
|
||||
if ( this->sendQue.flushThreshold ( 16u ) ) {
|
||||
this->flushToWire ( true );
|
||||
this->threadContextSensitiveFlushToWire ( true );
|
||||
}
|
||||
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
@@ -1543,8 +1557,9 @@ int tcpiiu::readCopyRequest ( nciu &chan, unsigned type, unsigned nElem, void *p
|
||||
status = ECA_DISCONNCHID;
|
||||
}
|
||||
else {
|
||||
netReadCopyIO *pIO = new netReadCopyIO ( chan, type, nElem, pValue,
|
||||
this->pCAC ()->readSequenceOfOutstandingIO () );
|
||||
unsigned seqNo = this->pCAC ()->readSequenceOfOutstandingIO ();
|
||||
netReadCopyIO *pIO = new netReadCopyIO ( chan, type,
|
||||
nElem, pValue, seqNo );
|
||||
if ( ! pIO ) {
|
||||
status = ECA_ALLOCMEM;
|
||||
}
|
||||
@@ -1575,7 +1590,7 @@ int tcpiiu::readNotifyRequest ( nciu &chan, cacNotify ¬ify,
|
||||
}
|
||||
|
||||
if ( this->sendQue.flushThreshold ( 16u ) ) {
|
||||
this->flushToWire ( true );
|
||||
this->threadContextSensitiveFlushToWire ( true );
|
||||
}
|
||||
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
@@ -1668,7 +1683,7 @@ int tcpiiu::clearChannelRequest ( nciu &chan )
|
||||
int status;
|
||||
|
||||
if ( this->sendQue.flushThreshold ( 16u ) ) {
|
||||
this->flushToWire ( true );
|
||||
this->threadContextSensitiveFlushToWire ( true );
|
||||
}
|
||||
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
@@ -1707,7 +1722,7 @@ int tcpiiu::subscriptionRequest ( netSubscription &subscr, bool userThread )
|
||||
|
||||
if ( this->sendQue.flushThreshold ( 32u ) ) {
|
||||
if ( userThread ) {
|
||||
this->flushToWire ( true );
|
||||
this->threadContextSensitiveFlushToWire ( true );
|
||||
}
|
||||
else {
|
||||
this->flush ();
|
||||
@@ -1748,7 +1763,7 @@ void tcpiiu::subscriptionCancelRequest ( netSubscription &subscr, bool userThrea
|
||||
{
|
||||
if ( this->sendQue.flushThreshold ( 16u ) ) {
|
||||
if ( userThread ) {
|
||||
this->flushToWire ( true );
|
||||
this->threadContextSensitiveFlushToWire ( true );
|
||||
}
|
||||
else {
|
||||
this->flush ();
|
||||
@@ -1775,10 +1790,8 @@ void tcpiiu::lastChannelDetachNotify ()
|
||||
this->cleanShutdown ();
|
||||
}
|
||||
|
||||
bool tcpiiu::flushToWire ( bool userThread )
|
||||
bool tcpiiu::threadContextSensitiveFlushToWire ( bool userThread )
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
// the recv thread is not permitted to flush as this
|
||||
// can result in a push / pull deadlock on the TCP pipe,
|
||||
// but in that case we still schedual the flush through
|
||||
@@ -1787,6 +1800,12 @@ bool tcpiiu::flushToWire ( bool userThread )
|
||||
this->flush ();
|
||||
return true;
|
||||
}
|
||||
return this->flushToWire ( userThread );
|
||||
}
|
||||
|
||||
bool tcpiiu::flushToWire ( bool userThread )
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
// enable callback processing prior to taking the flush lock
|
||||
if ( userThread ) {
|
||||
@@ -1984,13 +2003,43 @@ void tcpiiu::disconnectAllIO ( nciu &chan )
|
||||
}
|
||||
}
|
||||
|
||||
void tcpiiu::uninstallIO ( baseNMIU &io )
|
||||
//
|
||||
// care is taken to not hold the lock while deleting the
|
||||
// IO so that subscription delete request (sent by the
|
||||
// IO's destructor) do not deadlock
|
||||
//
|
||||
bool tcpiiu::destroyAllIO ( nciu &chan )
|
||||
{
|
||||
tsDLList < baseNMIU > eventQ;
|
||||
{
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
if ( chan.verifyIIU ( *this ) ) {
|
||||
while ( baseNMIU *pIO = eventQ.get () ) {
|
||||
this->ioTable.remove ( *pIO );
|
||||
eventQ.add ( *pIO );
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while ( baseNMIU *pIO = eventQ.get () ) {
|
||||
pIO->destroy ();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tcpiiu::uninstallIO ( baseNMIU &io )
|
||||
{
|
||||
epicsAutoMutex autoMutex ( this->mutex );
|
||||
if ( io.channel ().verifyConnected ( *this ) ) {
|
||||
if ( io.channel ().verifyIIU ( *this ) ) {
|
||||
this->ioTable.remove ( io );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
io.channel ().tcpiiuPrivateListOfIO::eventq.remove ( io );
|
||||
return true;
|
||||
}
|
||||
|
||||
double tcpiiu::beaconPeriod () const
|
||||
|
||||
Reference in New Issue
Block a user