Files
pcas/src/cas/generic/casAsyncIOI.cc
2003-02-12 19:06:15 +00:00

131 lines
3.5 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
*/
#include <stdexcept>
#define epicsExportSharedSymbols
#include "casAsyncIOI.h"
casAsyncIOI::casAsyncIOI ( const casCtx & ctx ) :
client ( *ctx.getClient() ), inTheEventQueue ( false ),
posted ( false ), ioComplete ( false )
{
//
// catch situation where they create more than one
// async IO object per request
//
if ( ! client.okToStartAsynchIO () ) {
throw std::logic_error (
"server tool attempted to "
"start duplicate asynchronous IO" );
}
}
//
// ways this gets destroyed:
// 1) io completes, this is pulled off the queue, and result
// is sent to the client
// 2) client, channel, or PV is deleted
// 3) server tool deletes the casAsyncXxxxIO obj
//
// Case 1) => normal completion
//
// Case 2)
// If the server deletes the channel or the PV then the
// client will get a disconnect msg for the channel
// involved and this will cause the io call back
// to be called with a disconnect error code.
// Therefore we dont need to force an IO canceled
// response here.
//
// Case 3)
// If for any reason the server tool needs to cancel an IO
// operation then it should post io completion with status
// S_casApp_canceledAsyncIO. Deleting the asyncronous io
// object prior to its being allowed to forward an IO termination
// message to the client will result in NO IO CALL BACK TO THE
// CLIENT PROGRAM (in this situation a warning message will be printed by
// the server lib).
//
casAsyncIOI::~casAsyncIOI()
{
//
// pulls itself out of the event queue
// if it is installed there.
//
this->client.removeFromEventQueue ( *this, this->inTheEventQueue );
}
//
// o called when IO completion event reaches top of event queue
// o clients lock is applied when calling this
//
caStatus casAsyncIOI::cbFunc (
casCoreClient &, epicsGuard < epicsMutex > & guard )
{
caStatus status = S_cas_success;
{
this->inTheEventQueue = false;
{
epicsGuardRelease < epicsMutex > unlocker ( guard );
status = this->cbFuncAsyncIO ();
}
if ( status == S_cas_sendBlocked ) {
//
// causes this op to be pushed back on the queue
//
this->inTheEventQueue = true;
return status;
}
else if ( status != S_cas_success ) {
errMessage ( status, "Asynch IO completion failed" );
}
this->ioComplete = true;
}
this->client.getCAS().ioBlockedList::signal ();
// dont use "this" after destroying the object here
delete this;
return S_cas_success;
}
caStatus casAsyncIOI::insertEventQueue ()
{
//
// place this event in the event queue
// o this also signals the event consumer
// o clients lock protects list and flag
//
return this->client.addToEventQueue ( *this, this->inTheEventQueue, this->posted );
}
caServer *casAsyncIOI::getCAS() const
{
return this->client.getCAS().getAdapter();
}
bool casAsyncIOI::oneShotReadOP() const
{
return false;
}