Files
epics-base/src/cas/generic/casMonitor.cc
2003-02-12 19:06:15 +00:00

173 lines
4.6 KiB
C++

/*************************************************************************\
* 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
*/
#define epicsExportSharedSymbols
#include "casMonitor.h"
#include "casChannelI.h"
casEvent::~casEvent () {}
casMonitor::casMonitor (
caResId clientIdIn,
casChannelI & chan,
ca_uint32_t nElemIn,
unsigned dbrTypeIn,
const casEventMask & maskIn,
casMonitorCallbackInterface & cb ) :
overFlowEvent ( *this ),
nElem ( nElemIn ),
pChannel ( & chan ),
callBackIntf ( cb ),
mask ( maskIn ),
clientId ( clientIdIn ),
dbrType ( static_cast <unsigned char> ( dbrTypeIn ) ),
nPend ( 0u ),
ovf ( false )
{
assert ( dbrTypeIn <= 0xff );
}
casMonitor::~casMonitor()
{
}
caStatus casMonitor::response ( casCoreClient & client,
const smartConstGDDPointer & value )
{
if ( this->pChannel ) {
// reconstruct request header
caHdrLargeArray msg;
msg.m_cmmd = CA_PROTO_EVENT_ADD;
msg.m_postsize = 0u;
msg.m_dataType = this->dbrType;
msg.m_count = this->nElem;
msg.m_cid = this->pChannel->getSID();
msg.m_available = this->clientId;
return client.monitorResponse ( *this->pChannel,
msg, value, S_cas_success );
}
else {
return S_cas_success;
}
}
void casMonitor::installNewEventLog (
tsDLList < casEvent > & eventLogQue,
casMonEvent * pLog, const gdd & event )
{
if ( this->ovf ) {
if ( pLog ) {
pLog->assign ( event );
this->overFlowEvent.swapValues ( *pLog );
eventLogQue.insertAfter ( *pLog, this->overFlowEvent );
assert ( this->nPend != UCHAR_MAX );
this->nPend++; // X aCC 818
}
else {
// replace the old OVF value with the current one
this->overFlowEvent.assign ( event );
}
// remove OVF entry (with its new value) from the queue so
// that it ends up properly ordered at the back of the
// queue
eventLogQue.remove ( this->overFlowEvent );
pLog = & this->overFlowEvent;
}
else {
if ( pLog == 0 ) {
// use the over flow block in the event structure
this->ovf = true;
pLog = & this->overFlowEvent;
}
pLog->assign ( event );
assert ( this->nPend != UCHAR_MAX );
this->nPend++; // X aCC 818
}
eventLogQue.add ( *pLog );
}
caStatus casMonitor::executeEvent ( casCoreClient & client,
casMonEvent & ev, smartConstGDDPointer & pValue,
epicsGuard < epicsMutex > & guard )
{
assert ( pValue.valid() );
if ( this->pChannel ) {
epicsGuardRelease < epicsMutex > unguard ( guard );
caStatus status = this->callBackIntf.casMonitorCallBack (
*this, pValue );
if ( status != S_cas_success ) {
return status;
}
}
client.getCAS().incrEventsProcessedCounter ();
assert ( this->nPend != 0u );
this->nPend--; // X aCC 818
// delete event object if it isnt a cache entry
// saved in the call back object
if ( & ev == & this->overFlowEvent ) {
assert ( this->ovf );
this->ovf = false;
this->overFlowEvent.clear ();
}
else {
client.casMonEventDestroy ( ev, guard );
}
if ( ! this->pChannel && this->nPend == 0 ) {
// we are careful here not to invert
// the lock hierarchy
epicsGuardRelease < epicsMutex > unguard ( guard );
client.destroyMonitor ( *this );
}
return S_cas_success;
}
void casMonitor::show ( unsigned level ) const
{
if ( level > 1u ) {
printf (
"\tmonitor type=%u count=%lu client id=%u OVF=%u nPend=%u\n",
dbrType, nElem, clientId, ovf, nPend );
this->mask.show ( level );
}
}
void * casMonitor::operator new (
size_t size,
tsFreeList < casMonitor, 1024 > & freeList )
{
return freeList.allocate ( size );
}
#ifdef CXX_PLACEMENT_DELETE
void casMonitor::operator delete ( void * pCadaver,
tsFreeList < casMonitor, 1024 > & freeList )
{
freeList.release ( pCadaver );
}
#endif
void casMonitor::operator delete ( void * )
{
errlogPrintf ( "casMonitor: compiler is confused "
"about placement delete?\n" );
}