redesigned mutex locking

This commit is contained in:
Jeff Hill
2003-01-08 23:22:08 +00:00
parent 7cf6e3bcdd
commit adb0b5d9eb
19 changed files with 270 additions and 302 deletions

View File

@@ -79,7 +79,7 @@ caServerI::~caServerI()
//
// destructor takes client out of list
//
iter->destroy ();
delete iter.pointer ();
iter = tmp;
}

View File

@@ -151,12 +151,12 @@ inline void caServerI::casMonEventDestroy ( casMonEvent & monEvent )
inline casMonitor & caServerI::casMonitorFactory (
casChannelI & chan, caResId clientId,
const unsigned long count, const unsigned type,
const casEventMask & mask, epicsMutex & mutexIn,
const casEventMask & mask,
casMonitorCallbackInterface & cb )
{
casMonitor * pMon =
new ( this->casMonitorFreeList ) casMonitor
( clientId, chan, count, type, mask, mutexIn, cb );
( clientId, chan, count, type, mask, cb );
this->installItem ( *pMon );
return *pMon;
}

View File

@@ -84,30 +84,20 @@ casAsyncIOI::~casAsyncIOI()
"WARNING: by deleting the async IO object.\n");
}
epicsGuard < casCoreClient > guard ( this->client );
//
// pulls itself out of the event queue
// if it is installed there
// if it is installed there.
//
if ( this->inTheEventQueue ) {
this->client.removeFromEventQueue ( *this );
}
this->client.removeFromEventQueue ( *this );
}
//
// casAsyncIOI::cbFunc()
// (called when IO completion event reaches top of event queue)
// o called when IO completion event reaches top of event queue
// o clients lock is applied when calling this
//
caStatus casAsyncIOI::cbFunc ( casCoreClient & )
{
//
// Use the client's lock here (which is the same as the
// asynch IO's lock) here because we need to leave the lock
// applied around the destroy() call here.
//
epicsGuard < casCoreClient > guard ( this->client );
this->inTheEventQueue = false;
caStatus status = this->cbFuncAsyncIO();
@@ -140,9 +130,9 @@ void casAsyncIOI::eventSysDestroyNotify ( casCoreClient & )
}
//
// casAsyncIOI::postIOCompletionI()
// casAsyncIOI::postIOCompletionI ()
//
caStatus casAsyncIOI::postIOCompletionI()
caStatus casAsyncIOI::postIOCompletionI ()
{
//
// detect the case where the server called destroy(),
@@ -154,10 +144,10 @@ caStatus casAsyncIOI::postIOCompletionI()
return S_cas_redundantPost;
}
epicsGuard < casCoreClient > guard ( this->client );
if (this->duplicate) {
errMessage(S_cas_badParameter,
// this is only touched in the constructor so its
// ok not to not take a lock here
if ( this->duplicate ) {
errMessage ( S_cas_badParameter,
"- duplicate async IO");
//
// dont use "this" after potentially destroying the
@@ -167,24 +157,12 @@ caStatus casAsyncIOI::postIOCompletionI()
return S_cas_redundantPost;
}
//
// verify that they dont post completion more than once
//
if ( this->posted ) {
return S_cas_redundantPost;
}
//
// dont call the server tool's cancel() when this object deletes
//
this->posted = true;
//
// place this event in the event queue
// (this also signals the event consumer)
// o this also signals the event consumer
// o clients lock protects list and flag
//
this->inTheEventQueue = true;
this->client.addToEventQueue ( *this );
return this->client.addToEventQueue ( *this, this->inTheEventQueue, this->posted );
return S_cas_success;
}
@@ -211,16 +189,11 @@ bool casAsyncIOI::readOP() const
//
// casAsyncIOI::serverDestroyIfReadOP()
// o clients lock is held when this is called
//
void casAsyncIOI::serverDestroyIfReadOP()
{
//
// client lock used because this object's
// lock may be destroyed
//
epicsGuard < casCoreClient > guard ( this->client );
if (this->readOP()) {
{
if ( this->readOP() ) {
this->serverDestroy();
}

View File

@@ -37,29 +37,24 @@ casAsyncReadIO::casAsyncReadIO ( const casCtx & ctx ) :
//
casAsyncReadIO::~casAsyncReadIO ()
{
epicsGuard < casCoreClient > guard ( this->client );
this->chan.removeAsyncIO ( *this );
}
//
// casAsyncReadIO::postIOCompletion()
//
caStatus casAsyncReadIO::postIOCompletion (caStatus completionStatusIn,
const gdd &valueRead)
caStatus casAsyncReadIO::postIOCompletion ( caStatus completionStatusIn,
const gdd & valueRead)
{
{
epicsGuard < casCoreClient > guard ( this->client );
this->pDD = & valueRead;
this->completionStatus = completionStatusIn;
}
return this->postIOCompletionI();
this->pDD = & valueRead;
this->completionStatus = completionStatusIn;
return this->postIOCompletionI ();
}
//
// casAsyncReadIO::readOP()
//
bool casAsyncReadIO::readOP() const
bool casAsyncReadIO::readOP () const
{
return true; // it is a read op
}

View File

@@ -38,7 +38,6 @@ casAsyncWriteIO::casAsyncWriteIO ( const casCtx & ctx ) :
//
casAsyncWriteIO::~casAsyncWriteIO()
{
epicsGuard < casCoreClient > guard ( this->client );
this->chan.removeAsyncIO ( *this );
}

View File

@@ -23,29 +23,17 @@
//
// casChannelI::casChannelI()
//
casChannelI::casChannelI ( const casCtx & ) :
pClient ( 0 ), pPV ( 0 ), cid ( 0xffffffff ),
accessRightsEvPending ( false )
casChannelI::casChannelI ( const casCtx & ctx ) :
pClient ( ctx.getClient() ), pPV ( ctx.getPV() ),
cid ( ctx.getMsg()->m_cid ), accessRightsEvPending ( false )
{
}
void casChannelI::bindToClientI (
casCoreClient & client, casPVI & pv, caResId cidIn )
{
this->pClient = & client;
this->pPV = & pv;
this->cid = cidIn;
client.installChannel ( *this );
}
//
// casChannelI::~casChannelI()
//
casChannelI::~casChannelI()
{
epicsGuard < casCoreClient >
guard ( * this->pClient );
{
//
// cancel any pending asynchronous IO
//
@@ -80,8 +68,6 @@ casChannelI::~casChannelI()
//
void casChannelI::clearOutstandingReads()
{
epicsGuard < casCoreClient > guard ( * this->pClient );
//
// cancel any pending asynchronous IO
//
@@ -102,20 +88,14 @@ void casChannelI::clearOutstandingReads()
//
void casChannelI::show ( unsigned level ) const
{
epicsGuard < casCoreClient > guard ( * this->pClient );
tsDLIterConst < casMonitor > iter =
this->monitorList.firstIter ();
if ( iter.valid () ) {
printf("List of CA events (monitors) for \"%s\".\n",
this->pPV->getName());
}
while ( iter.valid () ) {
iter->show ( level );
++iter;
}
this->show ( level );
printf ( "casChannelI: client id %u PV %s\n",
this->cid, this->pPV->getName() );
if ( this->monitorList.count() ) {
printf ( "List of subscriptions attached\n" );
// use the client's lock to protect the list
this->pClient->showMonitorsInList (
this->monitorList, level );
}
}
//
@@ -189,7 +169,6 @@ void casChannelI::destroyClientNotify ()
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
@@ -216,7 +195,6 @@ void casChannelI::installMonitor (
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

@@ -25,14 +25,9 @@
//
// casChannelI::postEvent()
//
inline void casChannelI::postEvent (const casEventMask &select, const gdd &event)
inline void casChannelI::postEvent ( const casEventMask &select, const gdd &event )
{
epicsGuard < casCoreClient > guard ( *this->pClient );
tsDLIter<casMonitor> iter = this->monitorList.firstIter ();
while ( iter.valid () ) {
iter->post (select, event);
++iter;
}
this->pClient->postEvent ( this->monitorList, select, event );
}
//
@@ -52,10 +47,11 @@ inline void casChannelI::destroyNoClientNotify()
//
// casChannelI::installAsyncIO()
//
inline void casChannelI::installAsyncIO(casAsyncIOI &io)
inline void casChannelI::installAsyncIO ( casAsyncIOI & io )
{
epicsGuard < casCoreClient > guard ( *this->pClient );
this->ioInProgList.add(io);
// install through the client so that we can
// use its lock to protect the list
this->pClient->installChannelsAsynchIO ( this->ioInProgList, io );
}
//
@@ -63,9 +59,10 @@ inline void casChannelI::installAsyncIO(casAsyncIOI &io)
//
inline void casChannelI::removeAsyncIO ( casAsyncIOI & io )
{
epicsGuard < casCoreClient > guard ( *this->pClient );
this->ioInProgList.remove(io);
this->pPV->unregisterIO();
// uninstall through the client so that we can
// use its lock to protect the list
this->pClient->uninstallChannelsAsynchIO ( this->ioInProgList, io );
this->pPV->unregisterIO ();
}
//

View File

@@ -62,14 +62,6 @@ casCoreClient::~casCoreClient()
}
}
//
// casCoreClient::destroy()
//
void casCoreClient::destroy()
{
delete this;
}
//
// casCoreClient::disconnectChan()
//
@@ -82,6 +74,7 @@ caStatus casCoreClient::disconnectChan(caResId)
void casCoreClient::show ( unsigned level ) const
{
printf ( "Core client\n" );
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.show ( level );
printf ( "\t%d io ops in progess\n", this->ioInProgList.count() );
this->ctx.show ( level );
@@ -203,20 +196,151 @@ casMonitor & casCoreClient::monitorFactory (
const casEventMask & mask )
{
casMonitor & mon = this->ctx.getServer()->casMonitorFactory (
chan, clientId, count,
type, mask,
this->mutex,
*this );
this->eventSys.installMonitor ();
chan, clientId, count, type, mask, *this );
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.installMonitor ();
}
return mon;
}
void casCoreClient::destroyMonitor ( casMonitor & mon )
{
this->eventSys.removeMonitor ();
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.removeMonitor ();
}
this->ctx.getServer()->casMonitorDestroy ( mon );
}
void casCoreClient::postEvent ( tsDLList < casMonitor > & monitorList,
const casEventMask & select, const gdd & event )
{
epicsGuard < epicsMutex > guard ( this->mutex );
tsDLIter < casMonitor > iter = monitorList.firstIter ();
while ( iter.valid () ) {
iter->postEvent ( select, event );
++iter;
}
}
void casCoreClient::showMonitorsInList (
const tsDLList < casMonitor > & monitorList, unsigned level ) const
{
epicsGuard < epicsMutex > guard ( this->mutex );
tsDLIterConst < casMonitor > iter = monitorList.firstIter ();
while ( iter.valid () ) {
iter->show ( level );
++iter;
}
}
void casCoreClient::installChannelsAsynchIO (
tsDLList < casAsyncIOI > & list, casAsyncIOI & io )
{
epicsGuard < epicsMutex > guard ( this->mutex );
list.add ( io );
}
void casCoreClient::uninstallChannelsAsynchIO (
tsDLList < casAsyncIOI > & list, casAsyncIOI & io )
{
epicsGuard < epicsMutex > guard ( this->mutex );
list.remove ( io );
}
//
// casCoreClient::installAsyncIO()
//
void casCoreClient::installAsyncIO(casAsyncIOI &ioIn)
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->ioInProgList.add ( ioIn );
}
//
// casCoreClient::removeAsyncIO()
//
void casCoreClient::removeAsyncIO(casAsyncIOI &ioIn)
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->ioInProgList.remove ( ioIn );
this->ctx.getServer()->ioBlockedList::signal ();
}
casEventSys::processStatus casCoreClient::eventSysProcess ()
{
epicsGuard < epicsMutex > guard ( this->mutex );
return this->eventSys.process ();
}
void casCoreClient::addToEventQueue ( casEvent & ev )
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.addToEventQueue ( ev );
}
// clients lock protects the event list and the
// flags in the asynch IO object
caStatus casCoreClient::addToEventQueue ( casAsyncIOI & io,
bool & onTheQueue, bool & posted )
{
epicsGuard < epicsMutex > guard ( this->mutex );
// dont allow them to post completion more than once
if ( posted || onTheQueue ) {
return S_cas_redundantPost;
}
posted = true;
onTheQueue = true;
this->eventSys.addToEventQueue ( io );
return S_cas_success;
}
void casCoreClient::insertEventQueue ( casEvent & insert, casEvent & prevEvent )
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.insertEventQueue ( insert, prevEvent );
}
void casCoreClient::removeFromEventQueue ( casEvent & ev )
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.removeFromEventQueue ( ev );
}
void casCoreClient::removeFromEventQueue ( casAsyncIOI & io )
{
epicsGuard < epicsMutex > guard ( this->mutex );
if ( io.onTheEventQueue () ) {
this->eventSys.removeFromEventQueue ( io );
}
}
void casCoreClient::enableEvents ()
{
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.eventsOn ();
}
this->eventSignal (); // wake up the event queue consumer
}
void casCoreClient::disableEvents ()
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.eventsOff ();
}
void casCoreClient::setDestroyPending ()
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventSys.setDestroyPending ();
}
bool casCoreClient::eventSysIsFull ()
{
epicsGuard < epicsMutex > guard ( this->mutex );
return this->eventSys.full ();
}

View File

@@ -41,25 +41,6 @@ inline caServerI &casCoreClient::getCAS() const
return *this->ctx.getServer();
}
//
// casCoreClient::installAsyncIO()
//
inline void casCoreClient::installAsyncIO(casAsyncIOI &ioIn)
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->ioInProgList.add ( ioIn );
}
//
// casCoreClient::removeAsyncIO()
//
inline void casCoreClient::removeAsyncIO(casAsyncIOI &ioIn)
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->ioInProgList.remove ( ioIn );
this->ctx.getServer()->ioBlockedList::signal ();
}
inline bool casCoreClient::okToStartAsynchIO ()
{
if ( ! this->asyncIOFlag ) {
@@ -80,47 +61,6 @@ 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 casMonitor * casCoreClient::lookupMonitor ( const caResId & idIn )
{
return this->ctx.getServer()->lookupMonitor ( idIn );

View File

@@ -74,7 +74,7 @@ inline casChannelI * casCtx::getChannel() const
//
// casCtx::setMsg()
//
inline void casCtx::setMsg ( caHdrLargeArray &msgIn, void * pBody )
inline void casCtx::setMsg ( const caHdrLargeArray & msgIn, void * pBody )
{
this->msg = msgIn;
this->pData = pBody;

View File

@@ -49,8 +49,6 @@ void casEventSys::show(unsigned level) const
//
casEventSys::~casEventSys()
{
epicsGuard < epicsMutex > guard ( this->mutex );
if ( this->pPurgeEvent != NULL ) {
this->eventLogQue.remove ( *this->pPurgeEvent );
delete this->pPurgeEvent;
@@ -64,7 +62,6 @@ casEventSys::~casEventSys()
while ( casEvent * pE = this->eventLogQue.get () ) {
pE->eventSysDestroyNotify ( this->client );
}
}
//
@@ -72,7 +69,6 @@ casEventSys::~casEventSys()
//
void casEventSys::installMonitor()
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->numEventBlocks++;
this->maxLogEntries += averageEventEntries;
}
@@ -82,7 +78,6 @@ void casEventSys::installMonitor()
//
void casEventSys::removeMonitor ()
{
epicsGuard < epicsMutex > guard ( this->mutex );
assert (this->numEventBlocks>=1u);
this->numEventBlocks--;
this->maxLogEntries -= averageEventEntries;
@@ -100,16 +95,12 @@ casEventSys::processStatus casEventSys::process ()
while ( ! this->dontProcess ) {
casEvent * pEvent;
{
epicsGuard < epicsMutex > guard ( this->mutex );
pEvent = this->eventLogQue.get ();
}
pEvent = this->eventLogQue.get ();
if ( pEvent == NULL ) {
break;
}
// lock must remain on until the event is called
caStatus status = pEvent->cbFunc ( this->client );
if ( status == S_cas_success ) {
ps.nAccepted++;
@@ -117,10 +108,7 @@ casEventSys::processStatus casEventSys::process ()
else if ( status == S_cas_sendBlocked ) {
// not accepted so return to the head of the list
// (we will try again later)
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->pushOnToEventQueue ( *pEvent );
}
this->pushOnToEventQueue ( *pEvent );
ps.cond = casProcOk;
break;
}
@@ -157,28 +145,24 @@ casEventSys::processStatus casEventSys::process ()
//
void casEventSys::eventsOn()
{
{
epicsGuard < epicsMutex > guard ( this->mutex );
//
// allow multiple events for each monitor
//
this->replaceEvents = false;
//
// allow multiple events for each monitor
//
this->replaceEvents = false;
//
// allow the event queue to be processed
//
this->dontProcess = false;
//
// allow the event queue to be processed
//
this->dontProcess = false;
//
// remove purge event if it is still pending
//
if ( this->pPurgeEvent != NULL ) {
this->eventLogQue.remove ( *this->pPurgeEvent );
delete this->pPurgeEvent;
this->pPurgeEvent = NULL;
}
}
//
// remove purge event if it is still pending
//
if ( this->pPurgeEvent != NULL ) {
this->eventLogQue.remove ( *this->pPurgeEvent );
delete this->pPurgeEvent;
this->pPurgeEvent = NULL;
}
}
//
@@ -186,8 +170,6 @@ void casEventSys::eventsOn()
//
void casEventSys::eventsOff()
{
epicsGuard < epicsMutex > guard ( this->mutex );
//
// new events will replace the last event on
// the queue for a particular monitor
@@ -228,11 +210,8 @@ casEventPurgeEv::casEventPurgeEv ( casEventSys & evSysIn ) :
//
caStatus casEventPurgeEv::cbFunc ( casCoreClient & )
{
{
epicsGuard < epicsMutex > guard ( this->evSys.mutex );
this->evSys.dontProcess = true;
this->evSys.pPurgeEvent = NULL;
}
this->evSys.dontProcess = true;
this->evSys.pPurgeEvent = NULL;
delete this;

View File

@@ -38,10 +38,7 @@ inline casEventSys::casEventSys ( casCoreClient & clientIn ) :
//
inline void casEventSys::addToEventQueue ( casEvent & event )
{
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventLogQue.add ( event );
}
this->eventLogQue.add ( event );
//
// wake up the event queue consumer only if
@@ -70,7 +67,6 @@ inline void casEventSys::setDestroyPending()
//
inline void casEventSys::insertEventQueue( casEvent & insert, casEvent & prevEvent )
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventLogQue.insertAfter ( insert, prevEvent );
}
@@ -79,7 +75,6 @@ inline void casEventSys::insertEventQueue( casEvent & insert, casEvent & prevEve
//
inline void casEventSys::pushOnToEventQueue ( casEvent & event )
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventLogQue.push ( event );
}
@@ -88,7 +83,6 @@ inline void casEventSys::pushOnToEventQueue ( casEvent & event )
//
inline void casEventSys::removeFromEventQueue ( casEvent & event )
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->eventLogQue.remove ( event );
}

View File

@@ -79,7 +79,7 @@ public:
ioBlocked ();
virtual ~ioBlocked ();
private:
ioBlockedList *pList;
ioBlockedList * pList;
virtual void ioBlockedSignal ();
};
@@ -137,7 +137,7 @@ class casMonitor :
public:
casMonitor ( caResId clientIdIn, casChannelI & chan,
unsigned long nElem, unsigned dbrType,
const casEventMask & maskIn, epicsMutex & mutexIn,
const casEventMask & maskIn,
casMonitorCallbackInterface & );
virtual ~casMonitor();
@@ -145,7 +145,7 @@ public:
caStatus executeEvent ( casMonEvent & );
void post ( const casEventMask & select, const smartConstGDDPointer & pValue );
void postEvent ( const casEventMask & select, const smartConstGDDPointer & pValue );
caResId getClientId () const
{
@@ -174,7 +174,6 @@ public:
private:
casMonEvent overFlowEvent;
unsigned long const nElem;
epicsMutex & mutex;
casChannelI & ciu;
casMonitorCallbackInterface & callBackIntf;
const casEventMask mask;
@@ -194,10 +193,10 @@ private:
};
//
// casMonitor::post()
// casMonitor::postEvent()
// (check for NOOP case in line)
//
inline void casMonitor::post (const casEventMask &select, const smartConstGDDPointer &pValue)
inline void casMonitor::postEvent (const casEventMask &select, const smartConstGDDPointer &pValue)
{
casEventMask result (select&this->mask);
//
@@ -233,6 +232,11 @@ public:
caServer *getCAS () const;
bool onTheEventQueue () const
{
return this->inTheEventQueue;
}
protected:
casCoreClient & client;
@@ -242,11 +246,11 @@ protected:
caStatus postIOCompletionI();
private:
bool inTheEventQueue:1;
bool posted:1;
bool ioComplete:1;
bool serverDelete:1;
bool duplicate:1;
bool inTheEventQueue;
bool posted;
bool ioComplete;
bool serverDelete;
bool duplicate;
//
// casEvent virtual call back function
@@ -286,9 +290,6 @@ public:
casChannelI ( const casCtx & ctx );
epicsShareFunc virtual ~casChannelI ();
void bindToClientI ( class casCoreClient & client,
casPVI & pv, caResId cid );
class casCoreClient & getClient () const
{
return *this->pClient;
@@ -347,7 +348,7 @@ protected:
class casCoreClient * pClient;
casPVI * pPV;
caResId cid; // client id
bool accessRightsEvPending:1;
bool accessRightsEvPending;
epicsShareFunc virtual void destroy ();
epicsShareFunc caStatus cbFunc ( casCoreClient & ); // access rights event call back
@@ -363,8 +364,6 @@ class casPVListChan : public casChannelI, public tsDLNode<casPVListChan>
{
public:
casPVListChan ( const casCtx &ctx );
void bindToClient ( casCoreClient & client,
casPVI & pv, caResId cidIn );
epicsShareFunc virtual ~casPVListChan();
private:
casPVListChan ( const casPVListChan & );
@@ -414,12 +413,12 @@ public:
epicsShareFunc virtual void endTransaction () = 0;
epicsShareFunc virtual caStatus read ( const casCtx & ctx, gdd & prototype ) = 0;
epicsShareFunc virtual caStatus write ( const casCtx & ctx, const gdd & value ) = 0;
epicsShareFunc virtual casChannel *createChannel (const casCtx & ctx,
epicsShareFunc virtual casChannel * createChannel ( const casCtx & ctx,
const char * const pUserName, const char * const pHostName ) = 0;
epicsShareFunc virtual aitEnum bestExternalType () const = 0;
epicsShareFunc virtual unsigned maxDimension () const = 0;
epicsShareFunc virtual aitIndex maxBound ( unsigned dimension ) const = 0;
epicsShareFunc virtual const char *getName () const = 0;
epicsShareFunc virtual const char * getName () const = 0;
epicsShareFunc casPV *apiPointer (); //retuns NULL if casPVI isnt a base of casPV
private:

View File

@@ -32,10 +32,8 @@ casMonitor::casMonitor (
unsigned long nElemIn,
unsigned dbrTypeIn,
const casEventMask & maskIn,
epicsMutex & mutexIn,
casMonitorCallbackInterface & cb ) :
nElem ( nElemIn ),
mutex ( mutexIn ),
ciu ( chan ),
callBackIntf ( cb ),
mask ( maskIn ),
@@ -55,7 +53,6 @@ casMonitor::casMonitor (
//
casMonitor::~casMonitor()
{
epicsGuard < epicsMutex > guard ( this->mutex );
this->disable();
if ( this->ovf ) {
casCoreClient &client = this->ciu.getClient();
@@ -68,7 +65,6 @@ casMonitor::~casMonitor()
//
void casMonitor::enable()
{
epicsGuard < epicsMutex > guard ( this->mutex );
if ( ! this->enabled && this->ciu.readAccess() ) {
this->enabled = true;
caStatus status = this->ciu.getPVI().registerEvent();
@@ -84,7 +80,6 @@ void casMonitor::enable()
//
void casMonitor::disable()
{
epicsGuard < epicsMutex > guard ( this->mutex );
if ( this->enabled ) {
this->enabled = false;
this->ciu.getPVI().unregisterEvent();
@@ -95,9 +90,7 @@ void casMonitor::disable()
// casMonitor::push()
//
void casMonitor::push ( const smartConstGDDPointer & pNewValue )
{
epicsGuard < epicsMutex > guard ( this->mutex );
{
casCoreClient & client = this->ciu.getClient ();
client.getCAS().incrEventsPostedCounter ();
@@ -174,7 +167,6 @@ caStatus casMonitor::executeEvent ( casMonEvent & ev )
caStatus status;
{
epicsGuard < epicsMutex > guard ( this->mutex );
status =
this->callBackIntf.
casMonitorCallBack ( *this, *pVal );

View File

@@ -56,9 +56,9 @@ void casPV::destroy ()
// casPV::createChannel()
//
casChannel *casPV::createChannel (const casCtx &ctx, const char * const,
const char * const)
const char * const )
{
return new casChannel (ctx);
return new casChannel ( ctx );
}
//

View File

@@ -27,13 +27,6 @@ casPVListChan::casPVListChan (const casCtx &ctx) :
{
}
void casPVListChan::bindToClient (
casCoreClient & client, casPVI & pv, caResId cidIn )
{
this->bindToClientI ( client, pv, cidIn );
this->pPV->installChannel ( *this );
}
//
// casPVListChan::~casPVListChan()
//

View File

@@ -40,16 +40,13 @@ casStrmClient::casStrmClient ( caServerI & cas, clientBufMemoryManager & memMgr
this->pHostName = new char [1u];
*this->pHostName = '\0';
epicsGuard < casCoreClient > guard ( * this );
this->ctx.getServer()->installClient ( this );
this->pUserName = new ( std::nothrow ) char [1u];
if ( ! this->pUserName ) {
free ( this->pHostName );
throw std::bad_alloc();
}
*this->pUserName= '\0';
this->ctx.getServer()->installClient ( this );
}
//
@@ -57,19 +54,14 @@ casStrmClient::casStrmClient ( caServerI & cas, clientBufMemoryManager & memMgr
//
casStrmClient::~casStrmClient()
{
epicsGuard < casCoreClient > guard ( * this );
//
// remove this from the list of connected clients
//
this->ctx.getServer()->removeClient(this);
this->ctx.getServer()->removeClient ( this );
delete [] this->pUserName;
delete [] this->pHostName;
//
// delete all channel attached
// delete all channels attached
//
tsDLIter <casChannelI> iter = this->chanList.firstIter ();
while ( iter.valid () ) {
@@ -821,7 +813,7 @@ caStatus casStrmClient::hostNameAction()
size-1);
pMalloc[size-1]='\0';
epicsGuard < casCoreClient > guard ( * this );
epicsGuard < epicsMutex > guard ( this->mutex );
if (this->pHostName) {
delete [] this->pHostName;
@@ -867,7 +859,7 @@ caStatus casStrmClient::clientNameAction()
size-1);
pMalloc[size-1]='\0';
epicsGuard < casCoreClient > guard ( * this );
epicsGuard < epicsMutex > guard ( this->mutex );
if (this->pUserName) {
delete [] this->pUserName;
@@ -940,7 +932,7 @@ caStatus casStrmClient::claimChannelAction()
// prevent problems such as the PV being deleted before the
// channel references it
//
epicsGuard < casCoreClient > guard ( * this );
epicsGuard < epicsMutex > guard ( this->mutex );
this->asyncIOFlag = false;
//
@@ -1017,18 +1009,21 @@ caStatus casStrmClient::createChanResponse ( const caHdrLargeArray & hdr, const
//
// create server tool XXX derived from casChannel
// (use temp context because this can be caled asynchronously)
//
this->ctx.setPV ( pPV );
casCtx tmpCtx;
tmpCtx.setClient ( this );
tmpCtx.setPV ( pPV );
tmpCtx.setMsg ( hdr, 0 );
casChannel * pChan = pPV->createChannel (
this->ctx, this->pUserName, this->pHostName );
tmpCtx, this->pUserName, this->pHostName );
if ( ! pChan ) {
pPV->deleteSignal();
return this->channelCreateFailedResp ( hdr, S_cas_noMemory );
}
pChan->bindToClient ( *this, *pPV, hdr.m_cid );
casChannelI * pChanI = (casChannelI *) pChan;
this->installChannel ( *pChan );
pPV->installChannel ( *pChan );
//
// check to see if the enum table is empty and therefore
@@ -1038,7 +1033,7 @@ caStatus casStrmClient::createChanResponse ( const caHdrLargeArray & hdr, const
//
if ( nativeTypeDBR == DBR_ENUM ) {
this->ctx.setPV ( pPV );
this->ctx.setChannel ( pChanI );
this->ctx.setChannel ( pChan );
this->asyncIOFlag = false;
status = pPV->updateEnumStringTable ( this->ctx );
if ( this->asyncIOFlag ) {
@@ -1302,6 +1297,7 @@ caStatus casStrmClient::eventAddAction ()
}
if ( status == S_cas_success ) {
epicsGuard < epicsMutex > guard ( this->mutex );
pciu->installMonitor (
mp->m_available, mp->m_count,
mp->m_dataType, mask );
@@ -1474,7 +1470,7 @@ caStatus casStrmClient::readSyncAction()
const caHdrLargeArray *mp = this->ctx.getMsg();
int status;
epicsGuard < casCoreClient > guard ( * this );
epicsGuard < epicsMutex > guard ( this->mutex );
//
// This messages indicates that the client
@@ -1857,7 +1853,7 @@ inline bool caServerI::roomForNewChannel() const
//
void casStrmClient::installChannel(casChannelI &chan)
{
epicsGuard < casCoreClient > guard ( * this );
epicsGuard < epicsMutex > guard ( this->mutex );
this->getCAS().installItem (chan);
this->chanList.add(chan);
}
@@ -1867,7 +1863,7 @@ void casStrmClient::installChannel(casChannelI &chan)
//
void casStrmClient::removeChannel(casChannelI &chan)
{
epicsGuard < casCoreClient > guard ( * this );
epicsGuard < epicsMutex > guard ( this->mutex );
casRes * pRes = this->getCAS().removeItem(chan);
assert (&chan == (casChannelI *)pRes);
this->chanList.remove(chan);

View File

@@ -110,7 +110,7 @@ public:
casPVI * getPV () const;
casChannelI * getChannel () const;
void setMsg ( caHdrLargeArray &, void * pBody );
void setMsg ( const caHdrLargeArray &, void * pBody );
void setServer ( caServerI * p );
@@ -382,7 +382,6 @@ public:
private:
tsDLList < casEvent > eventLogQue;
epicsMutex mutex;
casCoreClient & client;
class casEventPurgeEv * pPurgeEvent; // flow control purge complete event
unsigned numEventBlocks; // N event blocks installed
@@ -421,21 +420,20 @@ class casCoreClient : public ioBlocked,
public:
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 removeAsyncIO ( casAsyncIOI & ioIn );
void installChannelsAsynchIO (
tsDLList < casAsyncIOI > & list, casAsyncIOI & io );
void uninstallChannelsAsynchIO (
tsDLList < casAsyncIOI > & list, casAsyncIOI & io );
caServerI & getCAS () const;
void lock ();
void unlock ();
//
// one virtual function for each CA request type that has
// asynchronous completion
@@ -479,9 +477,12 @@ public:
casEventSys::processStatus eventSysProcess();
void addToEventQueue ( casEvent & );
caStatus addToEventQueue ( casAsyncIOI &,
bool & onTheQueue, bool & posted );
void insertEventQueue ( casEvent & insert,
casEvent & prevEvent );
void removeFromEventQueue ( casEvent & );
void removeFromEventQueue ( casAsyncIOI & );
void enableEvents ();
void disableEvents ();
bool eventSysIsFull ();
@@ -498,12 +499,20 @@ public:
caStatus casMonitorCallBack ( casMonitor &,
const smartConstGDDPointer & );
casMonitor * lookupMonitor ( const caResId &idIn );
void postEvent ( tsDLList <casMonitor > &,
const casEventMask &select, const gdd &event );
void showMonitorsInList (
const tsDLList < casMonitor > & monitorList,
unsigned level ) const;
protected:
epicsMutex mutex;
mutable epicsMutex mutex;
casCtx ctx;
bool asyncIOFlag;
void lock ();
void unlock ();
private:
casEventSys eventSys;
tsDLList < casAsyncIOI > ioInProgList;
@@ -916,7 +925,7 @@ public:
casMonitor & casMonitorFactory ( casChannelI &,
caResId clientId, const unsigned long count,
const unsigned type, const casEventMask &,
epicsMutex & , casMonitorCallbackInterface & );
casMonitorCallbackInterface & );
void casMonitorDestroy ( casMonitor & );
private:

View File

@@ -165,7 +165,7 @@ epicsTimerNotify::expireStatus casStreamEvWakeup::expire ( const epicsTime & /*
// called from a client member function
// higher up on the stack
//
os.destroy();
delete & os;
//
// must not touch the "this" pointer
@@ -482,7 +482,7 @@ void casStreamOS::sendCB()
// called from a client member function
// higher up on the stack
//
this->destroy();
delete this;
//
// must _not_ touch "this" pointer
// after the destroy
@@ -507,7 +507,7 @@ void casStreamOS::sendCB()
// called from a client member function
// higher up on the stack
//
this->destroy();
delete this;
//
// must _not_ touch "this" pointer
// after the destroy