some initial steps towards fre list based memory management
This commit is contained in:
@@ -39,7 +39,6 @@ LIBSRCS += casPVI.cc
|
||||
LIBSRCS += casChannel.cc
|
||||
LIBSRCS += casChannelI.cc
|
||||
LIBSRCS += casPVListChan.cc
|
||||
LIBSRCS += casClientMon.cc
|
||||
LIBSRCS += casChanDelEv.cc
|
||||
LIBSRCS += casAsyncIOI.cc
|
||||
LIBSRCS += casAsyncReadIO.cc
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
LOCAL int parseDirectoryFile (const char *pFileName);
|
||||
LOCAL int parseDirectoryFP (FILE *pf, const char *pFileName);
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE (~0ul)
|
||||
#endif
|
||||
@@ -152,7 +148,7 @@ LOCAL int parseDirectoryFP (FILE *pf, const char *pFileName)
|
||||
int nPV=0;
|
||||
|
||||
ipa.sin_family = AF_INET;
|
||||
while (TRUE) {
|
||||
while ( true ) {
|
||||
|
||||
//
|
||||
// parse the PV name entry from the file
|
||||
|
||||
@@ -175,7 +175,7 @@ caStatus exVectorPV::updateValue(smartConstGDDPointer pValueIn)
|
||||
//
|
||||
// Check bounds of incoming request
|
||||
// (and see if we are replacing all elements -
|
||||
// replaceOk==TRUE)
|
||||
// replaceOk==true)
|
||||
//
|
||||
// Perhaps much of this is unnecessary since the
|
||||
// server lib checks the bounds of all requests
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
//
|
||||
// caServer::caServer()
|
||||
//
|
||||
epicsShareFunc caServer::caServer ()
|
||||
caServer::caServer ()
|
||||
{
|
||||
static bool init = false;
|
||||
|
||||
if (!init) {
|
||||
if ( ! init ) {
|
||||
gddMakeMapDBR(gddApplicationTypeTable::app_table);
|
||||
init = true;
|
||||
}
|
||||
@@ -39,7 +39,7 @@ epicsShareFunc caServer::caServer ()
|
||||
//
|
||||
// caServer::~caServer()
|
||||
//
|
||||
epicsShareFunc caServer::~caServer()
|
||||
caServer::~caServer()
|
||||
{
|
||||
if (this->pCAS) {
|
||||
delete this->pCAS;
|
||||
@@ -50,7 +50,7 @@ epicsShareFunc caServer::~caServer()
|
||||
//
|
||||
// caServer::pvExistTest()
|
||||
//
|
||||
epicsShareFunc pvExistReturn caServer::pvExistTest (const casCtx &, const char *)
|
||||
pvExistReturn caServer::pvExistTest (const casCtx &, const char *)
|
||||
{
|
||||
return pverDoesNotExistHere;
|
||||
}
|
||||
@@ -58,7 +58,7 @@ epicsShareFunc pvExistReturn caServer::pvExistTest (const casCtx &, const char *
|
||||
//
|
||||
// caServer::createPV()
|
||||
//
|
||||
epicsShareFunc pvCreateReturn caServer::createPV (const casCtx &, const char *)
|
||||
pvCreateReturn caServer::createPV (const casCtx &, const char *)
|
||||
{
|
||||
return S_casApp_pvNotFound;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ epicsShareFunc pvCreateReturn caServer::createPV (const casCtx &, const char *)
|
||||
//
|
||||
// caServer::pvAttach()
|
||||
//
|
||||
epicsShareFunc pvAttachReturn caServer::pvAttach (const casCtx &ctx, const char *pAliasName)
|
||||
pvAttachReturn caServer::pvAttach (const casCtx &ctx, const char *pAliasName)
|
||||
{
|
||||
//
|
||||
// remain backwards compatible (call deprecated routine)
|
||||
@@ -77,7 +77,7 @@ epicsShareFunc pvAttachReturn caServer::pvAttach (const casCtx &ctx, const char
|
||||
//
|
||||
// caServer::registerEvent()
|
||||
//
|
||||
epicsShareFunc casEventMask caServer::registerEvent (const char *pName) // X aCC 361
|
||||
casEventMask caServer::registerEvent (const char *pName) // X aCC 361
|
||||
{
|
||||
if (this->pCAS) {
|
||||
return this->pCAS->registerEvent(pName);
|
||||
@@ -92,7 +92,7 @@ epicsShareFunc casEventMask caServer::registerEvent (const char *pName) // X aCC
|
||||
//
|
||||
// caServer::show()
|
||||
//
|
||||
epicsShareFunc void caServer::show(unsigned level) const
|
||||
void caServer::show(unsigned level) const
|
||||
{
|
||||
if (this->pCAS) {
|
||||
this->pCAS->show(level);
|
||||
@@ -105,7 +105,7 @@ epicsShareFunc void caServer::show(unsigned level) const
|
||||
//
|
||||
// caServer::setDebugLevel()
|
||||
//
|
||||
epicsShareFunc void caServer::setDebugLevel (unsigned level)
|
||||
void caServer::setDebugLevel (unsigned level)
|
||||
{
|
||||
if (pCAS) {
|
||||
this->pCAS->setDebugLevel(level);
|
||||
@@ -118,7 +118,7 @@ epicsShareFunc void caServer::setDebugLevel (unsigned level)
|
||||
//
|
||||
// caServer::getDebugLevel()
|
||||
//
|
||||
epicsShareFunc unsigned caServer::getDebugLevel () const // X aCC 361
|
||||
unsigned caServer::getDebugLevel () const // X aCC 361
|
||||
{
|
||||
if (pCAS) {
|
||||
return this->pCAS->getDebugLevel();
|
||||
@@ -132,7 +132,7 @@ epicsShareFunc unsigned caServer::getDebugLevel () const // X aCC 361
|
||||
//
|
||||
// caServer::valueEventMask ()
|
||||
//
|
||||
epicsShareFunc casEventMask caServer::valueEventMask () const // X aCC 361
|
||||
casEventMask caServer::valueEventMask () const // X aCC 361
|
||||
{
|
||||
if (pCAS) {
|
||||
return this->pCAS->valueEventMask();
|
||||
@@ -146,7 +146,7 @@ epicsShareFunc casEventMask caServer::valueEventMask () const // X aCC 361
|
||||
//
|
||||
// caServer::logEventMask ()
|
||||
//
|
||||
epicsShareFunc casEventMask caServer::logEventMask () const // X aCC 361
|
||||
casEventMask caServer::logEventMask () const // X aCC 361
|
||||
{
|
||||
if (pCAS) {
|
||||
return this->pCAS->logEventMask();
|
||||
@@ -160,7 +160,7 @@ epicsShareFunc casEventMask caServer::logEventMask () const // X aCC 361
|
||||
//
|
||||
// caServer::alarmEventMask ()
|
||||
//
|
||||
epicsShareFunc casEventMask caServer::alarmEventMask () const // X aCC 361
|
||||
casEventMask caServer::alarmEventMask () const // X aCC 361
|
||||
{
|
||||
if (pCAS) {
|
||||
return this->pCAS->alarmEventMask();
|
||||
@@ -182,7 +182,7 @@ class epicsTimer & caServer::createTimer ()
|
||||
//
|
||||
// caServer::subscriptionEventsProcessed
|
||||
//
|
||||
epicsShareFunc unsigned caServer::subscriptionEventsProcessed () const // X aCC 361
|
||||
unsigned caServer::subscriptionEventsProcessed () const // X aCC 361
|
||||
{
|
||||
if ( pCAS ) {
|
||||
return this->pCAS->subscriptionEventsProcessed();
|
||||
@@ -195,7 +195,7 @@ epicsShareFunc unsigned caServer::subscriptionEventsProcessed () const // X aCC
|
||||
//
|
||||
// caServer::subscriptionEventsPosted
|
||||
//
|
||||
epicsShareFunc unsigned caServer::subscriptionEventsPosted () const // X aCC 361
|
||||
unsigned caServer::subscriptionEventsPosted () const // X aCC 361
|
||||
{
|
||||
if ( pCAS ) {
|
||||
return this->pCAS->subscriptionEventsPosted ();
|
||||
@@ -205,7 +205,7 @@ epicsShareFunc unsigned caServer::subscriptionEventsPosted () const // X aCC 361
|
||||
}
|
||||
}
|
||||
|
||||
epicsShareFunc void caServer::generateBeaconAnomaly ()
|
||||
void caServer::generateBeaconAnomaly ()
|
||||
{
|
||||
if ( pCAS ) {
|
||||
this->pCAS->generateBeaconAnomaly ();
|
||||
|
||||
@@ -169,6 +169,38 @@ inline void caServerI::unlock () const
|
||||
this->mutex.unlock ();
|
||||
}
|
||||
|
||||
inline casMonEvent & caServerI::casMonEventFactory ( casMonitor & monitor,
|
||||
const smartConstGDDPointer & pNewValue )
|
||||
{
|
||||
return * new ( this->casMonEventFreeList ) casMonEvent ( monitor, pNewValue );
|
||||
}
|
||||
|
||||
inline void caServerI::casMonEventDestroy ( casMonEvent & monEvent )
|
||||
{
|
||||
monEvent.~casMonEvent ();
|
||||
this->casMonEventFreeList.release ( & monEvent );
|
||||
}
|
||||
|
||||
inline casMonitor & caServerI::casMonitorFactory (
|
||||
casChannelI & chan, caResId clientId,
|
||||
const unsigned long count, const unsigned type,
|
||||
const casEventMask & mask, epicsMutex & mutex,
|
||||
casMonitorCallbackInterface & cb )
|
||||
{
|
||||
casMonitor * pMon =
|
||||
new ( this->casMonitorFreeList ) casMonitor
|
||||
( clientId, chan, count, type, mask, mutex, cb );
|
||||
this->installItem ( *pMon );
|
||||
return *pMon;
|
||||
}
|
||||
|
||||
inline void caServerI::casMonitorDestroy ( casMonitor & cm )
|
||||
{
|
||||
casRes * pRes = this->removeItem ( cm );
|
||||
assert ( & cm == ( casMonitor * ) pRes );
|
||||
cm.~casMonitor ();
|
||||
this->casMonitorFreeList.release ( & cm );
|
||||
}
|
||||
|
||||
#endif // caServerIIL_h
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ casAsyncIOI::casAsyncIOI ( const casCtx & ctx ) :
|
||||
//
|
||||
casAsyncIOI::~casAsyncIOI()
|
||||
{
|
||||
if (!this->serverDelete) {
|
||||
if ( ! this->serverDelete ) {
|
||||
fprintf(stderr,
|
||||
"WARNING: An async IO operation was deleted prematurely\n");
|
||||
fprintf(stderr,
|
||||
@@ -90,8 +90,8 @@ casAsyncIOI::~casAsyncIOI()
|
||||
// pulls itself out of the event queue
|
||||
// if it is installed there
|
||||
//
|
||||
if (this->inTheEventQueue) {
|
||||
this->client.casEventSys::removeFromEventQueue(*this);
|
||||
if ( this->inTheEventQueue ) {
|
||||
this->client.removeFromEventQueue ( *this );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ casAsyncIOI::~casAsyncIOI()
|
||||
// casAsyncIOI::cbFunc()
|
||||
// (called when IO completion event reaches top of event queue)
|
||||
//
|
||||
caStatus casAsyncIOI::cbFunc(class casEventSys &)
|
||||
caStatus casAsyncIOI::cbFunc ( casCoreClient & )
|
||||
{
|
||||
//
|
||||
// Use the client's lock here (which is the same as the
|
||||
@@ -108,7 +108,7 @@ caStatus casAsyncIOI::cbFunc(class casEventSys &)
|
||||
//
|
||||
epicsGuard < casCoreClient > guard ( this->client );
|
||||
|
||||
this->inTheEventQueue = FALSE;
|
||||
this->inTheEventQueue = false;
|
||||
|
||||
caStatus status = this->cbFuncAsyncIO();
|
||||
|
||||
@@ -116,14 +116,14 @@ caStatus casAsyncIOI::cbFunc(class casEventSys &)
|
||||
//
|
||||
// causes this op to be pushed back on the queue
|
||||
//
|
||||
this->inTheEventQueue = TRUE;
|
||||
this->inTheEventQueue = true;
|
||||
return status;
|
||||
}
|
||||
else if (status != S_cas_success) {
|
||||
errMessage (status, "Asynch IO completion failed");
|
||||
}
|
||||
|
||||
this->ioComplete = TRUE;
|
||||
this->ioComplete = true;
|
||||
|
||||
//
|
||||
// dont use "this" after potentially destroying the
|
||||
@@ -134,6 +134,11 @@ caStatus casAsyncIOI::cbFunc(class casEventSys &)
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
void casAsyncIOI::eventSysDestroyNotify ( casCoreClient & )
|
||||
{
|
||||
this->serverDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// casAsyncIOI::postIOCompletionI()
|
||||
//
|
||||
@@ -145,7 +150,7 @@ caStatus casAsyncIOI::postIOCompletionI()
|
||||
// and then it called postIOCompletion() on this object
|
||||
// when it was currently not in use by the server.
|
||||
//
|
||||
if (this->serverDelete) {
|
||||
if ( this->serverDelete ) {
|
||||
return S_cas_redundantPost;
|
||||
}
|
||||
|
||||
@@ -165,21 +170,21 @@ caStatus casAsyncIOI::postIOCompletionI()
|
||||
//
|
||||
// verify that they dont post completion more than once
|
||||
//
|
||||
if (this->posted) {
|
||||
if ( this->posted ) {
|
||||
return S_cas_redundantPost;
|
||||
}
|
||||
|
||||
//
|
||||
// dont call the server tool's cancel() when this object deletes
|
||||
//
|
||||
this->posted = TRUE;
|
||||
this->posted = true;
|
||||
|
||||
//
|
||||
// place this event in the event queue
|
||||
// (this also signals the event consumer)
|
||||
//
|
||||
this->inTheEventQueue = TRUE;
|
||||
this->client.casEventSys::addToEventQueue(*this);
|
||||
this->inTheEventQueue = true;
|
||||
this->client.addToEventQueue ( *this );
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
@@ -196,7 +201,7 @@ caServer *casAsyncIOI::getCAS() const
|
||||
//
|
||||
// casAsyncIOI::readOP()
|
||||
//
|
||||
epicsShareFunc bool casAsyncIOI::readOP() const
|
||||
bool casAsyncIOI::readOP() const
|
||||
{
|
||||
//
|
||||
// not a read op
|
||||
@@ -230,7 +235,7 @@ void casAsyncIOI::serverDestroyIfReadOP()
|
||||
//
|
||||
void casAsyncIOI::serverDestroy ()
|
||||
{
|
||||
this->serverDelete = TRUE;
|
||||
this->serverDelete = true;
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ caStatus casAsyncPVAttachIO::postIOCompletion ( const pvAttachReturn & retValIn
|
||||
// casAsyncPVAttachIO::cbFuncAsyncIO()
|
||||
// (called when IO completion event reaches top of event queue)
|
||||
//
|
||||
epicsShareFunc caStatus casAsyncPVAttachIO::cbFuncAsyncIO()
|
||||
caStatus casAsyncPVAttachIO::cbFuncAsyncIO()
|
||||
{
|
||||
caStatus status;
|
||||
|
||||
@@ -90,7 +90,7 @@ casAsyncPVCreateIO::casAsyncPVCreateIO ( const casCtx & ctx ) :
|
||||
//
|
||||
// deprecated
|
||||
//
|
||||
epicsShareFunc casAsyncPVCreateIO::~casAsyncPVCreateIO ()
|
||||
casAsyncPVCreateIO::~casAsyncPVCreateIO ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ caStatus casAsyncPVExistIO::postIOCompletion (const pvExistReturn &retValIn)
|
||||
// casAsyncPVExistIO::cbFuncAsyncIO()
|
||||
// (called when IO completion event reaches top of event queue)
|
||||
//
|
||||
epicsShareFunc caStatus casAsyncPVExistIO::cbFuncAsyncIO()
|
||||
caStatus casAsyncPVExistIO::cbFuncAsyncIO()
|
||||
{
|
||||
caStatus status;
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ caStatus casAsyncReadIO::postIOCompletion (caStatus completionStatusIn,
|
||||
//
|
||||
// casAsyncReadIO::readOP()
|
||||
//
|
||||
epicsShareFunc bool casAsyncReadIO::readOP() const
|
||||
bool casAsyncReadIO::readOP() const
|
||||
{
|
||||
return true; // it is a read op
|
||||
}
|
||||
@@ -68,7 +68,7 @@ epicsShareFunc bool casAsyncReadIO::readOP() const
|
||||
// casAsyncReadIO::cbFuncAsyncIO()
|
||||
// (called when IO completion event reaches top of event queue)
|
||||
//
|
||||
epicsShareFunc caStatus casAsyncReadIO::cbFuncAsyncIO()
|
||||
caStatus casAsyncReadIO::cbFuncAsyncIO()
|
||||
{
|
||||
caStatus status;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ caStatus casAsyncWriteIO::postIOCompletion ( caStatus completionStatusIn )
|
||||
// casAsyncWriteIO::cbFuncAsyncIO()
|
||||
// (called when IO completion event reaches top of event queue)
|
||||
//
|
||||
epicsShareFunc caStatus casAsyncWriteIO::cbFuncAsyncIO ()
|
||||
caStatus casAsyncWriteIO::cbFuncAsyncIO ()
|
||||
{
|
||||
caStatus status;
|
||||
|
||||
|
||||
@@ -29,13 +29,18 @@ casChanDelEv::~casChanDelEv()
|
||||
//
|
||||
// casChanDelEv()
|
||||
//
|
||||
caStatus casChanDelEv::cbFunc(casEventSys &eSys)
|
||||
caStatus casChanDelEv::cbFunc ( casCoreClient & client )
|
||||
{
|
||||
caStatus status;
|
||||
status = eSys.disconnectChan (this->id);
|
||||
if (status == S_cas_success) {
|
||||
status = client.disconnectChan ( this->id );
|
||||
if ( status == S_cas_success ) {
|
||||
delete this;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void casChanDelEv::eventSysDestroyNotify ( casCoreClient & )
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
// casChannel::casChannel()
|
||||
//
|
||||
epicsShareFunc casChannel::casChannel(const casCtx &ctx) :
|
||||
casChannel::casChannel(const casCtx &ctx) :
|
||||
casPVListChan (ctx)
|
||||
{
|
||||
}
|
||||
@@ -30,14 +30,14 @@ epicsShareFunc casChannel::casChannel(const casCtx &ctx) :
|
||||
//
|
||||
// casChannel::~casChannel()
|
||||
//
|
||||
epicsShareFunc casChannel::~casChannel()
|
||||
casChannel::~casChannel()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// casChannel::getPV()
|
||||
//
|
||||
epicsShareFunc casPV *casChannel::getPV() // X aCC 361
|
||||
casPV *casChannel::getPV() // X aCC 361
|
||||
{
|
||||
casPVI *pPVI = &this->casChannelI::getPVI();
|
||||
|
||||
@@ -52,7 +52,7 @@ epicsShareFunc casPV *casChannel::getPV() // X aCC 361
|
||||
//
|
||||
// casChannel::setOwner()
|
||||
//
|
||||
epicsShareFunc void casChannel::setOwner(const char * const /* pUserName */,
|
||||
void casChannel::setOwner(const char * const /* pUserName */,
|
||||
const char * const /* pHostName */)
|
||||
{
|
||||
//
|
||||
@@ -63,7 +63,7 @@ epicsShareFunc void casChannel::setOwner(const char * const /* pUserName */,
|
||||
//
|
||||
// casChannel::readAccess()
|
||||
//
|
||||
epicsShareFunc bool casChannel::readAccess () const
|
||||
bool casChannel::readAccess () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -71,16 +71,15 @@ epicsShareFunc bool casChannel::readAccess () const
|
||||
//
|
||||
// casChannel::writeAccess()
|
||||
//
|
||||
epicsShareFunc bool casChannel::writeAccess() const
|
||||
bool casChannel::writeAccess() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casChannel::confirmationRequested()
|
||||
//
|
||||
epicsShareFunc bool casChannel::confirmationRequested() const
|
||||
bool casChannel::confirmationRequested() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -88,7 +87,7 @@ epicsShareFunc bool casChannel::confirmationRequested() const
|
||||
//
|
||||
// casChannel::show()
|
||||
//
|
||||
epicsShareFunc void casChannel::show(unsigned level) const
|
||||
void casChannel::show(unsigned level) const
|
||||
{
|
||||
if (level>2u) {
|
||||
printf("casChannel: read access = %d\n",
|
||||
@@ -103,7 +102,7 @@ epicsShareFunc void casChannel::show(unsigned level) const
|
||||
//
|
||||
// casChannel::destroy()
|
||||
//
|
||||
epicsShareFunc void casChannel::destroy()
|
||||
void casChannel::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
@@ -111,7 +110,7 @@ epicsShareFunc void casChannel::destroy()
|
||||
//
|
||||
// casChannel::postAccessRightsEvent()
|
||||
//
|
||||
epicsShareFunc void casChannel::postAccessRightsEvent()
|
||||
void casChannel::postAccessRightsEvent()
|
||||
{
|
||||
this->casChannelI::postAccessRightsEvent();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ casChannelI::casChannelI ( const casCtx & ) :
|
||||
{
|
||||
}
|
||||
|
||||
void casChannelI::bindToClientI ( casCoreClient & client, casPVI & pv, caResId cidIn )
|
||||
void casChannelI::bindToClientI (
|
||||
casCoreClient & client, casPVI & pv, caResId cidIn )
|
||||
{
|
||||
this->pClient = & client;
|
||||
this->pPV = & pv;
|
||||
@@ -42,7 +43,8 @@ void casChannelI::bindToClientI ( casCoreClient & client, casPVI & pv, caResId c
|
||||
//
|
||||
casChannelI::~casChannelI()
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
epicsGuard < casCoreClient >
|
||||
guard ( * this->pClient );
|
||||
|
||||
//
|
||||
// cancel any pending asynchronous IO
|
||||
@@ -61,23 +63,16 @@ casChannelI::~casChannelI()
|
||||
//
|
||||
// cancel the monitors
|
||||
//
|
||||
tsDLIter <casMonitor> iterMon = this->monitorList.firstIter ();
|
||||
while ( iterMon.valid () ) {
|
||||
//
|
||||
// destructor removes from this list
|
||||
//
|
||||
tsDLIter <casMonitor> tmpMon = iterMon;
|
||||
++tmpMon;
|
||||
iterMon->destroy ();
|
||||
iterMon = tmpMon;
|
||||
while ( casMonitor * pMon = this->monitorList.get () ) {
|
||||
this->getClient().destroyMonitor ( *pMon );
|
||||
}
|
||||
|
||||
this->pClient->removeChannel(*this);
|
||||
this->pClient->removeChannel ( *this );
|
||||
|
||||
//
|
||||
// force PV delete if this is the last channel attached
|
||||
//
|
||||
this->pPV->deleteSignal();
|
||||
this->pPV->deleteSignal ();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -109,7 +104,8 @@ void casChannelI::show ( unsigned level ) const
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
|
||||
tsDLIterConst <casMonitor> iter = this->monitorList.firstIter ();
|
||||
tsDLIterConst < casMonitor > iter =
|
||||
this->monitorList.firstIter ();
|
||||
if ( iter.valid () ) {
|
||||
printf("List of CA events (monitors) for \"%s\".\n",
|
||||
this->pPV->getName());
|
||||
@@ -127,17 +123,22 @@ void casChannelI::show ( unsigned level ) const
|
||||
//
|
||||
// access rights event call back
|
||||
//
|
||||
caStatus casChannelI::cbFunc(casEventSys &)
|
||||
caStatus casChannelI::cbFunc ( casCoreClient & )
|
||||
{
|
||||
caStatus stat;
|
||||
|
||||
stat = this->pClient->accessRightsResponse(this);
|
||||
if (stat==S_cas_success) {
|
||||
stat = this->pClient->accessRightsResponse ( this );
|
||||
if ( stat == S_cas_success ) {
|
||||
this->accessRightsEvPending = false;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
void casChannelI::eventSysDestroyNotify ( casCoreClient & )
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
//
|
||||
// casChannelI::resourceType()
|
||||
//
|
||||
@@ -152,7 +153,7 @@ casResType casChannelI::resourceType() const
|
||||
// this noop version is safe to be called indirectly
|
||||
// from casChannelI::~casChannelI
|
||||
//
|
||||
epicsShareFunc void casChannelI::destroy()
|
||||
void casChannelI::destroy()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -161,13 +162,13 @@ void casChannelI::destroyClientNotify ()
|
||||
casChanDelEv *pCDEV;
|
||||
caStatus status;
|
||||
|
||||
pCDEV = new casChanDelEv (this->getCID());
|
||||
if (pCDEV) {
|
||||
this->pClient->casEventSys::addToEventQueue (*pCDEV);
|
||||
pCDEV = new casChanDelEv ( this->getCID() );
|
||||
if ( pCDEV ) {
|
||||
this->pClient->addToEventQueue ( *pCDEV );
|
||||
}
|
||||
else {
|
||||
status = this->pClient->disconnectChan (this->getCID());
|
||||
if (status) {
|
||||
status = this->pClient->disconnectChan ( this->getCID () );
|
||||
if ( status ) {
|
||||
//
|
||||
// At this point there is no space in pool
|
||||
// for a tiny object and there is also
|
||||
@@ -180,21 +181,20 @@ void casChannelI::destroyClientNotify ()
|
||||
// will result in bugs because no doubt this
|
||||
// could be called by a client member function.
|
||||
//
|
||||
this->pClient->setDestroyPending();
|
||||
this->pClient->setDestroyPending ();
|
||||
}
|
||||
}
|
||||
this->destroy();
|
||||
this->destroy ();
|
||||
}
|
||||
|
||||
//
|
||||
// casChannelI::findMonitor
|
||||
// (it is reasonable to do a linear search here because
|
||||
// sane clients will require only one or two monitors
|
||||
// per channel)
|
||||
//
|
||||
tsDLIter <casMonitor> casChannelI::findMonitor (const caResId clientIdIn)
|
||||
bool casChannelI::unistallMonitor ( ca_uint32_t clientIdIn )
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
//
|
||||
// (it is reasonable to do a linear search here because
|
||||
// sane clients will require only one or two monitors
|
||||
// per channel)
|
||||
//
|
||||
tsDLIter <casMonitor> iter = this->monitorList.firstIter ();
|
||||
while ( iter.valid () ) {
|
||||
if ( clientIdIn == iter->getClientId () ) {
|
||||
@@ -202,6 +202,26 @@ tsDLIter <casMonitor> casChannelI::findMonitor (const caResId clientIdIn)
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
return iter;
|
||||
if ( ! iter.valid () ) {
|
||||
return false;
|
||||
}
|
||||
this->monitorList.remove ( *iter.pointer() );
|
||||
this->getClient().destroyMonitor ( *iter.pointer() );
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// casChannelI::installMonitor ()
|
||||
//
|
||||
void casChannelI::installMonitor (
|
||||
caResId clientId,
|
||||
const unsigned long count,
|
||||
const unsigned type,
|
||||
const casEventMask & mask )
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
casMonitor & mon = this->pClient->monitorFactory (
|
||||
*this, clientId, count, type, mask );
|
||||
this->monitorList.add ( mon );
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
//
|
||||
inline void casChannelI::postEvent (const casEventMask &select, const gdd &event)
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
epicsGuard < casCoreClient > guard ( *this->pClient );
|
||||
tsDLIter<casMonitor> iter = this->monitorList.firstIter ();
|
||||
while ( iter.valid () ) {
|
||||
iter->post (select, event);
|
||||
@@ -35,30 +35,6 @@ inline void casChannelI::postEvent (const casEventMask &select, const gdd &event
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casChannelI::deleteMonitor()
|
||||
//
|
||||
inline void casChannelI::deleteMonitor(casMonitor &mon)
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
this->getClient().casEventSys::removeMonitor();
|
||||
this->monitorList.remove(mon);
|
||||
casRes *pRes = this->getClient().getCAS().removeItem(mon);
|
||||
assert ( & mon == (casMonitor *) pRes );
|
||||
}
|
||||
|
||||
//
|
||||
// casChannelI::addMonitor()
|
||||
//
|
||||
inline void casChannelI::addMonitor(casMonitor &mon)
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
this->monitorList.add(mon);
|
||||
this->getClient().getCAS().installItem(mon);
|
||||
this->getClient().casEventSys::installMonitor();
|
||||
}
|
||||
|
||||
//
|
||||
// casChannelI::destroyNoClientNotify()
|
||||
//
|
||||
@@ -78,16 +54,16 @@ inline void casChannelI::destroyNoClientNotify()
|
||||
//
|
||||
inline void casChannelI::installAsyncIO(casAsyncIOI &io)
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
epicsGuard < casCoreClient > guard ( *this->pClient );
|
||||
this->ioInProgList.add(io);
|
||||
}
|
||||
|
||||
//
|
||||
// casChannelI::removeAsyncIO()
|
||||
//
|
||||
inline void casChannelI::removeAsyncIO(casAsyncIOI &io)
|
||||
inline void casChannelI::removeAsyncIO ( casAsyncIOI & io )
|
||||
{
|
||||
epicsGuard < casCoreClient > guard ( * this->pClient );
|
||||
epicsGuard < casCoreClient > guard ( *this->pClient );
|
||||
this->ioInProgList.remove(io);
|
||||
this->pPV->unregisterIO();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ static const caHdr nill_msg = {0u,0u,0u,0u,0u,0u};
|
||||
//
|
||||
// static declartions for class casClient
|
||||
//
|
||||
int casClient::msgHandlersInit;
|
||||
bool casClient::msgHandlersInit;
|
||||
casClient::pCASMsgHandler casClient::msgHandlers[CA_PROTO_LAST_CMMD+1u];
|
||||
|
||||
//
|
||||
@@ -94,7 +94,7 @@ void casClient::loadProtoJumpTable()
|
||||
//
|
||||
// Load the static protocol handler tables
|
||||
//
|
||||
if (casClient::msgHandlersInit) {
|
||||
if ( casClient::msgHandlersInit ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ void casClient::loadProtoJumpTable()
|
||||
casClient::msgHandlers[CA_PROTO_CLAIM_CIU_FAILED] =
|
||||
&casClient::uknownMessageAction;
|
||||
|
||||
casClient::msgHandlersInit = TRUE;
|
||||
casClient::msgHandlersInit = true;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -182,123 +182,148 @@ void casClient::show (unsigned level) const
|
||||
//
|
||||
caStatus casClient::processMsg ()
|
||||
{
|
||||
// drain message that does not fit
|
||||
if ( this->incommingBytesToDrain ) {
|
||||
unsigned bytesLeft = this->in.bytesPresent();
|
||||
if ( bytesLeft < this->incommingBytesToDrain ) {
|
||||
this->in.removeMsg ( bytesLeft );
|
||||
this->incommingBytesToDrain -= bytesLeft;
|
||||
return S_cas_success;
|
||||
}
|
||||
else {
|
||||
this->in.removeMsg ( this->incommingBytesToDrain );
|
||||
this->incommingBytesToDrain = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// process any messages in the in buffer
|
||||
//
|
||||
int status = S_cas_success;
|
||||
|
||||
unsigned bytesLeft;
|
||||
while ( ( bytesLeft = this->in.bytesPresent() ) ) {
|
||||
caHdrLargeArray msgTmp;
|
||||
unsigned msgSize;
|
||||
ca_uint32_t hdrSize;
|
||||
char * rawMP;
|
||||
{
|
||||
//
|
||||
// copy as raw bytes in order to avoid
|
||||
// alignment problems
|
||||
//
|
||||
caHdr smallHdr;
|
||||
if ( bytesLeft < sizeof ( smallHdr ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
rawMP = this->in.msgPtr ();
|
||||
memcpy ( & smallHdr, rawMP, sizeof ( smallHdr ) );
|
||||
|
||||
ca_uint32_t payloadSize = epicsNTOH16 ( smallHdr.m_postsize );
|
||||
ca_uint32_t nElem = epicsNTOH16 ( smallHdr.m_count );
|
||||
if ( payloadSize != 0xffff && nElem != 0xffff ) {
|
||||
hdrSize = sizeof ( smallHdr );
|
||||
try {
|
||||
// drain message that does not fit
|
||||
if ( this->incommingBytesToDrain ) {
|
||||
unsigned bytesLeft = this->in.bytesPresent();
|
||||
if ( bytesLeft < this->incommingBytesToDrain ) {
|
||||
this->in.removeMsg ( bytesLeft );
|
||||
this->incommingBytesToDrain -= bytesLeft;
|
||||
return S_cas_success;
|
||||
}
|
||||
else {
|
||||
ca_uint32_t LWA[2];
|
||||
hdrSize = sizeof ( smallHdr ) + sizeof ( LWA );
|
||||
if ( bytesLeft < hdrSize ) {
|
||||
this->in.removeMsg ( this->incommingBytesToDrain );
|
||||
this->incommingBytesToDrain = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// process any messages in the in buffer
|
||||
//
|
||||
|
||||
unsigned bytesLeft;
|
||||
while ( ( bytesLeft = this->in.bytesPresent() ) ) {
|
||||
caHdrLargeArray msgTmp;
|
||||
unsigned msgSize;
|
||||
ca_uint32_t hdrSize;
|
||||
char * rawMP;
|
||||
{
|
||||
//
|
||||
// copy as raw bytes in order to avoid
|
||||
// alignment problems
|
||||
//
|
||||
caHdr smallHdr;
|
||||
if ( bytesLeft < sizeof ( smallHdr ) ) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// copy as raw bytes in order to avoid
|
||||
// alignment problems
|
||||
//
|
||||
memcpy ( LWA, rawMP + sizeof ( caHdr ), sizeof( LWA ) );
|
||||
payloadSize = epicsNTOH32 ( LWA[0] );
|
||||
nElem = epicsNTOH32 ( LWA[1] );
|
||||
}
|
||||
|
||||
msgTmp.m_cmmd = epicsNTOH16 ( smallHdr.m_cmmd );
|
||||
msgTmp.m_postsize = payloadSize;
|
||||
msgTmp.m_dataType = epicsNTOH16 ( smallHdr.m_dataType );
|
||||
msgTmp.m_count = nElem;
|
||||
msgTmp.m_cid = epicsNTOH32 ( smallHdr.m_cid );
|
||||
msgTmp.m_available = epicsNTOH32 ( smallHdr.m_available );
|
||||
rawMP = this->in.msgPtr ();
|
||||
memcpy ( & smallHdr, rawMP, sizeof ( smallHdr ) );
|
||||
|
||||
|
||||
msgSize = hdrSize + payloadSize;
|
||||
if ( bytesLeft < msgSize ) {
|
||||
if ( msgSize > this->in.bufferSize() ) {
|
||||
this->in.expandBuffer ();
|
||||
// msg to large - set up message drain
|
||||
if ( msgSize > this->in.bufferSize() ) {
|
||||
this->dumpMsg ( & msgTmp, 0,
|
||||
"The client requested transfer is greater than available "
|
||||
"memory in server or EPICS_CA_MAX_ARRAY_BYTES\n" );
|
||||
status = this->sendErr ( & msgTmp, ECA_TOLARGE,
|
||||
"request didnt fit within the CA server's message buffer" );
|
||||
this->in.removeMsg ( bytesLeft );
|
||||
this->incommingBytesToDrain = msgSize - bytesLeft;
|
||||
}
|
||||
ca_uint32_t payloadSize = epicsNTOH16 ( smallHdr.m_postsize );
|
||||
ca_uint32_t nElem = epicsNTOH16 ( smallHdr.m_count );
|
||||
if ( payloadSize != 0xffff && nElem != 0xffff ) {
|
||||
hdrSize = sizeof ( smallHdr );
|
||||
}
|
||||
break;
|
||||
else {
|
||||
ca_uint32_t LWA[2];
|
||||
hdrSize = sizeof ( smallHdr ) + sizeof ( LWA );
|
||||
if ( bytesLeft < hdrSize ) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// copy as raw bytes in order to avoid
|
||||
// alignment problems
|
||||
//
|
||||
memcpy ( LWA, rawMP + sizeof ( caHdr ), sizeof( LWA ) );
|
||||
payloadSize = epicsNTOH32 ( LWA[0] );
|
||||
nElem = epicsNTOH32 ( LWA[1] );
|
||||
}
|
||||
|
||||
msgTmp.m_cmmd = epicsNTOH16 ( smallHdr.m_cmmd );
|
||||
msgTmp.m_postsize = payloadSize;
|
||||
msgTmp.m_dataType = epicsNTOH16 ( smallHdr.m_dataType );
|
||||
msgTmp.m_count = nElem;
|
||||
msgTmp.m_cid = epicsNTOH32 ( smallHdr.m_cid );
|
||||
msgTmp.m_available = epicsNTOH32 ( smallHdr.m_available );
|
||||
|
||||
|
||||
msgSize = hdrSize + payloadSize;
|
||||
if ( bytesLeft < msgSize ) {
|
||||
if ( msgSize > this->in.bufferSize() ) {
|
||||
this->in.expandBuffer ();
|
||||
// msg to large - set up message drain
|
||||
if ( msgSize > this->in.bufferSize() ) {
|
||||
this->dumpMsg ( & msgTmp, 0,
|
||||
"The client requested transfer is greater than available "
|
||||
"memory in server or EPICS_CA_MAX_ARRAY_BYTES\n" );
|
||||
status = this->sendErr ( & msgTmp, ECA_TOLARGE,
|
||||
"request didnt fit within the CA server's message buffer" );
|
||||
this->in.removeMsg ( bytesLeft );
|
||||
this->incommingBytesToDrain = msgSize - bytesLeft;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this->ctx.setMsg ( msgTmp, rawMP + hdrSize );
|
||||
|
||||
if ( this->getCAS().getDebugLevel() > 2u ) {
|
||||
this->dumpMsg ( & msgTmp, rawMP + hdrSize, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this->ctx.setMsg ( msgTmp, rawMP + hdrSize );
|
||||
//
|
||||
// Reset the context to the default
|
||||
// (guarantees that previous message does not get mixed
|
||||
// up with the current message)
|
||||
//
|
||||
this->ctx.setChannel ( NULL );
|
||||
this->ctx.setPV ( NULL );
|
||||
|
||||
if ( this->getCAS().getDebugLevel() > 2u ) {
|
||||
this->dumpMsg ( & msgTmp, rawMP + hdrSize, 0 );
|
||||
//
|
||||
// Call protocol stub
|
||||
//
|
||||
pCASMsgHandler pHandler;
|
||||
if ( msgTmp.m_cmmd < NELEMENTS ( casClient::msgHandlers ) ) {
|
||||
pHandler = this->casClient::msgHandlers[msgTmp.m_cmmd];
|
||||
}
|
||||
else {
|
||||
pHandler = & casClient::uknownMessageAction;
|
||||
}
|
||||
status = ( this->*pHandler ) ();
|
||||
if ( status ) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Reset the context to the default
|
||||
// (guarantees that previous message does not get mixed
|
||||
// up with the current message)
|
||||
//
|
||||
this->ctx.setChannel ( NULL );
|
||||
this->ctx.setPV ( NULL );
|
||||
|
||||
//
|
||||
// Call protocol stub
|
||||
//
|
||||
pCASMsgHandler pHandler;
|
||||
if ( msgTmp.m_cmmd < NELEMENTS ( casClient::msgHandlers ) ) {
|
||||
pHandler = this->casClient::msgHandlers[msgTmp.m_cmmd];
|
||||
}
|
||||
else {
|
||||
pHandler = & casClient::uknownMessageAction;
|
||||
}
|
||||
status = ( this->*pHandler ) ();
|
||||
if ( status ) {
|
||||
break;
|
||||
}
|
||||
|
||||
this->in.removeMsg ( msgSize );
|
||||
}
|
||||
this->in.removeMsg ( msgSize );
|
||||
}
|
||||
}
|
||||
catch ( std::bad_alloc & ) {
|
||||
status = this->sendErr (
|
||||
this->ctx.getMsg(), ECA_ALLOCMEM,
|
||||
"inablility to allocate memory in "
|
||||
"the server disconnected client" );
|
||||
status = S_cas_noMemory;
|
||||
}
|
||||
catch ( std::exception & except ) {
|
||||
status = this->sendErr (
|
||||
this->ctx.getMsg(), ECA_INTERNAL,
|
||||
"C++ exception \"%s\" in server "
|
||||
"diconnected client",
|
||||
except.what () );
|
||||
status = S_cas_internal;
|
||||
}
|
||||
catch (...) {
|
||||
status = this->sendErr (
|
||||
this->ctx.getMsg(), ECA_INTERNAL,
|
||||
"unexpected C++ exception in server "
|
||||
"diconnected client" );
|
||||
status = S_cas_internal;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
|
||||
#include "server.h"
|
||||
|
||||
#include "casChannelIIL.h"
|
||||
|
||||
|
||||
//
|
||||
// casClientMon::casClientMon()
|
||||
//
|
||||
casClientMon::casClientMon(casChannelI &chan, caResId clientIdIn,
|
||||
const unsigned long count, const unsigned type,
|
||||
const casEventMask &maskIn, epicsMutex &mutexIn) :
|
||||
casMonitor(clientIdIn, chan, count, type, maskIn, mutexIn)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casClientMon::~casClientMon()
|
||||
//
|
||||
casClientMon::~casClientMon()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casClientMon::callBack()
|
||||
//
|
||||
caStatus casClientMon::callBack ( const smartConstGDDPointer &value )
|
||||
{
|
||||
casCoreClient & client = this->getChannel().getClient();
|
||||
caStatus status;
|
||||
caHdrLargeArray msg;
|
||||
|
||||
//
|
||||
// reconstruct the msg header
|
||||
//
|
||||
msg.m_cmmd = CA_PROTO_EVENT_ADD;
|
||||
msg.m_postsize = 0u;
|
||||
unsigned type = this->getType();
|
||||
assert ( type <= 0xffff );
|
||||
msg.m_dataType = static_cast <ca_uint16_t> ( type );
|
||||
unsigned long count = this->getCount();
|
||||
assert ( count <= 0xffffffff );
|
||||
msg.m_count = static_cast <ca_uint32_t> ( count );
|
||||
msg.m_cid = this->getChannel().getSID();
|
||||
msg.m_available = this->getClientId();
|
||||
|
||||
status = client.monitorResponse ( this->getChannel(),
|
||||
msg, value, S_cas_success );
|
||||
return status;
|
||||
}
|
||||
|
||||
//
|
||||
// casClientMon::destroy()
|
||||
//
|
||||
// this class is always created inside the server
|
||||
// lib with new
|
||||
//
|
||||
void casClientMon::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
//
|
||||
// casClientMon::resourceType()
|
||||
//
|
||||
casResType casClientMon::resourceType() const
|
||||
{
|
||||
return casClientMonT;
|
||||
}
|
||||
|
||||
@@ -17,16 +17,18 @@
|
||||
|
||||
|
||||
#include "server.h"
|
||||
#include "caServerIIL.h" // caServerI in line func
|
||||
#include "casEventSysIL.h" // casEventSys in line func
|
||||
#include "casCtxIL.h" // casCtx in line func
|
||||
#include "inBufIL.h" // inBuf in line func
|
||||
#include "outBufIL.h" // outBuf in line func
|
||||
#include "caServerIIL.h"
|
||||
#include "casEventSysIL.h"
|
||||
#include "casCtxIL.h"
|
||||
#include "inBufIL.h"
|
||||
#include "outBufIL.h"
|
||||
#include "casCoreClientIL.h"
|
||||
|
||||
//
|
||||
// casCoreClient::casCoreClient()
|
||||
//
|
||||
casCoreClient::casCoreClient (caServerI &serverInternal)
|
||||
casCoreClient::casCoreClient ( caServerI & serverInternal ) :
|
||||
eventSys ( *this )
|
||||
{
|
||||
assert (&serverInternal);
|
||||
ctx.setServer (&serverInternal);
|
||||
@@ -77,10 +79,10 @@ caStatus casCoreClient::disconnectChan(caResId)
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
void casCoreClient::show (unsigned level) const
|
||||
void casCoreClient::show ( unsigned level ) const
|
||||
{
|
||||
printf ( "Core client\n" );
|
||||
this->casEventSys::show ( level );
|
||||
this->eventSys.show ( level );
|
||||
printf ( "\t%d io ops in progess\n", this->ioInProgList.count() );
|
||||
this->ctx.show ( level );
|
||||
this->mutex.show ( level );
|
||||
@@ -183,9 +185,46 @@ ca_uint16_t casCoreClient::protocolRevision() const
|
||||
//
|
||||
// casCoreClient::lookupRes()
|
||||
//
|
||||
casRes *casCoreClient::lookupRes (const caResId &idIn, casResType type)
|
||||
casRes * casCoreClient::lookupRes (const caResId &idIn, casResType type)
|
||||
{
|
||||
casRes *pRes;
|
||||
pRes = this->ctx.getServer()->lookupRes(idIn, type);
|
||||
return pRes;
|
||||
return this->ctx.getServer()->lookupRes(idIn, type);
|
||||
}
|
||||
|
||||
// this is a pure virtual function, but we nevertheless need a
|
||||
// noop to be called if they post events when a channel is being
|
||||
// destroyed when we are in the casStrmClient destructor
|
||||
void casCoreClient::eventSignal()
|
||||
{
|
||||
}
|
||||
|
||||
caStatus casCoreClient::casMonitorCallBack ( casMonitor &,
|
||||
const smartConstGDDPointer & )
|
||||
{
|
||||
return S_cas_internal;
|
||||
}
|
||||
|
||||
casMonitor & casCoreClient::monitorFactory (
|
||||
casChannelI & chan,
|
||||
caResId clientId,
|
||||
const unsigned long count,
|
||||
const unsigned type,
|
||||
const casEventMask & mask )
|
||||
{
|
||||
casMonitor & mon = this->ctx.getServer()->casMonitorFactory (
|
||||
chan, clientId, count,
|
||||
type, mask,
|
||||
this->mutex,
|
||||
*this );
|
||||
this->installMonitor ();
|
||||
return mon;
|
||||
}
|
||||
|
||||
void casCoreClient::destroyMonitor ( casMonitor & mon )
|
||||
{
|
||||
this->removeMonitor ();
|
||||
this->ctx.getServer()->casMonitorDestroy ( mon );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ inline caServerI &casCoreClient::getCAS() const
|
||||
inline void casCoreClient::installAsyncIO(casAsyncIOI &ioIn)
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
this->ioInProgList.add(ioIn);
|
||||
this->ioInProgList.add ( ioIn );
|
||||
}
|
||||
|
||||
//
|
||||
@@ -56,8 +56,8 @@ inline void casCoreClient::installAsyncIO(casAsyncIOI &ioIn)
|
||||
inline void casCoreClient::removeAsyncIO(casAsyncIOI &ioIn)
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
this->ioInProgList.remove(ioIn);
|
||||
this->ctx.getServer()->ioBlockedList::signal();
|
||||
this->ioInProgList.remove ( ioIn );
|
||||
this->ctx.getServer()->ioBlockedList::signal ();
|
||||
}
|
||||
|
||||
inline bool casCoreClient::okToStartAsynchIO ()
|
||||
@@ -69,5 +69,67 @@ inline bool casCoreClient::okToStartAsynchIO ()
|
||||
return false;
|
||||
}
|
||||
|
||||
inline casMonEvent & casCoreClient::casMonEventFactory ( casMonitor & monitor,
|
||||
const smartConstGDDPointer & pNewValue )
|
||||
{
|
||||
return this->ctx.getServer()->casMonEventFactory ( monitor, pNewValue );
|
||||
}
|
||||
|
||||
inline void casCoreClient::casMonEventDestroy ( casMonEvent & event )
|
||||
{
|
||||
this->ctx.getServer()->casMonEventDestroy ( event );
|
||||
}
|
||||
|
||||
inline casEventSys::processStatus casCoreClient::eventSysProcess ()
|
||||
{
|
||||
return this->eventSys.process ();
|
||||
}
|
||||
|
||||
inline void casCoreClient::addToEventQueue ( casEvent & ev )
|
||||
{
|
||||
this->eventSys.addToEventQueue ( ev );
|
||||
}
|
||||
|
||||
inline void casCoreClient::insertEventQueue ( casEvent & insert, casEvent & prevEvent )
|
||||
{
|
||||
this->eventSys.insertEventQueue ( insert, prevEvent );
|
||||
}
|
||||
|
||||
inline void casCoreClient::removeFromEventQueue ( casEvent & ev )
|
||||
{
|
||||
this->eventSys.removeFromEventQueue ( ev );
|
||||
}
|
||||
|
||||
inline void casCoreClient::enableEvents ()
|
||||
{
|
||||
this->eventSys.eventsOn ();
|
||||
this->eventSignal (); // wake up the event queue consumer
|
||||
}
|
||||
|
||||
inline void casCoreClient::disableEvents ()
|
||||
{
|
||||
this->eventSys.eventsOff ();
|
||||
}
|
||||
|
||||
inline void casCoreClient::setDestroyPending ()
|
||||
{
|
||||
this->eventSys.setDestroyPending ();
|
||||
}
|
||||
|
||||
inline bool casCoreClient::eventSysIsFull ()
|
||||
{
|
||||
return this->eventSys.full ();
|
||||
}
|
||||
|
||||
inline void casCoreClient::installMonitor ()
|
||||
{
|
||||
this->eventSys.installMonitor ();
|
||||
}
|
||||
|
||||
inline void casCoreClient::removeMonitor ()
|
||||
{
|
||||
this->eventSys.removeMonitor ();
|
||||
}
|
||||
|
||||
#endif // casCoreClientIL_h
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ void casEventSys::show(unsigned level) const
|
||||
printf ("\tthere are %d events in the queue\n",
|
||||
this->eventLogQue.count());
|
||||
printf ("Replace events flag = %d, dontProcess flag = %d\n",
|
||||
this->replaceEvents, this->dontProcess);
|
||||
static_cast < int > ( this->replaceEvents ),
|
||||
static_cast < int > ( this->dontProcess ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +61,8 @@ casEventSys::~casEventSys()
|
||||
*/
|
||||
casVerify ( this->numEventBlocks == 0 );
|
||||
|
||||
while ( casEvent *pE = this->eventLogQue.get () ) {
|
||||
delete pE;
|
||||
while ( casEvent * pE = this->eventLogQue.get () ) {
|
||||
pE->eventSysDestroyNotify ( this->client );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -77,9 +78,9 @@ void casEventSys::installMonitor()
|
||||
}
|
||||
|
||||
//
|
||||
// casEventSys::removeMonitor()
|
||||
// casEventSys::removeMonitor ()
|
||||
//
|
||||
void casEventSys::removeMonitor()
|
||||
void casEventSys::removeMonitor ()
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
assert (this->numEventBlocks>=1u);
|
||||
@@ -90,10 +91,11 @@ void casEventSys::removeMonitor()
|
||||
//
|
||||
// casEventSys::process()
|
||||
//
|
||||
casProcCond casEventSys::process ()
|
||||
casEventSys::processStatus casEventSys::process ()
|
||||
{
|
||||
casProcCond cond = casProcOk;
|
||||
unsigned long nAccepted = 0u;
|
||||
casEventSys::processStatus ps;
|
||||
ps.cond = casProcOk;
|
||||
ps.nAccepted = 0u;
|
||||
|
||||
while ( ! this->dontProcess ) {
|
||||
casEvent * pEvent;
|
||||
@@ -108,9 +110,9 @@ casProcCond casEventSys::process ()
|
||||
}
|
||||
|
||||
// lock must remain on until the event is called
|
||||
caStatus status = pEvent->cbFunc ( *this );
|
||||
caStatus status = pEvent->cbFunc ( this->client );
|
||||
if ( status == S_cas_success ) {
|
||||
nAccepted++;
|
||||
ps.nAccepted++;
|
||||
}
|
||||
else if ( status == S_cas_sendBlocked ) {
|
||||
// not accepted so return to the head of the list
|
||||
@@ -119,26 +121,21 @@ casProcCond casEventSys::process ()
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
this->pushOnToEventQueue ( *pEvent );
|
||||
}
|
||||
cond = casProcOk;
|
||||
ps.cond = casProcOk;
|
||||
break;
|
||||
}
|
||||
else if ( status == S_cas_disconnect ) {
|
||||
cond = casProcDisconnect;
|
||||
ps.cond = casProcDisconnect;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
errMessage ( status,
|
||||
"- unexpected error processing event" );
|
||||
cond = casProcDisconnect;
|
||||
ps.cond = casProcDisconnect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// call flush function if they provided one
|
||||
if ( nAccepted > 0u ) {
|
||||
this->eventFlush ();
|
||||
}
|
||||
|
||||
//
|
||||
// allows the derived class to be informed that it
|
||||
// needs to delete itself via the event system
|
||||
@@ -149,10 +146,10 @@ casProcCond casEventSys::process ()
|
||||
// pointer.
|
||||
//
|
||||
if ( this->destroyPending ) {
|
||||
cond = casProcDisconnect;
|
||||
ps.cond = casProcDisconnect;
|
||||
}
|
||||
|
||||
return cond;
|
||||
return ps;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -166,12 +163,12 @@ void casEventSys::eventsOn()
|
||||
//
|
||||
// allow multiple events for each monitor
|
||||
//
|
||||
this->replaceEvents = FALSE;
|
||||
this->replaceEvents = false;
|
||||
|
||||
//
|
||||
// allow the event queue to be processed
|
||||
//
|
||||
this->dontProcess = FALSE;
|
||||
this->dontProcess = false;
|
||||
|
||||
//
|
||||
// remove purge event if it is still pending
|
||||
@@ -182,17 +179,12 @@ void casEventSys::eventsOn()
|
||||
this->pPurgeEvent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// wakes up the event queue consumer
|
||||
//
|
||||
this->eventSignal ();
|
||||
}
|
||||
|
||||
//
|
||||
// casEventSys::eventsOff()
|
||||
//
|
||||
caStatus casEventSys::eventsOff()
|
||||
void casEventSys::eventsOff()
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
|
||||
@@ -200,7 +192,7 @@ caStatus casEventSys::eventsOff()
|
||||
// new events will replace the last event on
|
||||
// the queue for a particular monitor
|
||||
//
|
||||
this->replaceEvents = TRUE;
|
||||
this->replaceEvents = true;
|
||||
|
||||
//
|
||||
// suppress the processing and sending of events
|
||||
@@ -208,62 +200,38 @@ caStatus casEventSys::eventsOff()
|
||||
// for this particular client
|
||||
//
|
||||
if ( this->pPurgeEvent == NULL ) {
|
||||
this->pPurgeEvent = new casEventPurgeEv;
|
||||
this->pPurgeEvent = new casEventPurgeEv ( *this );
|
||||
if ( this->pPurgeEvent == NULL ) {
|
||||
//
|
||||
// if there is no room for the event then immediately
|
||||
// stop processing and sending events to the client
|
||||
// until we exit flow control
|
||||
//
|
||||
this->dontProcess = TRUE;
|
||||
this->dontProcess = true;
|
||||
}
|
||||
else {
|
||||
this->casEventSys::addToEventQueue ( *this->pPurgeEvent );
|
||||
}
|
||||
}
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
// this is a pure virtual function, but we nevertheless need a
|
||||
// noop to be called if they post events when a channel is being
|
||||
// destroyed when we are in the casStrmClient destructor
|
||||
void casEventSys::eventSignal()
|
||||
//
|
||||
// casEventPurgeEv::casEventPurgeEv ()
|
||||
//
|
||||
casEventPurgeEv::casEventPurgeEv ( casEventSys & evSysIn ) :
|
||||
evSys ( evSysIn )
|
||||
{
|
||||
}
|
||||
|
||||
// this is a pure virtual function, but we nevertheless need a
|
||||
// noop to be called if they call this when we are in the
|
||||
// casStrmClient destructor
|
||||
caStatus casEventSys::disconnectChan ( caResId )
|
||||
{
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
// this is a pure virtual function, but we nevertheless need a
|
||||
// noop to be called if they call this when we are in the
|
||||
// casStrmClient destructor
|
||||
void casEventSys::eventFlush ()
|
||||
{
|
||||
}
|
||||
|
||||
// this is a pure virtual function, but we nevertheless need a
|
||||
// noop to be called if they call this when we are in the
|
||||
// casStrmClient destructor
|
||||
casRes * casEventSys::lookupRes ( const caResId &, casResType )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// casEventPurgeEv::cbFunc()
|
||||
//
|
||||
caStatus casEventPurgeEv::cbFunc ( casEventSys & evSys )
|
||||
caStatus casEventPurgeEv::cbFunc ( casCoreClient & )
|
||||
{
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( evSys.mutex );
|
||||
evSys.dontProcess = TRUE;
|
||||
evSys.pPurgeEvent = NULL;
|
||||
epicsGuard < epicsMutex > guard ( this->evSys.mutex );
|
||||
this->evSys.dontProcess = true;
|
||||
this->evSys.pPurgeEvent = NULL;
|
||||
}
|
||||
|
||||
delete this;
|
||||
@@ -271,3 +239,9 @@ caStatus casEventPurgeEv::cbFunc ( casEventSys & evSys )
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
void casEventPurgeEv::eventSysDestroyNotify ( casCoreClient & )
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,13 +22,14 @@
|
||||
//
|
||||
// casEventSys::casEventSys ()
|
||||
//
|
||||
inline casEventSys::casEventSys () :
|
||||
pPurgeEvent (NULL),
|
||||
numEventBlocks (0u),
|
||||
maxLogEntries (individualEventEntries),
|
||||
destroyPending (false),
|
||||
replaceEvents (false),
|
||||
dontProcess (false)
|
||||
inline casEventSys::casEventSys ( casCoreClient & clientIn ) :
|
||||
client ( clientIn ),
|
||||
pPurgeEvent ( NULL ),
|
||||
numEventBlocks ( 0u ),
|
||||
maxLogEntries ( individualEventEntries ),
|
||||
destroyPending ( false ),
|
||||
replaceEvents ( false ),
|
||||
dontProcess ( false )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -48,7 +49,7 @@ inline void casEventSys::addToEventQueue ( casEvent & event )
|
||||
// is in flow control
|
||||
//
|
||||
if ( ! this->dontProcess ) {
|
||||
this->eventSignal ();
|
||||
this->client.eventSignal ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +62,7 @@ inline void casEventSys::setDestroyPending()
|
||||
//
|
||||
// wakes up the event queue consumer
|
||||
//
|
||||
this->eventSignal ();
|
||||
this->client.eventSignal ();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -104,19 +105,5 @@ inline bool casEventSys::full() // X aCC 361
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// casMonitor::resIdToMon()
|
||||
//
|
||||
inline casMonitor *casEventSys::resIdToMon(const caResId id)
|
||||
{
|
||||
casRes *pRes = this->lookupRes (id, casClientMonT);
|
||||
|
||||
//
|
||||
// safe to cast because we have checked the type code above
|
||||
// (and we know that casMonitor derived from casRes)
|
||||
//
|
||||
return (casMonitor *) pRes;
|
||||
}
|
||||
|
||||
#endif // casEventSysIL_h
|
||||
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
//
|
||||
// EPICS
|
||||
//
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "tsDLList.h"
|
||||
#include "tsFreeList.h"
|
||||
#include "resourceLib.h"
|
||||
#define CA_MINOR_PROTOCOL_REVISION 11
|
||||
#include "caProto.h"
|
||||
@@ -26,38 +28,40 @@
|
||||
|
||||
typedef aitUint32 caResId;
|
||||
|
||||
class casEventSys;
|
||||
class casChannelI;
|
||||
class casCoreClient;
|
||||
|
||||
//
|
||||
// casEvent
|
||||
//
|
||||
class casEvent : public tsDLNode<casEvent> {
|
||||
class casEvent : public tsDLNode < casEvent > {
|
||||
public:
|
||||
epicsShareFunc virtual ~casEvent();
|
||||
virtual caStatus cbFunc (casEventSys &)=0;
|
||||
private:
|
||||
virtual caStatus cbFunc ( casCoreClient & ) = 0;
|
||||
virtual void eventSysDestroyNotify ( casCoreClient & ) = 0;
|
||||
protected:
|
||||
virtual ~casEvent();
|
||||
};
|
||||
|
||||
class casChanDelEv : public casEvent {
|
||||
public:
|
||||
casChanDelEv(caResId idIn) : id(idIn) {}
|
||||
~casChanDelEv();
|
||||
caStatus cbFunc(casEventSys &);
|
||||
casChanDelEv ( caResId idIn ) : id(idIn) {}
|
||||
~casChanDelEv ();
|
||||
private:
|
||||
caResId id;
|
||||
caStatus cbFunc ( casCoreClient & );
|
||||
void eventSysDestroyNotify ( casCoreClient & );
|
||||
};
|
||||
|
||||
enum casResType {casChanT=1, casClientMonT, casPVT};
|
||||
enum casResType {casChanT=1, casMonitorT, casPVT};
|
||||
|
||||
class casRes : public chronIntIdRes<casRes>
|
||||
{
|
||||
public:
|
||||
casRes ();
|
||||
epicsShareFunc virtual ~casRes();
|
||||
virtual casResType resourceType() const = 0;
|
||||
virtual void show (unsigned level) const = 0;
|
||||
virtual void destroy() = 0;
|
||||
virtual casResType resourceType () const = 0;
|
||||
virtual void show ( unsigned level ) const = 0;
|
||||
//virtual void destroy() = 0;
|
||||
private:
|
||||
casRes ( const casRes & );
|
||||
casRes & operator = ( const casRes & );
|
||||
@@ -100,90 +104,90 @@ class casMonitor;
|
||||
//
|
||||
class casMonEvent : public casEvent {
|
||||
public:
|
||||
//
|
||||
// only used when this is part of another structure
|
||||
// (and we need to postpone true construction)
|
||||
//
|
||||
inline casMonEvent ();
|
||||
inline casMonEvent (casMonitor &monitor, const smartConstGDDPointer &pNewValue);
|
||||
inline casMonEvent (const casMonEvent &initValue);
|
||||
|
||||
//
|
||||
// ~casMonEvent ()
|
||||
// (not inline because this is virtual in the base class)
|
||||
//
|
||||
casMonEvent ();
|
||||
casMonEvent (casMonitor &monitor, const smartConstGDDPointer &pNewValue);
|
||||
casMonEvent (const casMonEvent &initValue);
|
||||
~casMonEvent ();
|
||||
|
||||
caStatus cbFunc (casEventSys &);
|
||||
|
||||
//
|
||||
// casMonEvent::getValue()
|
||||
//
|
||||
inline smartConstGDDPointer getValue () const;
|
||||
|
||||
inline void operator = (const class casMonEvent &monEventIn);
|
||||
|
||||
inline void clear ();
|
||||
|
||||
smartConstGDDPointer getValue () const;
|
||||
void operator = (const class casMonEvent &monEventIn);
|
||||
void clear ();
|
||||
void assign (casMonitor &monitor, const smartConstGDDPointer &pValueIn);
|
||||
void * operator new ( size_t size, tsFreeList < class casMonEvent, 1024 > & );
|
||||
epicsPlacementDeleteOperator (( void *, tsFreeList < class casMonEvent, 1024 > & ))
|
||||
private:
|
||||
smartConstGDDPointer pValue;
|
||||
caResId id;
|
||||
void * operator new ( size_t );
|
||||
void operator delete ( void * );
|
||||
caStatus cbFunc ( casCoreClient & );
|
||||
void eventSysDestroyNotify ( casCoreClient & );
|
||||
};
|
||||
|
||||
class casMonitorCallbackInterface {
|
||||
public:
|
||||
virtual caStatus casMonitorCallBack ( casMonitor &,
|
||||
const smartConstGDDPointer & pValue ) = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// casMonitor()
|
||||
//
|
||||
class casMonitor : public tsDLNode<casMonitor>, public casRes {
|
||||
class casMonitor :
|
||||
public tsDLNode < casMonitor >, public casRes {
|
||||
public:
|
||||
casMonitor(caResId clientIdIn, casChannelI &chan,
|
||||
unsigned long nElem, unsigned dbrType,
|
||||
const casEventMask &maskIn, epicsMutex &mutexIn);
|
||||
casMonitor ( caResId clientIdIn, casChannelI & chan,
|
||||
unsigned long nElem, unsigned dbrType,
|
||||
const casEventMask & maskIn, epicsMutex & mutexIn,
|
||||
casMonitorCallbackInterface & );
|
||||
virtual ~casMonitor();
|
||||
|
||||
caStatus executeEvent(casMonEvent *);
|
||||
void show ( unsigned level ) const;
|
||||
|
||||
inline void post(const casEventMask &select, const smartConstGDDPointer &pValue);
|
||||
caStatus executeEvent ( casMonEvent & );
|
||||
|
||||
virtual void show (unsigned level) const;
|
||||
virtual caStatus callBack (const smartConstGDDPointer &pValue) = 0;
|
||||
void post ( const casEventMask & select, const smartConstGDDPointer & pValue );
|
||||
|
||||
caResId getClientId() const
|
||||
caResId getClientId () const
|
||||
{
|
||||
return this->clientId;
|
||||
}
|
||||
|
||||
unsigned getType() const
|
||||
unsigned getType () const
|
||||
{
|
||||
return this->dbrType;
|
||||
}
|
||||
|
||||
unsigned long getCount() const
|
||||
unsigned long getCount () const
|
||||
{
|
||||
return this->nElem;
|
||||
}
|
||||
casChannelI &getChannel() const
|
||||
casChannelI & getChannel () const
|
||||
{
|
||||
return this->ciu;
|
||||
}
|
||||
void * operator new ( size_t size,
|
||||
tsFreeList < casMonitor, 1024 > & );
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
tsFreeList < casMonitor, 1024 > & ))
|
||||
|
||||
private:
|
||||
casMonEvent overFlowEvent;
|
||||
unsigned long const nElem;
|
||||
epicsMutex & mutex;
|
||||
casChannelI & ciu;
|
||||
casMonitorCallbackInterface & callBackIntf;
|
||||
const casEventMask mask;
|
||||
caResId const clientId;
|
||||
unsigned char const dbrType;
|
||||
unsigned char nPend;
|
||||
bool ovf;
|
||||
bool enabled;
|
||||
|
||||
void enable ();
|
||||
void disable ();
|
||||
|
||||
void push (const smartConstGDDPointer &pValue);
|
||||
casResType resourceType () const;
|
||||
void push ( const smartConstGDDPointer & pValue );
|
||||
void * operator new ( size_t );
|
||||
void operator delete ( void * );
|
||||
casMonitor ( const casMonitor & );
|
||||
casMonitor & operator = ( const casMonitor & );
|
||||
};
|
||||
@@ -210,7 +214,6 @@ inline void casMonitor::post (const casEventMask &select, const smartConstGDDPoi
|
||||
}
|
||||
|
||||
class caServer;
|
||||
class casCoreClient;
|
||||
class casChannelI;
|
||||
class casCtx;
|
||||
class caServer;
|
||||
@@ -248,7 +251,9 @@ private:
|
||||
// casEvent virtual call back function
|
||||
// (called when IO completion event reaches top of event queue)
|
||||
//
|
||||
epicsShareFunc caStatus cbFunc(casEventSys &);
|
||||
epicsShareFunc caStatus cbFunc ( casCoreClient & );
|
||||
|
||||
epicsShareFunc void eventSysDestroyNotify ( casCoreClient & );
|
||||
|
||||
//
|
||||
// derived class specic call back
|
||||
@@ -274,15 +279,16 @@ class casPVI;
|
||||
// this derives from casEvent so that access rights
|
||||
// events can be posted
|
||||
//
|
||||
class casChannelI : public tsDLNode<casChannelI>, public casRes,
|
||||
public casEvent {
|
||||
class casChannelI : public tsDLNode < casChannelI >,
|
||||
public casRes, public casEvent {
|
||||
public:
|
||||
casChannelI (const casCtx &ctx);
|
||||
epicsShareFunc virtual ~casChannelI();
|
||||
casChannelI ( const casCtx & ctx );
|
||||
epicsShareFunc virtual ~casChannelI ();
|
||||
|
||||
void bindToClientI ( casCoreClient & client, casPVI & pv, caResId cid );
|
||||
void bindToClientI ( class casCoreClient & client,
|
||||
casPVI & pv, caResId cid );
|
||||
|
||||
casCoreClient &getClient () const
|
||||
class casCoreClient & getClient () const
|
||||
{
|
||||
return *this->pClient;
|
||||
}
|
||||
@@ -295,33 +301,23 @@ public:
|
||||
//
|
||||
const caResId getSID ();
|
||||
|
||||
//
|
||||
// addMonitor()
|
||||
//
|
||||
void addMonitor (casMonitor &mon);
|
||||
void installMonitor (
|
||||
caResId clientId,
|
||||
const unsigned long count,
|
||||
const unsigned type,
|
||||
const casEventMask & );
|
||||
|
||||
//
|
||||
// deleteMonitor()
|
||||
//
|
||||
void deleteMonitor (casMonitor &mon);
|
||||
|
||||
//
|
||||
// findMonitor
|
||||
// (it is reasonable to do a linear search here because
|
||||
// sane clients will require only one or two monitors
|
||||
// per channel)
|
||||
//
|
||||
tsDLIter <casMonitor> findMonitor (const caResId clientIdIn);
|
||||
bool unistallMonitor ( ca_uint32_t monId );
|
||||
|
||||
casPVI &getPVI () const
|
||||
{
|
||||
return *this->pPV;
|
||||
}
|
||||
|
||||
void installAsyncIO (casAsyncIOI &);
|
||||
void removeAsyncIO (casAsyncIOI &);
|
||||
void installAsyncIO ( casAsyncIOI & );
|
||||
void removeAsyncIO ( casAsyncIOI & );
|
||||
|
||||
void postEvent (const casEventMask &select, const gdd &event);
|
||||
void postEvent ( const casEventMask & select, const gdd & event );
|
||||
|
||||
epicsShareFunc virtual casResType resourceType () const;
|
||||
|
||||
@@ -330,11 +326,6 @@ public:
|
||||
|
||||
void clearOutstandingReads ();
|
||||
|
||||
//
|
||||
// access rights event call back
|
||||
//
|
||||
epicsShareFunc caStatus cbFunc (casEventSys &);
|
||||
|
||||
void postAccessRightsEvent ();
|
||||
|
||||
const gddEnumStringTable & enumStringTable () const;
|
||||
@@ -342,22 +333,24 @@ public:
|
||||
//
|
||||
// virtual functions
|
||||
//
|
||||
epicsShareFunc virtual void setOwner (const char * const pUserName,
|
||||
const char * const pHostName) = 0;
|
||||
epicsShareFunc virtual void setOwner ( const char * const pUserName,
|
||||
const char * const pHostName ) = 0;
|
||||
epicsShareFunc virtual bool readAccess () const = 0;
|
||||
epicsShareFunc virtual bool writeAccess () const = 0;
|
||||
epicsShareFunc virtual bool confirmationRequested () const = 0;
|
||||
epicsShareFunc virtual void show (unsigned level) const;
|
||||
epicsShareFunc virtual void show ( unsigned level ) const;
|
||||
|
||||
protected:
|
||||
tsDLList<casMonitor> monitorList;
|
||||
tsDLList<casAsyncIOI> ioInProgList;
|
||||
casCoreClient * pClient;
|
||||
casPVI * pPV;
|
||||
caResId cid; // client id
|
||||
bool accessRightsEvPending:1;
|
||||
tsDLList < casMonitor > monitorList;
|
||||
tsDLList < casAsyncIOI > ioInProgList;
|
||||
class casCoreClient * pClient;
|
||||
casPVI * pPV;
|
||||
caResId cid; // client id
|
||||
bool accessRightsEvPending:1;
|
||||
|
||||
epicsShareFunc virtual void destroy ();
|
||||
epicsShareFunc caStatus cbFunc ( casCoreClient & ); // access rights event call back
|
||||
epicsShareFunc void eventSysDestroyNotify ( casCoreClient & );
|
||||
casChannelI ( const casChannelI & );
|
||||
casChannelI & operator = ( const casChannelI & );
|
||||
};
|
||||
@@ -369,7 +362,8 @@ class casPVListChan : public casChannelI, public tsDLNode<casPVListChan>
|
||||
{
|
||||
public:
|
||||
casPVListChan ( const casCtx &ctx );
|
||||
void bindToClient ( casCoreClient & client, casPVI & pv, caResId cid );
|
||||
void bindToClient ( casCoreClient & client,
|
||||
casPVI & pv, caResId cidIn );
|
||||
epicsShareFunc virtual ~casPVListChan();
|
||||
private:
|
||||
casPVListChan ( const casPVListChan & );
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "server.h"
|
||||
#include "casEventSysIL.h" // casEventSys in line func
|
||||
@@ -24,30 +25,37 @@
|
||||
//
|
||||
// casMonEvent::cbFunc()
|
||||
//
|
||||
caStatus casMonEvent::cbFunc(casEventSys &eSys)
|
||||
caStatus casMonEvent::cbFunc ( casCoreClient & client )
|
||||
{
|
||||
casMonitor *pMon;
|
||||
caStatus status;
|
||||
|
||||
//
|
||||
// ignore this event if it is stale and there is
|
||||
// no call back object associated with it
|
||||
//
|
||||
pMon = eSys.resIdToMon(this->id);
|
||||
if (!pMon) {
|
||||
/*
|
||||
* we know this isnt an overflow event because those are
|
||||
* removed from the queue when the call back object
|
||||
* is deleted
|
||||
*/
|
||||
status = S_casApp_success;
|
||||
delete this;
|
||||
}
|
||||
else {
|
||||
status = pMon->executeEvent(this);
|
||||
}
|
||||
|
||||
return status;
|
||||
caStatus status;
|
||||
|
||||
//
|
||||
// ignore this event if it is stale and there is
|
||||
// no call back object associated with it
|
||||
//
|
||||
// safe to cast because we have checked the type code
|
||||
//
|
||||
casMonitor * pMon = reinterpret_cast < casMonitor * >
|
||||
( client.lookupRes ( this->id, casMonitorT ) );
|
||||
if ( ! pMon ) {
|
||||
// we know this isnt an overflow event because those are
|
||||
// removed from the queue when the casMonitor object is
|
||||
// destroyed
|
||||
client.casMonEventDestroy ( *this );
|
||||
status = S_casApp_success;
|
||||
}
|
||||
else {
|
||||
// this object may have been destroyed
|
||||
// here by the executeEvent() call below
|
||||
status = pMon->executeEvent ( *this );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void casMonEvent::eventSysDestroyNotify ( casCoreClient & client )
|
||||
{
|
||||
client.casMonEventDestroy ( *this );
|
||||
}
|
||||
|
||||
//
|
||||
@@ -68,3 +76,37 @@ casMonEvent::~casMonEvent ()
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void * casMonEvent::operator new ( size_t size,
|
||||
tsFreeList < class casMonEvent, 1024 > & freeList )
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#ifdef CXX_PLACEMENT_DELETE
|
||||
void casMonEvent::operator delete ( void *pCadaver,
|
||||
tsFreeList < class casMonEvent, 1024 > & freeList ) epicsThrows(())
|
||||
{
|
||||
freeList.release ( pCadaver, sizeof ( casMonEvent ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
void * casMonEvent::operator new ( size_t ) // X aCC 361
|
||||
{
|
||||
// The HPUX compiler seems to require this even though no code
|
||||
// calls it directly
|
||||
throw std::logic_error ( "why is the compiler calling private operator new" );
|
||||
}
|
||||
|
||||
void casMonEvent::operator delete ( void * )
|
||||
{
|
||||
// Visual C++ .net appears to require operator delete if
|
||||
// placement operator delete is defined? I smell a ms rat
|
||||
// because if I declare placement new and delete, but
|
||||
// comment out the placement delete definition there are
|
||||
// no undefined symbols.
|
||||
errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked",
|
||||
__FILE__, __LINE__ );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,27 +26,27 @@
|
||||
//
|
||||
// casMonitor::casMonitor()
|
||||
//
|
||||
casMonitor::casMonitor(caResId clientIdIn, casChannelI &chan,
|
||||
unsigned long nElemIn, unsigned dbrTypeIn,
|
||||
const casEventMask &maskIn, epicsMutex &mutexIn) :
|
||||
nElem(nElemIn),
|
||||
mutex(mutexIn),
|
||||
ciu(chan),
|
||||
mask(maskIn),
|
||||
clientId(clientIdIn),
|
||||
dbrType(static_cast <unsigned char> ( dbrTypeIn ) ),
|
||||
nPend(0u),
|
||||
ovf(false),
|
||||
enabled(false)
|
||||
casMonitor::casMonitor (
|
||||
caResId clientIdIn,
|
||||
casChannelI & chan,
|
||||
unsigned long nElemIn,
|
||||
unsigned dbrTypeIn,
|
||||
const casEventMask & maskIn,
|
||||
epicsMutex & mutexIn,
|
||||
casMonitorCallbackInterface & cb ) :
|
||||
nElem ( nElemIn ),
|
||||
mutex ( mutexIn ),
|
||||
ciu ( chan ),
|
||||
callBackIntf ( cb ),
|
||||
mask ( maskIn ),
|
||||
clientId ( clientIdIn ),
|
||||
dbrType ( static_cast <unsigned char> ( dbrTypeIn ) ),
|
||||
nPend ( 0u ),
|
||||
ovf ( false ),
|
||||
enabled ( false )
|
||||
{
|
||||
//
|
||||
// If these are nill it is a programmer error
|
||||
//
|
||||
assert (&this->ciu);
|
||||
assert (dbrTypeIn<=0xff);
|
||||
|
||||
this->ciu.addMonitor(*this);
|
||||
|
||||
assert ( &this->ciu );
|
||||
assert ( dbrTypeIn <= 0xff );
|
||||
this->enable();
|
||||
}
|
||||
|
||||
@@ -56,18 +56,11 @@ casMonitor::casMonitor(caResId clientIdIn, casChannelI &chan,
|
||||
casMonitor::~casMonitor()
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
|
||||
this->disable();
|
||||
|
||||
//
|
||||
// remove from the event system
|
||||
//
|
||||
if ( this->ovf ) {
|
||||
casCoreClient &client = this->ciu.getClient();
|
||||
client.removeFromEventQueue ( this->overFlowEvent );
|
||||
}
|
||||
|
||||
this->ciu.deleteMonitor ( * this );
|
||||
}
|
||||
|
||||
//
|
||||
@@ -101,22 +94,22 @@ void casMonitor::disable()
|
||||
//
|
||||
// casMonitor::push()
|
||||
//
|
||||
void casMonitor::push (const smartConstGDDPointer &pNewValue)
|
||||
void casMonitor::push ( const smartConstGDDPointer & pNewValue )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
|
||||
casCoreClient &client = this->ciu.getClient ();
|
||||
casCoreClient & client = this->ciu.getClient ();
|
||||
client.getCAS().incrEventsPostedCounter ();
|
||||
|
||||
//
|
||||
// get a new block if we havent exceeded quotas
|
||||
//
|
||||
bool full = ( this->nPend >= individualEventEntries )
|
||||
|| client.casEventSys::full ();
|
||||
|| client.eventSysIsFull ();
|
||||
casMonEvent * pLog;
|
||||
if ( ! full ) {
|
||||
pLog = new casMonEvent (*this, pNewValue);
|
||||
if (pLog) {
|
||||
pLog = & client.casMonEventFactory ( *this, pNewValue );
|
||||
if ( pLog ) {
|
||||
this->nPend++; // X aCC 818
|
||||
}
|
||||
}
|
||||
@@ -165,19 +158,19 @@ void casMonitor::push (const smartConstGDDPointer &pNewValue)
|
||||
//
|
||||
// casMonitor::executeEvent()
|
||||
//
|
||||
caStatus casMonitor::executeEvent(casMonEvent *pEV)
|
||||
caStatus casMonitor::executeEvent ( casMonEvent & ev )
|
||||
{
|
||||
caStatus status;
|
||||
smartConstGDDPointer pVal;
|
||||
|
||||
pVal = pEV->getValue ();
|
||||
smartConstGDDPointer pVal = ev.getValue ();
|
||||
if ( ! pVal ) {
|
||||
assert ( 0 );
|
||||
}
|
||||
|
||||
caStatus status;
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
status = this->callBack ( * pVal );
|
||||
status =
|
||||
this->callBackIntf.
|
||||
casMonitorCallBack ( *this, *pVal );
|
||||
}
|
||||
|
||||
//
|
||||
@@ -197,13 +190,13 @@ caStatus casMonitor::executeEvent(casMonEvent *pEV)
|
||||
// delete event object if it isnt a cache entry
|
||||
// saved in the call back object
|
||||
//
|
||||
if ( pEV == &this->overFlowEvent ) {
|
||||
if ( &ev == &this->overFlowEvent ) {
|
||||
assert ( this->ovf );
|
||||
this->ovf = false;
|
||||
pEV->clear();
|
||||
ev.clear();
|
||||
}
|
||||
else {
|
||||
delete pEV;
|
||||
this->ciu.getClient().casMonEventDestroy ( ev );
|
||||
}
|
||||
|
||||
this->ciu.getClient().getCAS().incrEventsProcessedCounter ();
|
||||
@@ -224,3 +217,32 @@ void casMonitor::show ( unsigned level ) const
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// casMonitor::resourceType()
|
||||
//
|
||||
casResType casMonitor::resourceType() const
|
||||
{
|
||||
return casMonitorT;
|
||||
}
|
||||
|
||||
void * casMonitor::operator new (
|
||||
size_t size,
|
||||
tsFreeList < casMonitor, 1024 > & freeList )
|
||||
epicsThrows ( ( std::bad_alloc ) )
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#ifdef CXX_PLACEMENT_DELETE
|
||||
void casMonitor::operator delete ( void * pCadaver,
|
||||
tsFreeList < casMonitor, 1024 > & freeList ) epicsThrows(())
|
||||
{
|
||||
freeList.release ( pCadaver );
|
||||
}
|
||||
#endif
|
||||
|
||||
void casMonitor::operator delete ( void * )
|
||||
{
|
||||
errlogPrintf ( "casMonitor: compiler is confused "
|
||||
"about placement delete?\n" );
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ casOpaqueAddr::casOpaqueAddr()
|
||||
//
|
||||
void casOpaqueAddr::clear()
|
||||
{
|
||||
this->init = 0;
|
||||
this->init = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ inline void casOpaqueAddr::set (const caAddr &addr)
|
||||
// sizeof(casOpaqueAddr::opaqueAddr) < sizeof(caAddr)
|
||||
//
|
||||
*p = addr;
|
||||
this->init = TRUE;
|
||||
this->init = true;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -42,7 +42,7 @@ inline caAddr casOpaqueAddr::get () const
|
||||
{
|
||||
caAddr *p = (caAddr *) this->opaqueAddr;
|
||||
|
||||
assert(this->init);
|
||||
assert ( this->init );
|
||||
//
|
||||
// see class casOpaqueAddr::checkSize
|
||||
// for assert fail when
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "casPVIIL.h" // casPVI inline func
|
||||
#include "casCtxIL.h" // casCtx inline func
|
||||
|
||||
epicsShareFunc casPV::casPV ()
|
||||
casPV::casPV ()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -33,11 +33,11 @@ epicsShareFunc casPV::casPV ()
|
||||
// This constructor is preserved for backwards compatibility only.
|
||||
// Please do _not_ use this constructor.
|
||||
//
|
||||
epicsShareFunc casPV::casPV (caServer &)
|
||||
casPV::casPV (caServer &)
|
||||
{
|
||||
}
|
||||
|
||||
epicsShareFunc casPV::~casPV ()
|
||||
casPV::~casPV ()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ void casPV::destroy ()
|
||||
//
|
||||
// casPV::createChannel()
|
||||
//
|
||||
epicsShareFunc casChannel *casPV::createChannel (const casCtx &ctx, const char * const,
|
||||
casChannel *casPV::createChannel (const casCtx &ctx, const char * const,
|
||||
const char * const)
|
||||
{
|
||||
return new casChannel (ctx);
|
||||
@@ -64,7 +64,7 @@ epicsShareFunc casChannel *casPV::createChannel (const casCtx &ctx, const char *
|
||||
//
|
||||
// casPV::interestRegister()
|
||||
//
|
||||
epicsShareFunc caStatus casPV::interestRegister ()
|
||||
caStatus casPV::interestRegister ()
|
||||
{
|
||||
return S_casApp_success;
|
||||
}
|
||||
@@ -72,14 +72,14 @@ epicsShareFunc caStatus casPV::interestRegister ()
|
||||
//
|
||||
// casPV::interestDelete()
|
||||
//
|
||||
epicsShareFunc void casPV::interestDelete ()
|
||||
void casPV::interestDelete ()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// casPV::beginTransaction()
|
||||
//
|
||||
epicsShareFunc caStatus casPV::beginTransaction ()
|
||||
caStatus casPV::beginTransaction ()
|
||||
{
|
||||
return S_casApp_success;
|
||||
}
|
||||
@@ -87,14 +87,14 @@ epicsShareFunc caStatus casPV::beginTransaction ()
|
||||
//
|
||||
// casPV::endTransaction()
|
||||
//
|
||||
epicsShareFunc void casPV::endTransaction ()
|
||||
void casPV::endTransaction ()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// casPV::read()
|
||||
//
|
||||
epicsShareFunc caStatus casPV::read (const casCtx &, gdd &)
|
||||
caStatus casPV::read (const casCtx &, gdd &)
|
||||
{
|
||||
return S_casApp_noSupport;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ epicsShareFunc caStatus casPV::read (const casCtx &, gdd &)
|
||||
//
|
||||
// casPV::write()
|
||||
//
|
||||
epicsShareFunc caStatus casPV::write (const casCtx &, const gdd &)
|
||||
caStatus casPV::write (const casCtx &, const gdd &)
|
||||
{
|
||||
return S_casApp_noSupport;
|
||||
}
|
||||
@@ -110,7 +110,7 @@ epicsShareFunc caStatus casPV::write (const casCtx &, const gdd &)
|
||||
//
|
||||
// casPV::bestExternalType()
|
||||
//
|
||||
epicsShareFunc aitEnum casPV::bestExternalType () const
|
||||
aitEnum casPV::bestExternalType () const
|
||||
{
|
||||
return aitEnumString;
|
||||
}
|
||||
@@ -119,7 +119,7 @@ epicsShareFunc aitEnum casPV::bestExternalType () const
|
||||
// casPV::maxDimension()
|
||||
// (base returns zero - scalar)
|
||||
//
|
||||
epicsShareFunc unsigned casPV::maxDimension () const
|
||||
unsigned casPV::maxDimension () const
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ epicsShareFunc unsigned casPV::maxDimension () const
|
||||
// casPV::maxBound()
|
||||
// (base returns scalar bound independent of the dimension arg)
|
||||
//
|
||||
epicsShareFunc aitIndex casPV::maxBound (unsigned /* dimension */) const
|
||||
aitIndex casPV::maxBound (unsigned /* dimension */) const
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ epicsShareFunc aitIndex casPV::maxBound (unsigned /* dimension */) const
|
||||
//
|
||||
// casPV::show (unsigned level)
|
||||
//
|
||||
epicsShareFunc void casPV::show (unsigned level) const
|
||||
void casPV::show (unsigned level) const
|
||||
{
|
||||
casPVI::show (level);
|
||||
}
|
||||
@@ -144,7 +144,7 @@ epicsShareFunc void casPV::show (unsigned level) const
|
||||
//
|
||||
// Server tool calls this function to post a PV event.
|
||||
//
|
||||
epicsShareFunc void casPV::postEvent (const casEventMask &select, const gdd &event)
|
||||
void casPV::postEvent (const casEventMask &select, const gdd &event)
|
||||
{
|
||||
this->casPVI::postEvent (select, event);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ epicsShareFunc void casPV::postEvent (const casEventMask &select, const gdd &eve
|
||||
// into a server.
|
||||
// ***************
|
||||
//
|
||||
epicsShareFunc caServer *casPV::getCAS () const
|
||||
caServer *casPV::getCAS () const
|
||||
{
|
||||
return this->casPVI::getExtServer ();
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ caServer *casPVI::getExtServer() const // X aCC 361
|
||||
//
|
||||
// casPVI::show()
|
||||
//
|
||||
epicsShareFunc void casPVI::show (unsigned level) const
|
||||
void casPVI::show (unsigned level) const
|
||||
{
|
||||
if (level>1u) {
|
||||
printf ("CA Server PV: nChanAttached=%u nMonAttached=%u nIOAttached=%u\n",
|
||||
@@ -364,7 +364,7 @@ epicsShareFunc void casPVI::show (unsigned level) const
|
||||
//
|
||||
// casPVI::resourceType()
|
||||
//
|
||||
epicsShareFunc casResType casPVI::resourceType() const
|
||||
casResType casPVI::resourceType() const
|
||||
{
|
||||
return casPVT;
|
||||
}
|
||||
@@ -373,7 +373,7 @@ epicsShareFunc casResType casPVI::resourceType() const
|
||||
// casPVI::apiPointer()
|
||||
// retuns NULL if casPVI isnt a base of casPV
|
||||
//
|
||||
epicsShareFunc casPV *casPVI::apiPointer ()
|
||||
casPV *casPVI::apiPointer ()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ casPVListChan::casPVListChan (const casCtx &ctx) :
|
||||
{
|
||||
}
|
||||
|
||||
void casPVListChan::bindToClient ( casCoreClient & client, casPVI & pv, caResId cidIn )
|
||||
void casPVListChan::bindToClient (
|
||||
casCoreClient & client, casPVI & pv, caResId cidIn )
|
||||
{
|
||||
this->bindToClientI ( client, pv, cidIn );
|
||||
this->pPV->installChannel ( *this );
|
||||
|
||||
@@ -144,22 +144,21 @@ caStatus casStrmClient::verifyRequest (casChannelI *&pChan)
|
||||
//
|
||||
// find the monitor associated with a resource id
|
||||
//
|
||||
inline casClientMon *caServerI::resIdToClientMon (const caResId &idIn)
|
||||
inline casClientMon * caServerI::resIdToClientMon (
|
||||
const caResId & idIn )
|
||||
{
|
||||
casRes *pRes;
|
||||
|
||||
pRes = this->lookupRes(idIn, casClientMonT);
|
||||
casRes * pRes = this->lookupRes ( idIn, casMonitorT );
|
||||
//
|
||||
// cast is ok since the type code was verified
|
||||
// (and we know casClientMon derived from resource)
|
||||
//
|
||||
return (casClientMon *) pRes;
|
||||
return reinterpret_cast < casClientMon * > ( pRes );
|
||||
}
|
||||
|
||||
//
|
||||
// casStrmClient::show (unsigned level)
|
||||
//
|
||||
void casStrmClient::show (unsigned level) const
|
||||
void casStrmClient::show ( unsigned level ) const
|
||||
{
|
||||
this->casClient::show (level);
|
||||
printf ( "casStrmClient at %p\n",
|
||||
@@ -259,7 +258,7 @@ caStatus casStrmClient::readResponse ( casChannelI * pChan, const caHdrLargeArra
|
||||
}
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
( * cac_dbr_cvrt[msg.m_dataType] )
|
||||
( pPayload, pPayload, TRUE, msg.m_count );
|
||||
( pPayload, pPayload, true, msg.m_count );
|
||||
#endif
|
||||
|
||||
if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
|
||||
@@ -380,7 +379,7 @@ caStatus casStrmClient::readNotifyResponse ( casChannelI * pChan,
|
||||
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
( * cac_dbr_cvrt[ msg.m_dataType ] )
|
||||
( pPayload, pPayload, TRUE, msg.m_count );
|
||||
( pPayload, pPayload, true, msg.m_count );
|
||||
#endif
|
||||
|
||||
if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
|
||||
@@ -515,7 +514,7 @@ static smartGDDPointer createDBRDD ( unsigned dbrType, unsigned elemCount )
|
||||
}
|
||||
|
||||
//
|
||||
// casStrmClient::monitorResponse ()
|
||||
// casStrmClient::monitorFailureResponse ()
|
||||
//
|
||||
caStatus casStrmClient::monitorFailureResponse ( const caHdrLargeArray & msg,
|
||||
const caStatus ECA_XXXX )
|
||||
@@ -604,7 +603,7 @@ caStatus casStrmClient::monitorResponse ( casChannelI & chan, const caHdrLargeAr
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
/* use type as index into conversion jumptable */
|
||||
(* cac_dbr_cvrt[msg.m_dataType])
|
||||
( pPayload, pPayload, TRUE, msg.m_count );
|
||||
( pPayload, pPayload, true, msg.m_count );
|
||||
#endif
|
||||
//
|
||||
// force string message size to be the true size
|
||||
@@ -1026,7 +1025,8 @@ caStatus casStrmClient::createChanResponse ( const caHdrLargeArray & hdr, const
|
||||
// create server tool XXX derived from casChannel
|
||||
//
|
||||
this->ctx.setPV ( pPV );
|
||||
casChannel * pChan = pPV->createChannel ( this->ctx, this->pUserName, this->pHostName );
|
||||
casChannel * pChan = pPV->createChannel (
|
||||
this->ctx, this->pUserName, this->pHostName );
|
||||
if ( ! pChan ) {
|
||||
pPV->deleteSignal();
|
||||
return this->channelCreateFailedResp ( hdr, S_cas_noMemory );
|
||||
@@ -1220,7 +1220,7 @@ caStatus casStrmClient::disconnectChan ( caResId id )
|
||||
//
|
||||
caStatus casStrmClient::eventsOnAction ()
|
||||
{
|
||||
this->casEventSys::eventsOn();
|
||||
this->enableEvents ();
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
@@ -1229,7 +1229,8 @@ caStatus casStrmClient::eventsOnAction ()
|
||||
//
|
||||
caStatus casStrmClient::eventsOffAction()
|
||||
{
|
||||
return this->casEventSys::eventsOff();
|
||||
this->disableEvents ();
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1240,7 +1241,6 @@ caStatus casStrmClient::eventAddAction ()
|
||||
const caHdrLargeArray *mp = this->ctx.getMsg();
|
||||
struct mon_info *pMonInfo = (struct mon_info *)
|
||||
this->ctx.getData();
|
||||
casClientMon *pMonitor;
|
||||
casChannelI *pciu;
|
||||
smartGDDPointer pDD;
|
||||
caStatus status;
|
||||
@@ -1306,24 +1306,14 @@ caStatus casStrmClient::eventAddAction ()
|
||||
return S_cas_success;
|
||||
}
|
||||
else {
|
||||
status = this->monitorResponse ( *pciu, *mp, pDD, status );
|
||||
status = this->monitorResponse ( *pciu,
|
||||
*mp, pDD, status );
|
||||
}
|
||||
|
||||
if ( status == S_cas_success ) {
|
||||
|
||||
pMonitor = new casClientMon ( *pciu, mp->m_available,
|
||||
mp->m_count, mp->m_dataType, mask, this->mutex );
|
||||
if ( ! pMonitor ) {
|
||||
status = this->sendErr ( mp, ECA_ALLOCMEM, NULL );
|
||||
if ( status==S_cas_success ) {
|
||||
//
|
||||
// If we cant allocate space for a monitor then
|
||||
// delete (disconnect) the channel
|
||||
//
|
||||
pciu->destroyClientNotify ();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
pciu->installMonitor (
|
||||
mp->m_available, mp->m_count,
|
||||
mp->m_dataType, mask );
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -1390,13 +1380,11 @@ caStatus casStrmClient::eventCancelAction ()
|
||||
{
|
||||
const caHdrLargeArray * mp = this->ctx.getMsg ();
|
||||
const void * dp = this->ctx.getData ();
|
||||
casChannelI *pciu;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Verify the channel
|
||||
*/
|
||||
pciu = this->resIdToChannel ( mp->m_cid );
|
||||
casChannelI *pciu = this->resIdToChannel ( mp->m_cid );
|
||||
if ( ! pciu ) {
|
||||
/*
|
||||
* it is possible that the event delete arrives just
|
||||
@@ -1409,27 +1397,21 @@ caStatus casStrmClient::eventCancelAction ()
|
||||
return S_cas_badResourceId;
|
||||
}
|
||||
|
||||
/*
|
||||
* verify the event (monitor)
|
||||
*/
|
||||
tsDLIter <casMonitor> pMon = pciu->findMonitor ( mp->m_available );
|
||||
if ( ! pMon.valid () ) {
|
||||
//
|
||||
// this indicates client or server library corruption so a
|
||||
// disconnect is the best response
|
||||
//
|
||||
logBadId ( mp, dp, ECA_BADMONID, mp->m_available );
|
||||
return S_cas_badResourceId;
|
||||
}
|
||||
|
||||
unsigned type = pMon->getType ();
|
||||
assert ( type <= 0xff );
|
||||
status = this->out.copyInHeader ( CA_PROTO_EVENT_ADD, 0,
|
||||
static_cast <unsigned char> ( type ), pMon->getCount (),
|
||||
pciu->getCID (), pMon->getClientId (), 0 );
|
||||
int status = this->out.copyInHeader (
|
||||
CA_PROTO_EVENT_ADD, 0,
|
||||
mp->m_dataType, mp->m_count,
|
||||
pciu->getCID (), mp->m_available, 0 );
|
||||
if ( ! status ) {
|
||||
if ( ! pciu->unistallMonitor ( mp->m_available ) ) {
|
||||
//
|
||||
// this indicates client or server library
|
||||
// corruption so a disconnect is probably
|
||||
// the best option
|
||||
//
|
||||
logBadId ( mp, dp, ECA_BADMONID, mp->m_available );
|
||||
status = S_cas_badResourceId;
|
||||
}
|
||||
this->out.commitMsg ();
|
||||
pMon->destroy ();
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -1444,10 +1426,10 @@ caStatus casStrmClient::eventCancelAction ()
|
||||
*/
|
||||
caStatus casStrmClient::noReadAccessEvent(casClientMon *pMon)
|
||||
{
|
||||
caHdr falseReply;
|
||||
unsigned size;
|
||||
caHdr *reply;
|
||||
int status;
|
||||
caHdr falseReply;
|
||||
unsigned size;
|
||||
caHdr * reply;
|
||||
int status;
|
||||
|
||||
size = dbr_size_n ( pMon->getType(), pMon->getCount() );
|
||||
|
||||
@@ -1581,7 +1563,7 @@ caStatus casStrmClient::write()
|
||||
(* cac_dbr_cvrt[pHdr->m_dataType])
|
||||
( this->ctx.getData(),
|
||||
this->ctx.getData(),
|
||||
FALSE, /* net -> host format */
|
||||
false, /* net -> host format */
|
||||
pHdr->m_count);
|
||||
#endif
|
||||
|
||||
@@ -1973,5 +1955,32 @@ void casStrmClient::flush ()
|
||||
this->out.flush ();
|
||||
}
|
||||
|
||||
//
|
||||
// casStrmClient::casMonitorCallBack()
|
||||
//
|
||||
caStatus casStrmClient::casMonitorCallBack (
|
||||
casMonitor & mon, const smartConstGDDPointer & value )
|
||||
{
|
||||
caStatus status;
|
||||
caHdrLargeArray msg;
|
||||
|
||||
//
|
||||
// reconstruct the msg header
|
||||
//
|
||||
msg.m_cmmd = CA_PROTO_EVENT_ADD;
|
||||
msg.m_postsize = 0u;
|
||||
unsigned type = mon.getType();
|
||||
assert ( type <= 0xffff );
|
||||
msg.m_dataType = static_cast <ca_uint16_t> ( type );
|
||||
unsigned long count = mon.getCount();
|
||||
assert ( count <= 0xffffffff );
|
||||
msg.m_count = static_cast <ca_uint32_t> ( count );
|
||||
msg.m_cid = mon.getChannel().getSID();
|
||||
msg.m_available = mon.getClientId();
|
||||
|
||||
status = this->monitorResponse ( mon.getChannel(),
|
||||
msg, value, S_cas_success );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -601,6 +601,7 @@ public:
|
||||
//
|
||||
epicsShareFunc casPV *getPV ();
|
||||
|
||||
private:
|
||||
casChannel ( const casChannel & );
|
||||
casChannel & operator = ( const casChannel & );
|
||||
|
||||
|
||||
@@ -96,83 +96,6 @@ typedef caResId caEventId;
|
||||
//
|
||||
class caServerI;
|
||||
|
||||
//
|
||||
// casEventSys
|
||||
//
|
||||
class casEventSys {
|
||||
friend class casEventPurgeEv;
|
||||
public:
|
||||
casEventSys ();
|
||||
virtual ~casEventSys ();
|
||||
|
||||
void show (unsigned level) const;
|
||||
casProcCond process ();
|
||||
|
||||
void installMonitor ();
|
||||
void removeMonitor ();
|
||||
|
||||
void removeFromEventQueue (casEvent &);
|
||||
void addToEventQueue (casEvent &);
|
||||
|
||||
void insertEventQueue (casEvent &insert, casEvent &prevEvent);
|
||||
void pushOnToEventQueue (casEvent &event);
|
||||
|
||||
bool full ();
|
||||
|
||||
casMonitor *resIdToMon (const caResId id);
|
||||
|
||||
bool getNDuplicateEvents () const;
|
||||
|
||||
void setDestroyPending ();
|
||||
|
||||
void eventsOn ();
|
||||
|
||||
caStatus eventsOff ();
|
||||
|
||||
virtual caStatus disconnectChan (caResId id) = 0;
|
||||
|
||||
private:
|
||||
tsDLList<casEvent> eventLogQue;
|
||||
epicsMutex mutex;
|
||||
casEventPurgeEv *pPurgeEvent; // flow control purge complete event
|
||||
unsigned numEventBlocks; // N event blocks installed
|
||||
unsigned maxLogEntries; // max log entries
|
||||
unsigned char destroyPending;
|
||||
unsigned char replaceEvents; // replace last existing event on queue
|
||||
unsigned char dontProcess; // flow ctl is on - dont process event queue
|
||||
|
||||
virtual void eventFlush () = 0;
|
||||
virtual void eventSignal () = 0;
|
||||
virtual casRes *lookupRes (const caResId &idIn, casResType type) = 0;
|
||||
casEventSys ( const casEventSys & );
|
||||
casEventSys & operator = ( const casEventSys & );
|
||||
};
|
||||
|
||||
//
|
||||
// casClientMon
|
||||
//
|
||||
class casClientMon : public casMonitor {
|
||||
public:
|
||||
casClientMon(casChannelI &, caResId clientId,
|
||||
const unsigned long count, const unsigned type,
|
||||
const casEventMask &maskIn, epicsMutex &mutexIn);
|
||||
virtual ~casClientMon();
|
||||
|
||||
caStatus callBack (const smartConstGDDPointer &pValue);
|
||||
|
||||
virtual casResType resourceType() const;
|
||||
|
||||
caResId getId() const
|
||||
{
|
||||
return this->casRes::getId();
|
||||
}
|
||||
|
||||
virtual void destroy();
|
||||
private:
|
||||
casClientMon ( const casClientMon & );
|
||||
casClientMon & operator = ( const casClientMon & );
|
||||
};
|
||||
|
||||
class casCtx {
|
||||
public:
|
||||
casCtx();
|
||||
@@ -195,7 +118,7 @@ public:
|
||||
|
||||
void setPV ( casPVI * p );
|
||||
|
||||
void setChannel ( casChannelI * p );
|
||||
void setChannel ( casChannelI * p );
|
||||
|
||||
void show ( unsigned level ) const;
|
||||
|
||||
@@ -430,25 +353,89 @@ private:
|
||||
outBuf & operator = ( const outBuf & );
|
||||
};
|
||||
|
||||
//
|
||||
// casEventSys
|
||||
//
|
||||
class casEventSys {
|
||||
public:
|
||||
casEventSys ( casCoreClient & );
|
||||
~casEventSys ();
|
||||
|
||||
void show ( unsigned level ) const;
|
||||
struct processStatus {
|
||||
casProcCond cond;
|
||||
unsigned nAccepted;
|
||||
};
|
||||
processStatus process ();
|
||||
|
||||
void installMonitor ();
|
||||
void removeMonitor ();
|
||||
|
||||
void removeFromEventQueue ( casEvent & );
|
||||
void addToEventQueue ( casEvent & );
|
||||
|
||||
void insertEventQueue ( casEvent & insert, casEvent & prevEvent );
|
||||
void pushOnToEventQueue ( casEvent & event );
|
||||
|
||||
bool full ();
|
||||
|
||||
bool getNDuplicateEvents () const;
|
||||
|
||||
void setDestroyPending ();
|
||||
|
||||
void eventsOn ();
|
||||
void eventsOff ();
|
||||
|
||||
private:
|
||||
tsDLList < casEvent > eventLogQue;
|
||||
epicsMutex mutex;
|
||||
casCoreClient & client;
|
||||
class casEventPurgeEv * pPurgeEvent; // flow control purge complete event
|
||||
unsigned numEventBlocks; // N event blocks installed
|
||||
unsigned maxLogEntries; // max log entries
|
||||
bool destroyPending;
|
||||
bool replaceEvents; // replace last existing event on queue
|
||||
bool dontProcess; // flow ctl is on - dont process event queue
|
||||
|
||||
casEventSys ( const casEventSys & );
|
||||
casEventSys & operator = ( const casEventSys & );
|
||||
friend class casEventPurgeEv;
|
||||
};
|
||||
|
||||
/*
|
||||
* when this event reaches the top of the queue we
|
||||
* know that all duplicate events have been purged
|
||||
* and that now no events should not be sent to the
|
||||
* client until it exits flow control mode
|
||||
*/
|
||||
class casEventPurgeEv : public casEvent {
|
||||
public:
|
||||
casEventPurgeEv ( class casEventSys & );
|
||||
private:
|
||||
casEventSys & evSys;
|
||||
caStatus cbFunc ( casCoreClient & );
|
||||
void eventSysDestroyNotify ( casCoreClient & );
|
||||
};
|
||||
|
||||
//
|
||||
// casCoreClient
|
||||
// (this will eventually support direct communication
|
||||
// between the client lib and the server lib)
|
||||
//
|
||||
class casCoreClient : public ioBlocked,
|
||||
public casEventSys {
|
||||
class casCoreClient : public ioBlocked,
|
||||
private casMonitorCallbackInterface {
|
||||
public:
|
||||
casCoreClient ( caServerI &serverInternal );
|
||||
virtual ~casCoreClient();
|
||||
virtual void destroy();
|
||||
casCoreClient ( caServerI & serverInternal );
|
||||
virtual ~casCoreClient ();
|
||||
virtual void destroy ();
|
||||
virtual caStatus disconnectChan( caResId id );
|
||||
virtual void show (unsigned level ) const;
|
||||
virtual void show ( unsigned level ) const;
|
||||
virtual void installChannel ( casChannelI & );
|
||||
virtual void removeChannel ( casChannelI & );
|
||||
|
||||
void installAsyncIO( casAsyncIOI & ioIn );
|
||||
void installAsyncIO ( casAsyncIOI & ioIn );
|
||||
|
||||
void removeAsyncIO( casAsyncIOI & ioIn );
|
||||
void removeAsyncIO ( casAsyncIOI & ioIn );
|
||||
|
||||
casRes * lookupRes ( const caResId &idIn, casResType type );
|
||||
|
||||
@@ -481,6 +468,8 @@ public:
|
||||
virtual caStatus channelCreateFailedResp ( const caHdrLargeArray &,
|
||||
caStatus createStatus );
|
||||
|
||||
virtual void eventSignal () = 0;
|
||||
|
||||
virtual ca_uint16_t protocolRevision () const = 0;
|
||||
|
||||
//
|
||||
@@ -491,12 +480,42 @@ public:
|
||||
|
||||
bool okToStartAsynchIO ();
|
||||
|
||||
casMonEvent & casMonEventFactory ( casMonitor & monitor,
|
||||
const smartConstGDDPointer & pNewValue );
|
||||
void casMonEventDestroy ( casMonEvent & );
|
||||
|
||||
casEventSys::processStatus eventSysProcess();
|
||||
|
||||
void addToEventQueue ( casEvent & );
|
||||
void insertEventQueue ( casEvent & insert,
|
||||
casEvent & prevEvent );
|
||||
void removeFromEventQueue ( casEvent & );
|
||||
void enableEvents ();
|
||||
void disableEvents ();
|
||||
bool eventSysIsFull ();
|
||||
void installMonitor ();
|
||||
void removeMonitor ();
|
||||
|
||||
void setDestroyPending ();
|
||||
|
||||
casMonitor & monitorFactory (
|
||||
casChannelI & ,
|
||||
caResId clientId,
|
||||
const unsigned long count,
|
||||
const unsigned type,
|
||||
const casEventMask & );
|
||||
void destroyMonitor ( casMonitor & );
|
||||
|
||||
caStatus casMonitorCallBack ( casMonitor &,
|
||||
const smartConstGDDPointer & );
|
||||
|
||||
protected:
|
||||
epicsMutex mutex;
|
||||
casCtx ctx;
|
||||
bool asyncIOFlag;
|
||||
|
||||
private:
|
||||
casEventSys eventSys;
|
||||
tsDLList < casAsyncIOI > ioInProgList;
|
||||
casCoreClient ( const casCoreClient & );
|
||||
casCoreClient & operator = ( const casCoreClient & );
|
||||
@@ -585,7 +604,7 @@ private:
|
||||
//
|
||||
static void loadProtoJumpTable();
|
||||
static pCASMsgHandler msgHandlers[CA_PROTO_LAST_CMMD+1u];
|
||||
static int msgHandlersInit;
|
||||
static bool msgHandlersInit;
|
||||
|
||||
casClient ( const casClient & );
|
||||
casClient & operator = ( const casClient & );
|
||||
@@ -594,13 +613,14 @@ private:
|
||||
//
|
||||
// casStrmClient
|
||||
//
|
||||
class casStrmClient : public casClient,
|
||||
class casStrmClient :
|
||||
public casClient,
|
||||
public tsDLNode<casStrmClient> {
|
||||
public:
|
||||
casStrmClient ( caServerI &, clientBufMemoryManager & );
|
||||
virtual ~casStrmClient();
|
||||
|
||||
void show (unsigned level) const;
|
||||
void show ( unsigned level ) const;
|
||||
|
||||
void flush ();
|
||||
|
||||
@@ -632,9 +652,6 @@ public:
|
||||
caStatus channelCreateFailedResp ( const caHdrLargeArray &,
|
||||
caStatus createStatus );
|
||||
|
||||
caStatus noReadAccessEvent( casClientMon * );
|
||||
|
||||
|
||||
caStatus disconnectChan ( caResId id );
|
||||
|
||||
unsigned getDebugLevel () const;
|
||||
@@ -642,8 +659,6 @@ public:
|
||||
virtual void hostName ( char * pBuf, unsigned bufSize ) const = 0;
|
||||
void userName ( char * pBuf, unsigned bufSize ) const;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
tsDLList<casChannelI> chanList;
|
||||
char *pUserName;
|
||||
@@ -716,6 +731,9 @@ private:
|
||||
caStatus writeNotifyResponseECA_XXX ( const caHdrLargeArray &msg,
|
||||
const caStatus status );
|
||||
|
||||
caStatus casMonitorCallBack ( casMonitor &,
|
||||
const smartConstGDDPointer & pValue );
|
||||
|
||||
casStrmClient ( const casStrmClient & );
|
||||
casStrmClient & operator = ( const casStrmClient & );
|
||||
};
|
||||
@@ -754,11 +772,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
casProcCond eventSysProcess()
|
||||
{
|
||||
return this->casEventSys::process();
|
||||
}
|
||||
|
||||
caStatus processDG ();
|
||||
|
||||
private:
|
||||
@@ -906,9 +919,9 @@ public:
|
||||
|
||||
caServer *getAdapter ();
|
||||
|
||||
void installItem (casRes &res);
|
||||
void installItem ( casRes & res );
|
||||
|
||||
casRes *removeItem (casRes &res);
|
||||
casRes * removeItem ( casRes & res );
|
||||
|
||||
//
|
||||
// call virtual function in the interface class
|
||||
@@ -936,24 +949,36 @@ public:
|
||||
|
||||
void generateBeaconAnomaly ();
|
||||
|
||||
casMonEvent & casMonEventFactory ( casMonitor & monitor,
|
||||
const smartConstGDDPointer & pNewValue );
|
||||
void casMonEventDestroy ( casMonEvent & );
|
||||
|
||||
casMonitor & casMonitorFactory ( casChannelI &,
|
||||
caResId clientId, const unsigned long count,
|
||||
const unsigned type, const casEventMask &,
|
||||
epicsMutex & , casMonitorCallbackInterface & );
|
||||
void casMonitorDestroy ( casMonitor & );
|
||||
|
||||
private:
|
||||
clientBufMemoryManager clientBufMemMgr;
|
||||
mutable epicsMutex mutex;
|
||||
tsDLList<casStrmClient> clientList;
|
||||
tsDLList<casIntfOS> intfList;
|
||||
caServer & adapter;
|
||||
beaconTimer & beaconTmr;
|
||||
beaconAnomalyGovernor & beaconAnomalyGov;
|
||||
unsigned debugLevel;
|
||||
unsigned nEventsProcessed;
|
||||
unsigned nEventsPosted;
|
||||
clientBufMemoryManager clientBufMemMgr;
|
||||
mutable epicsMutex mutex;
|
||||
tsDLList < casStrmClient > clientList;
|
||||
tsDLList < casIntfOS > intfList;
|
||||
tsFreeList < casMonEvent, 1024 > casMonEventFreeList;
|
||||
tsFreeList < casMonitor, 1024 > casMonitorFreeList;
|
||||
caServer & adapter;
|
||||
beaconTimer & beaconTmr;
|
||||
beaconAnomalyGovernor & beaconAnomalyGov;
|
||||
unsigned debugLevel;
|
||||
unsigned nEventsProcessed;
|
||||
unsigned nEventsPosted;
|
||||
|
||||
//
|
||||
// predefined event types
|
||||
//
|
||||
casEventMask valueEvent; // DBE_VALUE registerEvent("value")
|
||||
casEventMask logEvent; // DBE_LOG registerEvent("log")
|
||||
casEventMask alarmEvent; // DBE_ALARM registerEvent("alarm")
|
||||
casEventMask valueEvent; // DBE_VALUE registerEvent("value")
|
||||
casEventMask logEvent; // DBE_LOG registerEvent("log")
|
||||
casEventMask alarmEvent; // DBE_ALARM registerEvent("alarm")
|
||||
|
||||
caStatus attachInterface (const caNetAddr &addr, bool autoBeaconAddr,
|
||||
bool addConfigAddr);
|
||||
@@ -978,18 +1003,6 @@ private:
|
||||
*/
|
||||
#define maxIOInProg 50
|
||||
|
||||
/*
|
||||
* when this event reaches the top of the queue we
|
||||
* know that all duplicate events have been purged
|
||||
* and that now no events should not be sent to the
|
||||
* client until it exits flow control mode
|
||||
*/
|
||||
class casEventPurgeEv : public casEvent {
|
||||
public:
|
||||
private:
|
||||
caStatus cbFunc(casEventSys &);
|
||||
};
|
||||
|
||||
bool convertContainerMemberToAtomic ( gdd & dd,
|
||||
aitUint32 appType, aitUint32 elemCount );
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "inBufIL.h" // inBuf in line func
|
||||
#include "outBufIL.h" // outBuf in line func
|
||||
#include "casIODIL.h" // IO Depen in line func
|
||||
#include "casCoreClientIL.h"
|
||||
|
||||
//
|
||||
// casDGReadReg
|
||||
@@ -145,7 +146,10 @@ void casDGEvWakeup::show ( unsigned level ) const
|
||||
//
|
||||
epicsTimerNotify::expireStatus casDGEvWakeup::expire ( const epicsTime & /* currentTime */ )
|
||||
{
|
||||
this->pOS->casEventSys::process();
|
||||
casEventSys::processStatus ps = this->pOS->eventSysProcess ();
|
||||
if ( ps.nAccepted > 0u ) {
|
||||
this->pOS->eventFlush ();
|
||||
}
|
||||
this->pOS = 0;
|
||||
return noRestart;
|
||||
}
|
||||
@@ -441,7 +445,7 @@ void casDGIntfOS::sendCB()
|
||||
// we _are_ able to write to see if additional events
|
||||
// can be sent to the slow client.
|
||||
//
|
||||
this->casEventSys::process();
|
||||
this->eventSysProcess ();
|
||||
|
||||
//
|
||||
// If we were able to send something then we need
|
||||
|
||||
@@ -100,6 +100,8 @@ public:
|
||||
|
||||
void processInput();
|
||||
|
||||
void eventFlush ();
|
||||
|
||||
private:
|
||||
casDGIOWakeup ioWk;
|
||||
casDGEvWakeup evWk;
|
||||
@@ -122,7 +124,6 @@ private:
|
||||
void ioBlockedSignal ();
|
||||
|
||||
void eventSignal ();
|
||||
void eventFlush ();
|
||||
|
||||
casDGIntfOS ( const casDGIntfOS & );
|
||||
casDGIntfOS & operator = ( const casDGIntfOS & );
|
||||
@@ -199,6 +200,8 @@ public:
|
||||
|
||||
casProcCond processInput ();
|
||||
|
||||
void eventFlush ();
|
||||
|
||||
private:
|
||||
casStreamEvWakeup evWk;
|
||||
casStreamIOWakeup ioWk;
|
||||
@@ -221,7 +224,6 @@ private:
|
||||
void ioBlockedSignal ();
|
||||
|
||||
void eventSignal ();
|
||||
void eventFlush ();
|
||||
|
||||
casStreamOS ( const casStreamOS & );
|
||||
casStreamOS & operator = ( const casStreamOS & );
|
||||
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
// casStreamWriteReg::casStreamWriteReg()
|
||||
//
|
||||
inline casStreamWriteReg::casStreamWriteReg (casStreamOS &osIn) :
|
||||
fdReg (osIn.getFD(), fdrWrite, TRUE), os (osIn)
|
||||
fdReg (osIn.getFD(), fdrWrite, true), os (osIn)
|
||||
{
|
||||
# if defined(DEBUG)
|
||||
printf ("Write on %d\n", this->os.getFD());
|
||||
@@ -148,10 +148,14 @@ void casStreamEvWakeup::show(unsigned level) const
|
||||
//
|
||||
epicsTimerNotify::expireStatus casStreamEvWakeup::expire ( const epicsTime & /* currentTime */ )
|
||||
{
|
||||
casStreamOS &os = *this->pOS;
|
||||
casStreamOS & os = *this->pOS;
|
||||
this->pOS = 0;
|
||||
casProcCond cond = os.casEventSys::process();
|
||||
if ( cond != casProcOk ) {
|
||||
|
||||
casEventSys::processStatus ps = os.eventSysProcess ();
|
||||
if ( ps.nAccepted > 0u ) {
|
||||
os.eventFlush ();
|
||||
}
|
||||
if ( ps.cond != casProcOk ) {
|
||||
//
|
||||
// ok to delete the client here
|
||||
// because casStreamEvWakeup::expire()
|
||||
@@ -396,20 +400,17 @@ void casStreamReadReg::callBack ()
|
||||
//
|
||||
void casStreamOS::recvCB()
|
||||
{
|
||||
inBufClient::fillCondition fillCond;
|
||||
casProcCond procCond;
|
||||
|
||||
assert ( this->pRdReg );
|
||||
|
||||
//
|
||||
// copy in new messages
|
||||
//
|
||||
fillCond = this->in.fill();
|
||||
inBufClient::fillCondition fillCond = this->in.fill();
|
||||
if ( fillCond == casFillDisconnect ) {
|
||||
delete this;
|
||||
}
|
||||
else {
|
||||
procCond = this->processInput();
|
||||
casProcCond procCond = this->processInput();
|
||||
if (procCond == casProcDisconnect) {
|
||||
delete this;
|
||||
}
|
||||
@@ -438,8 +439,8 @@ void casStreamOS::recvCB()
|
||||
//
|
||||
void casStreamOS::sendBlockSignal()
|
||||
{
|
||||
this->sendBlocked=TRUE;
|
||||
this->armSend();
|
||||
this->sendBlocked = true;
|
||||
this->armSend ();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -470,16 +471,13 @@ void casStreamWriteReg::callBack()
|
||||
//
|
||||
void casStreamOS::sendCB()
|
||||
{
|
||||
outBufClient::flushCondition flushCond;
|
||||
casProcCond procCond;
|
||||
|
||||
//
|
||||
// attempt to flush the output buffer
|
||||
//
|
||||
flushCond = this->out.flush ();
|
||||
outBufClient::flushCondition flushCond = this->out.flush ();
|
||||
if (flushCond==flushProgress) {
|
||||
if (this->sendBlocked) {
|
||||
this->sendBlocked = FALSE;
|
||||
if ( this->sendBlocked ) {
|
||||
this->sendBlocked = false;
|
||||
}
|
||||
}
|
||||
else if ( flushCond == outBufClient::flushDisconnect ) {
|
||||
@@ -506,8 +504,8 @@ void casStreamOS::sendCB()
|
||||
// we _are_ able to write to see if additional events
|
||||
// can be sent to the slow client.
|
||||
//
|
||||
procCond = this->casEventSys::process();
|
||||
if (procCond != casProcOk) {
|
||||
casEventSys::processStatus ps = this->eventSysProcess ();
|
||||
if ( ps.cond != casProcOk ) {
|
||||
//
|
||||
// ok to delete the client here
|
||||
// because casStreamWriteReg::callBack()
|
||||
@@ -536,7 +534,7 @@ void casStreamOS::sendCB()
|
||||
// to process the input queue in case we were send
|
||||
// blocked.
|
||||
//
|
||||
procCond = this->processInput();
|
||||
casProcCond procCond = this->processInput();
|
||||
if (procCond == casProcDisconnect) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ inline void caServerIO::staticInit()
|
||||
|
||||
epicsSignalInstallSigPipeIgnore ();
|
||||
|
||||
caServerIO::staticInitialized = TRUE;
|
||||
caServerIO::staticInitialized = true;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -293,7 +293,7 @@ void casDGIntfIO::show (unsigned level) const
|
||||
void casDGIntfIO::xSetNonBlocking()
|
||||
{
|
||||
int status;
|
||||
osiSockIoctl_t yes = TRUE;
|
||||
osiSockIoctl_t yes = true;
|
||||
|
||||
status = socket_ioctl(this->sock, FIONBIO, &yes); // X aCC 392
|
||||
if (status<0) {
|
||||
@@ -544,7 +544,7 @@ bufSizeT casDGIntfIO::optimumOutBufferSize ()
|
||||
//
|
||||
SOCKET casDGIntfIO::makeSockDG ()
|
||||
{
|
||||
int yes = TRUE;
|
||||
int yes = true;
|
||||
int status;
|
||||
SOCKET newSock;
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ casIntfIO::casIntfIO (const caNetAddr &addrIn) :
|
||||
* they exit ( even if SO_REUSEADDR isnt set ).
|
||||
*/
|
||||
# ifndef SO_REUSEADDR_ALLOWS_SIMULTANEOUS_TCP_SERVERS_TO_USE_SAME_PORT
|
||||
int yes = TRUE;
|
||||
int yes = true;
|
||||
status = setsockopt (
|
||||
this->sock,
|
||||
SOL_SOCKET,
|
||||
@@ -203,7 +203,7 @@ casStreamOS *casIntfIO::newStreamClient ( caServerI & cas,
|
||||
void casIntfIO::setNonBlocking()
|
||||
{
|
||||
int status;
|
||||
osiSockIoctl_t yes = TRUE;
|
||||
osiSockIoctl_t yes = true;
|
||||
|
||||
status = socket_ioctl(this->sock, FIONBIO, &yes); // X aCC 392
|
||||
if (status<0) {
|
||||
|
||||
@@ -22,7 +22,7 @@ casStreamIO::casStreamIO ( caServerI & cas, clientBufMemoryManager & bufMgr,
|
||||
blockingFlag ( xIsBlocking )
|
||||
{
|
||||
assert (sock>=0);
|
||||
int yes = TRUE;
|
||||
int yes = true;
|
||||
int status;
|
||||
|
||||
/*
|
||||
@@ -129,16 +129,16 @@ outBufClient::flushCondition casStreamIO::osdSend ( const char *pInBuf, bufSizeT
|
||||
int anerrno = SOCKERRNO;
|
||||
|
||||
if (anerrno != SOCK_EWOULDBLOCK) {
|
||||
char buf[64];
|
||||
int errnoCpy = SOCKERRNO;
|
||||
|
||||
ipAddrToA (&this->addr, buf, sizeof(buf));
|
||||
|
||||
if (
|
||||
errnoCpy != SOCK_ECONNABORTED &&
|
||||
errnoCpy != SOCK_ECONNRESET &&
|
||||
errnoCpy != SOCK_EPIPE &&
|
||||
errnoCpy != SOCK_ETIMEDOUT ) {
|
||||
|
||||
char buf[64];
|
||||
ipAddrToA (&this->addr, buf, sizeof(buf));
|
||||
|
||||
errlogPrintf(
|
||||
"CAS: TCP socket send to \"%s\" failed because \"%s\"\n",
|
||||
buf, SOCKERRSTR(errnoCpy));
|
||||
@@ -215,7 +215,7 @@ void casStreamIO::osdShow (unsigned level) const
|
||||
void casStreamIO::xSetNonBlocking()
|
||||
{
|
||||
int status;
|
||||
osiSockIoctl_t yes = TRUE;
|
||||
osiSockIoctl_t yes = true;
|
||||
|
||||
status = socket_ioctl(this->sock, FIONBIO, &yes); // X aCC 392
|
||||
if (status>=0) {
|
||||
|
||||
Reference in New Issue
Block a user