Stage 1 reorganization
Directory moves. src/RTEMS/ => src/libCom/RTEMS/ src/as/ => src/ioc/as/ src/bpt/ => src/ioc/bpt/ src/ca/ => src/ca/client/ src/cap5/ => src/ca/client/perl/ src/cas/ => src/ca/legacy/pcas/ src/catools/ => src/ca/client/tools/ src/db/ => src/ioc/db/ src/dbStatic/ => src/ioc/dbStatic/ src/dbtools/ => src/ioc/dbtemplate/ src/dev/softDev/ => src/std/dev/ src/dev/testDev/ => src/std/test/ src/excas/ => src/ca/legacy/pcas/ex/ src/gdd/ => src/ca/legacy/gdd/ src/makeBaseApp/ => src/template/base/ src/makeBaseExt/ => src/template/ext/ src/misc/ => src/ioc/misc/ src/rec/ => src/std/rec/ src/registry/ => src/ioc/registry/ src/rsrv/ => src/ioc/rsrv/ src/softIoc/ => src/std/softIoc/ src/toolsComm/ => src/libCom/tools/
This commit is contained in:
committed by
Andrew Johnson
parent
4a18db9f99
commit
2a36a3906d
628
src/ca/client/nciu.cpp
Normal file
628
src/ca/client/nciu.cpp
Normal file
@@ -0,0 +1,628 @@
|
||||
/*************************************************************************\
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
*
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
|
||||
|
||||
#include "epicsAlgorithm.h"
|
||||
|
||||
#include "errlog.h"
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "iocinf.h"
|
||||
#include "cac.h"
|
||||
#include "osiWireFormat.h"
|
||||
#include "udpiiu.h"
|
||||
#include "virtualCircuit.h"
|
||||
#include "cadef.h"
|
||||
#include "db_access.h" // for INVALID_DB_REQ
|
||||
#include "noopiiu.h"
|
||||
|
||||
nciu::nciu ( cac & cacIn, netiiu & iiuIn, cacChannelNotify & chanIn,
|
||||
const char *pNameIn, cacChannel::priLev pri ) :
|
||||
cacChannel ( chanIn ),
|
||||
cacCtx ( cacIn ),
|
||||
piiu ( & iiuIn ),
|
||||
sid ( UINT_MAX ),
|
||||
count ( 0 ),
|
||||
retry ( 0u ),
|
||||
nameLength ( 0u ),
|
||||
typeCode ( USHRT_MAX ),
|
||||
priority ( static_cast <ca_uint8_t> ( pri ) )
|
||||
{
|
||||
size_t nameLengthTmp = strlen ( pNameIn ) + 1;
|
||||
|
||||
// second constraint is imposed by size field in protocol header
|
||||
if ( nameLengthTmp > MAX_UDP_SEND - sizeof ( caHdr ) || nameLengthTmp > USHRT_MAX ) {
|
||||
throw cacChannel::badString ();
|
||||
}
|
||||
|
||||
if ( pri > 0xff ) {
|
||||
throw cacChannel::badPriority ();
|
||||
}
|
||||
|
||||
this->nameLength = static_cast <unsigned short> ( nameLengthTmp );
|
||||
|
||||
this->pNameStr = new char [ this->nameLength ];
|
||||
strcpy ( this->pNameStr, pNameIn );
|
||||
}
|
||||
|
||||
nciu::~nciu ()
|
||||
{
|
||||
delete [] this->pNameStr;
|
||||
}
|
||||
|
||||
// channels are created by the user, and only destroyed by the user
|
||||
// using this routine
|
||||
void nciu::destroy (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
while ( baseNMIU * pNetIO = this->eventq.first () ) {
|
||||
bool success = this->cacCtx.destroyIO ( guard, pNetIO->getId (), *this );
|
||||
assert ( success );
|
||||
}
|
||||
|
||||
// if the claim reply has not returned yet then we will issue
|
||||
// the clear channel request to the server when the claim reply
|
||||
// arrives and there is no matching nciu in the client
|
||||
if ( this->channelNode::isInstalledInServer ( guard ) ) {
|
||||
this->getPIIU(guard)->clearChannelRequest (
|
||||
guard, this->sid, this->id );
|
||||
}
|
||||
this->piiu->uninstallChan ( guard, *this );
|
||||
this->cacCtx.destroyChannel ( guard, *this );
|
||||
}
|
||||
|
||||
void * nciu::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 nciu::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__ );
|
||||
}
|
||||
|
||||
void nciu::initiateConnect (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
this->cacCtx.initiateConnect ( guard, *this, this->piiu );
|
||||
}
|
||||
|
||||
void nciu::connect ( unsigned nativeType,
|
||||
unsigned nativeCount, unsigned sidIn,
|
||||
epicsGuard < epicsMutex > & /* cbGuard */,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
if ( ! dbf_type_is_valid ( nativeType ) ) {
|
||||
throw std::logic_error ( "Ignored conn resp with bad native data type" );
|
||||
}
|
||||
|
||||
this->typeCode = static_cast < unsigned short > ( nativeType );
|
||||
this->count = nativeCount;
|
||||
this->sid = sidIn;
|
||||
|
||||
/*
|
||||
* if less than v4.1 then the server will never
|
||||
* send access rights and there will always be access
|
||||
*/
|
||||
bool v41Ok = this->piiu->ca_v41_ok ( guard );
|
||||
if ( ! v41Ok ) {
|
||||
this->accessRightState.setReadPermit();
|
||||
this->accessRightState.setWritePermit();
|
||||
}
|
||||
|
||||
/*
|
||||
* if less than v4.1 then the server will never
|
||||
* send access rights and we know that there
|
||||
* will always be access and also need to call
|
||||
* their call back here
|
||||
*/
|
||||
if ( ! v41Ok ) {
|
||||
this->notify().accessRightsNotify (
|
||||
guard, this->accessRightState );
|
||||
}
|
||||
|
||||
// channel uninstal routine grabs the callback lock so
|
||||
// a channel will not be deleted while a call back is
|
||||
// in progress
|
||||
//
|
||||
// the callback lock is also taken when a channel
|
||||
// disconnects to prevent a race condition with the
|
||||
// code below - ie we hold the callback lock here
|
||||
// so a chanel cant be destroyed out from under us.
|
||||
this->notify().connectNotify ( guard );
|
||||
}
|
||||
|
||||
void nciu::unresponsiveCircuitNotify (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
ioid tmpId = this->getId ();
|
||||
cac & caRefTmp = this->cacCtx;
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
this->cacCtx.disconnectAllIO ( cbGuard, guard,
|
||||
*this, this->eventq );
|
||||
this->notify().disconnectNotify ( guard );
|
||||
// if they destroy the channel in their disconnect
|
||||
// handler then we have to be very careful to not
|
||||
// touch this object if it has been destroyed
|
||||
nciu * pChan = caRefTmp.lookupChannel ( guard, tmpId );
|
||||
if ( pChan ) {
|
||||
caAccessRights noRights;
|
||||
pChan->notify().accessRightsNotify ( guard, noRights );
|
||||
// likewise, they might destroy the channel in their access rights
|
||||
// handler so we have to be very careful to not touch this
|
||||
// object from here on down
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::setServerAddressUnknown ( netiiu & newiiu,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
this->piiu = & newiiu;
|
||||
this->retry = 0;
|
||||
this->typeCode = USHRT_MAX;
|
||||
this->count = 0u;
|
||||
this->sid = UINT_MAX;
|
||||
this->accessRightState.clrReadPermit();
|
||||
this->accessRightState.clrWritePermit();
|
||||
}
|
||||
|
||||
void nciu::accessRightsStateChange (
|
||||
const caAccessRights & arIn, epicsGuard < epicsMutex > & /* cbGuard */,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
this->accessRightState = arIn;
|
||||
|
||||
//
|
||||
// the channel delete routine takes the call back lock so
|
||||
// that this will not be called when the channel is being
|
||||
// deleted.
|
||||
//
|
||||
this->notify().accessRightsNotify ( guard, this->accessRightState );
|
||||
}
|
||||
|
||||
/*
|
||||
* nciu::searchMsg ()
|
||||
*/
|
||||
bool nciu::searchMsg ( epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
bool success = this->piiu->searchMsg (
|
||||
guard, this->getId (), this->pNameStr, this->nameLength );
|
||||
if ( success ) {
|
||||
if ( this->retry < UINT_MAX ) {
|
||||
this->retry++;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
const char *nciu::pName (
|
||||
epicsGuard < epicsMutex > & guard ) const throw ()
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
return this->pNameStr;
|
||||
}
|
||||
|
||||
unsigned nciu::getName (
|
||||
epicsGuard < epicsMutex > &,
|
||||
char * pBuf, unsigned bufLen ) const throw ()
|
||||
{
|
||||
if ( bufLen == 0u ) {
|
||||
return 0u;
|
||||
}
|
||||
if ( this->nameLength < bufLen ) {
|
||||
strcpy ( pBuf, this->pNameStr );
|
||||
return this->nameLength;
|
||||
}
|
||||
else {
|
||||
unsigned reducedSize = bufLen - 1u;
|
||||
strncpy ( pBuf, this->pNameStr, bufLen );
|
||||
pBuf[reducedSize] = '\0';
|
||||
return reducedSize;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned nciu::nameLen (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
return this->nameLength;
|
||||
}
|
||||
|
||||
unsigned nciu::requestMessageBytesPending (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
return piiu->requestMessageBytesPending ( guard );
|
||||
}
|
||||
|
||||
void nciu::flush (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
piiu->flush ( guard );
|
||||
}
|
||||
|
||||
cacChannel::ioStatus nciu::read (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
unsigned type, arrayElementCount countIn,
|
||||
cacReadNotify ¬ify, ioid *pId )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
|
||||
if ( ! this->connected ( guard ) ) {
|
||||
throw cacChannel::notConnected ();
|
||||
}
|
||||
if ( ! this->accessRightState.readPermit () ) {
|
||||
throw cacChannel::noReadAccess ();
|
||||
}
|
||||
if ( countIn > this->count ) {
|
||||
throw cacChannel::outOfBounds ();
|
||||
}
|
||||
|
||||
//
|
||||
// fail out if their arguments are invalid
|
||||
//
|
||||
if ( INVALID_DB_REQ ( type ) ) {
|
||||
throw cacChannel::badType ();
|
||||
}
|
||||
|
||||
netReadNotifyIO & io = this->cacCtx.readNotifyRequest (
|
||||
guard, *this, *this, type, countIn, notify );
|
||||
if ( pId ) {
|
||||
*pId = io.getId ();
|
||||
}
|
||||
this->eventq.add ( io );
|
||||
return cacChannel::iosAsynch;
|
||||
}
|
||||
|
||||
void nciu::stringVerify ( const char *pStr, const unsigned count )
|
||||
{
|
||||
for ( unsigned i = 0; i < count; i++ ) {
|
||||
unsigned int strsize = 0;
|
||||
while ( pStr[strsize++] != '\0' ) {
|
||||
if ( strsize >= MAX_STRING_SIZE ) {
|
||||
throw badString();
|
||||
}
|
||||
}
|
||||
pStr += MAX_STRING_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::write (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
unsigned type, arrayElementCount countIn, const void * pValue )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
|
||||
// make sure that they get this and not "no write access"
|
||||
// if disconnected
|
||||
if ( ! this->connected ( guard ) ) {
|
||||
throw cacChannel::notConnected();
|
||||
}
|
||||
if ( ! this->accessRightState.writePermit() ) {
|
||||
throw cacChannel::noWriteAccess();
|
||||
}
|
||||
if ( countIn > this->count || countIn == 0 ) {
|
||||
throw cacChannel::outOfBounds();
|
||||
}
|
||||
if ( type == DBR_STRING ) {
|
||||
nciu::stringVerify ( (char *) pValue, countIn );
|
||||
}
|
||||
this->piiu->writeRequest ( guard, *this, type, countIn, pValue );
|
||||
}
|
||||
|
||||
cacChannel::ioStatus nciu::write (
|
||||
epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount countIn,
|
||||
const void * pValue, cacWriteNotify & notify, ioid * pId )
|
||||
{
|
||||
// make sure that they get this and not "no write access"
|
||||
// if disconnected
|
||||
if ( ! this->connected ( guard ) ) {
|
||||
throw cacChannel::notConnected();
|
||||
}
|
||||
if ( ! this->accessRightState.writePermit() ) {
|
||||
throw cacChannel::noWriteAccess();
|
||||
}
|
||||
if ( countIn > this->count || countIn == 0 ) {
|
||||
throw cacChannel::outOfBounds();
|
||||
}
|
||||
if ( type == DBR_STRING ) {
|
||||
nciu::stringVerify ( (char *) pValue, countIn );
|
||||
}
|
||||
|
||||
netWriteNotifyIO & io = this->cacCtx.writeNotifyRequest (
|
||||
guard, *this, *this, type, countIn, pValue, notify );
|
||||
if ( pId ) {
|
||||
*pId = io.getId ();
|
||||
}
|
||||
this->eventq.add ( io );
|
||||
return cacChannel::iosAsynch;
|
||||
}
|
||||
|
||||
void nciu::subscribe (
|
||||
epicsGuard < epicsMutex > & guard, unsigned type,
|
||||
arrayElementCount nElem, unsigned mask,
|
||||
cacStateNotify & notify, ioid *pId )
|
||||
{
|
||||
netSubscription & io = this->cacCtx.subscriptionRequest (
|
||||
guard, *this, *this, type, nElem, mask, notify,
|
||||
this->channelNode::isInstalledInServer ( guard ) );
|
||||
this->eventq.add ( io );
|
||||
if ( pId ) {
|
||||
*pId = io.getId ();
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::ioCancel (
|
||||
epicsGuard < epicsMutex > & guard, const ioid & idIn )
|
||||
{
|
||||
this->cacCtx.destroyIO ( guard, idIn, *this );
|
||||
}
|
||||
|
||||
void nciu::ioShow (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const ioid &idIn, unsigned level ) const
|
||||
{
|
||||
this->cacCtx.ioShow ( guard, idIn, level );
|
||||
}
|
||||
|
||||
unsigned nciu::getHostName (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
char *pBuf, unsigned bufLength ) const throw ()
|
||||
{
|
||||
return this->piiu->getHostName (
|
||||
guard, pBuf, bufLength );
|
||||
}
|
||||
|
||||
const char * nciu::pHostName (
|
||||
epicsGuard < epicsMutex > & guard ) const throw ()
|
||||
{
|
||||
return this->piiu->pHostName ( guard );
|
||||
}
|
||||
|
||||
bool nciu::ca_v42_ok (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
return this->piiu->ca_v42_ok ( guard );
|
||||
}
|
||||
|
||||
short nciu::nativeType (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
short type = TYPENOTCONN;
|
||||
if ( this->connected ( guard ) ) {
|
||||
if ( this->typeCode < SHRT_MAX ) {
|
||||
type = static_cast <short> ( this->typeCode );
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
arrayElementCount nciu::nativeElementCount (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
arrayElementCount countOut = 0ul;
|
||||
if ( this->connected ( guard ) ) {
|
||||
countOut = this->count;
|
||||
}
|
||||
return countOut;
|
||||
}
|
||||
|
||||
caAccessRights nciu::accessRights (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
return this->accessRightState;
|
||||
}
|
||||
|
||||
unsigned nciu::searchAttempts (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
return this->retry;
|
||||
}
|
||||
|
||||
double nciu::beaconPeriod (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
return this->cacCtx.beaconPeriod ( guard, *this );
|
||||
}
|
||||
|
||||
double nciu::receiveWatchdogDelay (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
return this->piiu->receiveWatchdogDelay ( guard );
|
||||
}
|
||||
|
||||
bool nciu::connected ( epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
return this->channelNode::isConnected ( guard );
|
||||
}
|
||||
|
||||
void nciu::show ( unsigned level ) const
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef() );
|
||||
this->show ( guard, level );
|
||||
}
|
||||
|
||||
void nciu::show (
|
||||
epicsGuard < epicsMutex > & guard, unsigned level ) const
|
||||
{
|
||||
if ( this->connected ( guard ) ) {
|
||||
char hostNameTmp [256];
|
||||
this->getHostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) );
|
||||
::printf ( "Channel \"%s\", connected to server %s",
|
||||
this->pNameStr, hostNameTmp );
|
||||
if ( level > 1u ) {
|
||||
int tmpTypeCode = static_cast < int > ( this->typeCode );
|
||||
::printf ( ", native type %s, native element count %u",
|
||||
dbf_type_to_text ( tmpTypeCode ), this->count );
|
||||
::printf ( ", %sread access, %swrite access",
|
||||
this->accessRightState.readPermit() ? "" : "no ",
|
||||
this->accessRightState.writePermit() ? "" : "no ");
|
||||
}
|
||||
::printf ( "\n" );
|
||||
}
|
||||
else {
|
||||
::printf ( "Channel \"%s\" is disconnected\n", this->pNameStr );
|
||||
}
|
||||
|
||||
if ( level > 2u ) {
|
||||
::printf ( "\tnetwork IO pointer = %p\n",
|
||||
static_cast <void *> ( this->piiu ) );
|
||||
::printf ( "\tserver identifier %u\n", this->sid );
|
||||
::printf ( "\tsearch retry number=%u\n", this->retry );
|
||||
::printf ( "\tname length=%u\n", this->nameLength );
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::ioCompletionNotify (
|
||||
epicsGuard < epicsMutex > &, class baseNMIU & io )
|
||||
{
|
||||
this->eventq.remove ( io );
|
||||
}
|
||||
|
||||
void nciu::resubscribe ( epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
tsDLIter < baseNMIU > pNetIO = this->eventq.firstIter ();
|
||||
while ( pNetIO.valid () ) {
|
||||
tsDLIter < baseNMIU > next = pNetIO;
|
||||
next++;
|
||||
class netSubscription * pSubscr = pNetIO->isSubscription ();
|
||||
// Its normal for other types of IO to exist after the channel connects,
|
||||
// but before all of the resubscription requests go out. We must ignore
|
||||
// them here.
|
||||
if ( pSubscr ) {
|
||||
try {
|
||||
pSubscr->subscribeIfRequired ( guard, *this );
|
||||
}
|
||||
catch ( ... ) {
|
||||
errlogPrintf ( "CAC: failed to send subscription request "
|
||||
"during channel connect\n" );
|
||||
}
|
||||
}
|
||||
pNetIO = next;
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::sendSubscriptionUpdateRequests ( epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
tsDLIter < baseNMIU > pNetIO = this->eventq.firstIter ();
|
||||
while ( pNetIO.valid () ) {
|
||||
tsDLIter < baseNMIU > next = pNetIO;
|
||||
next++;
|
||||
try {
|
||||
pNetIO->forceSubscriptionUpdate ( guard, *this );
|
||||
}
|
||||
catch ( ... ) {
|
||||
errlogPrintf (
|
||||
"CAC: failed to send subscription update request "
|
||||
"during channel connect\n" );
|
||||
}
|
||||
pNetIO = next;
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::disconnectAllIO (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
this->cacCtx.disconnectAllIO ( cbGuard, guard,
|
||||
*this, this->eventq );
|
||||
}
|
||||
|
||||
void nciu::serviceShutdownNotify (
|
||||
epicsGuard < epicsMutex > & callbackControlGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard )
|
||||
{
|
||||
this->setServerAddressUnknown ( noopIIU, mutualExclusionGuard );
|
||||
this->notify().serviceShutdownNotify ( mutualExclusionGuard );
|
||||
}
|
||||
|
||||
void channelNode::setRespPendingState (
|
||||
epicsGuard < epicsMutex > &, unsigned index )
|
||||
{
|
||||
this->listMember =
|
||||
static_cast < channelNode::channelState >
|
||||
( channelNode::cs_searchRespPending0 + index );
|
||||
if ( this->listMember > cs_searchRespPending17 ) {
|
||||
throw std::runtime_error (
|
||||
"resp search timer index out of bounds" );
|
||||
}
|
||||
}
|
||||
|
||||
void channelNode::setReqPendingState (
|
||||
epicsGuard < epicsMutex > &, unsigned index )
|
||||
{
|
||||
this->listMember =
|
||||
static_cast < channelNode::channelState >
|
||||
( channelNode::cs_searchReqPending0 + index );
|
||||
if ( this->listMember > cs_searchReqPending17 ) {
|
||||
throw std::runtime_error (
|
||||
"req search timer index out of bounds" );
|
||||
}
|
||||
}
|
||||
|
||||
unsigned channelNode::getMaxSearchTimerCount ()
|
||||
{
|
||||
return epicsMin (
|
||||
cs_searchReqPending17 - cs_searchReqPending0,
|
||||
cs_searchRespPending17 - cs_searchRespPending0 ) + 1u;
|
||||
}
|
||||
|
||||
unsigned channelNode::getSearchTimerIndex (
|
||||
epicsGuard < epicsMutex > & )
|
||||
{
|
||||
channelNode::channelState chanState = this->listMember;
|
||||
unsigned index = 0u;
|
||||
if ( chanState >= cs_searchReqPending0 &&
|
||||
chanState <= cs_searchReqPending17 ) {
|
||||
index = chanState - cs_searchReqPending0;
|
||||
}
|
||||
else if ( chanState >= cs_searchRespPending0 &&
|
||||
chanState <= cs_searchRespPending17 ) {
|
||||
index = chanState - cs_searchRespPending0;
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error (
|
||||
"channel was expected to be in a search timer, but wasnt" );;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user