/*************************************************************************\ * 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 is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* * Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd * * Author Jeffrey O. Hill * johill@lanl.gov * 505 665 1831 */ #include #include #include "errlog.h" #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 < casClientMutex > & clientGuard, epicsGuard < evSysMutex > & ) { caStatus status = S_cas_success; { this->inTheEventQueue = false; status = this->cbFuncAsyncIO ( clientGuard ); 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; } // 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; }