some initial steps towards fre list based memory management

This commit is contained in:
Jeff Hill
2002-12-06 00:05:55 +00:00
parent 467ff91c4f
commit cd52995cfa
38 changed files with 928 additions and 812 deletions

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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 ();

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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 ()
{
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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 );
}

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 );
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 & );

View File

@@ -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__ );
}

View File

@@ -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" );
}

View File

@@ -31,7 +31,7 @@ casOpaqueAddr::casOpaqueAddr()
//
void casOpaqueAddr::clear()
{
this->init = 0;
this->init = false;
}

View File

@@ -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

View File

@@ -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 ();
}

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -601,6 +601,7 @@ public:
//
epicsShareFunc casPV *getPV ();
private:
casChannel ( const casChannel & );
casChannel & operator = ( const casChannel & );

View File

@@ -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 );

View File

@@ -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

View File

@@ -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 & );

View File

@@ -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;
}

View File

@@ -149,7 +149,7 @@ inline void caServerIO::staticInit()
epicsSignalInstallSigPipeIgnore ();
caServerIO::staticInitialized = TRUE;
caServerIO::staticInitialized = true;
}
//

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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) {