Files
epics-base/src/ca/nciu.h
2004-10-19 20:46:55 +00:00

382 lines
12 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.
\*************************************************************************/
/*
*
*
* 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 Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*/
#ifndef nciuh
#define nciuh
#ifdef epicsExportSharedSymbols
# define nciuh_restore_epicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include "resourceLib.h"
#include "tsDLList.h"
#include "tsFreeList.h"
#include "epicsMutex.h"
#include "compilerDependencies.h"
#ifdef nciuh_restore_epicsExportSharedSymbols
# define epicsExportSharedSymbols
# include "shareLib.h"
#endif
#define CA_MINOR_PROTOCOL_REVISION 11
#include "caProto.h"
#include "cacIO.h"
class cac;
class netiiu;
// The node and the state which tracks the list membership
// are in the channel, but belong to the circuit.
// Protected by the callback mutex
class channelNode : public tsDLNode < class nciu >
{
protected:
channelNode ();
bool isConnectedAtOrAfterV42 ( epicsGuard < epicsMutex > & ) const;
bool isConnectedBeforeV42 ( epicsGuard < epicsMutex > & ) const;
bool isInstalledInServer ( epicsGuard < epicsMutex > & ) const;
static unsigned getMaxSearchTimerCount ();
private:
enum channelState {
cs_none,
cs_disconnGov,
// note: indexing is used here
// so these must be contiguous
cs_searchReqPending0,
cs_searchReqPending1,
cs_searchReqPending2,
cs_searchReqPending3,
cs_searchReqPending4,
cs_searchReqPending5,
cs_searchReqPending6,
cs_searchReqPending7,
cs_searchReqPending8,
cs_searchReqPending9,
cs_searchReqPending10,
cs_searchReqPending11,
cs_searchReqPending12,
cs_searchReqPending13,
cs_searchReqPending14,
cs_searchReqPending15,
cs_searchReqPending16,
cs_searchReqPending17,
// note: indexing is used here
// so these must be contiguous
cs_searchRespPending0,
cs_searchRespPending1,
cs_searchRespPending2,
cs_searchRespPending3,
cs_searchRespPending4,
cs_searchRespPending5,
cs_searchRespPending6,
cs_searchRespPending7,
cs_searchRespPending8,
cs_searchRespPending9,
cs_searchRespPending10,
cs_searchRespPending11,
cs_searchRespPending12,
cs_searchRespPending13,
cs_searchRespPending14,
cs_searchRespPending15,
cs_searchRespPending16,
cs_searchRespPending17,
cs_createReqPend,
cs_createRespPend,
cs_subscripReqPend,
cs_connected,
cs_unrespCircuit,
cs_subscripUpdateReqPend
} listMember;
void setRespPendingState ( epicsGuard < epicsMutex > &, unsigned index );
void setReqPendingState ( epicsGuard < epicsMutex > &, unsigned index );
unsigned getSearchTimerIndex ( epicsGuard < epicsMutex > & );
friend class tcpiiu;
friend class udpiiu;
friend class tcpSendThread;
friend class searchTimer;
friend class disconnectGovernorTimer;
};
class privateInterfaceForIO { // X aCC 655
public:
virtual void ioCompletionNotify (
epicsGuard < epicsMutex > &, class baseNMIU & ) = 0;
virtual arrayElementCount nativeElementCount (
epicsGuard < epicsMutex > & ) const = 0;
virtual bool connected ( epicsGuard < epicsMutex > & ) const = 0;
};
class nciu :
public cacChannel,
public chronIntIdRes < nciu >,
public channelNode,
private privateInterfaceForIO {
public:
nciu ( cac &, netiiu &, cacChannelNotify &,
const char * pNameIn, cacChannel::priLev );
~nciu ();
void connect ( unsigned nativeType,
unsigned nativeCount, unsigned sid,
epicsGuard < epicsMutex > & cbGuard,
epicsGuard < epicsMutex > & guard );
void connect ( epicsGuard < epicsMutex > & cbGuard,
epicsGuard < epicsMutex > & guard );
void unresponsiveCircuitNotify (
epicsGuard < epicsMutex > & cbGuard,
epicsGuard < epicsMutex > & guard );
void circuitHangupNotify ( class udpiiu &,
epicsGuard < epicsMutex > & cbGuard,
epicsGuard < epicsMutex > & guard );
void setServerAddressUnknown (
netiiu & newiiu, epicsGuard < epicsMutex > & guard );
bool searchMsg (
epicsGuard < epicsMutex > & );
void serviceShutdownNotify (
epicsGuard < epicsMutex > & callbackControlGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard );
void accessRightsStateChange ( const caAccessRights &,
epicsGuard < epicsMutex > & cbGuard,
epicsGuard < epicsMutex > & guard );
ca_uint32_t getSID (
epicsGuard < epicsMutex > & ) const;
ca_uint32_t getCID (
epicsGuard < epicsMutex > & ) const;
netiiu * getPIIU (
epicsGuard < epicsMutex > & );
const netiiu * getConstPIIU (
epicsGuard < epicsMutex > & ) const;
cac & getClient ();
void searchReplySetUp ( netiiu &iiu, unsigned sidIn,
ca_uint16_t typeIn, arrayElementCount countIn,
epicsGuard < epicsMutex > & );
void show (
unsigned level ) const;
void show (
epicsGuard < epicsMutex > &,
unsigned level ) const;
unsigned getName (
epicsGuard < epicsMutex > &,
char * pBuf, unsigned bufLen ) const throw ();
const char * pName (
epicsGuard < epicsMutex > & ) const throw ();
unsigned nameLen (
epicsGuard < epicsMutex > & ) const;
unsigned getHostName (
epicsGuard < epicsMutex > &,
char * pBuf, unsigned bufLen ) const throw ();
void writeException (
epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > &,
int status, const char *pContext, unsigned type, arrayElementCount count );
cacChannel::priLev getPriority (
epicsGuard < epicsMutex > & ) const;
void * operator new (
size_t size, tsFreeList < class nciu, 1024, epicsMutexNOOP > & );
epicsPlacementDeleteOperator (
( void *, tsFreeList < class nciu, 1024, epicsMutexNOOP > & ))
//arrayElementCount nativeElementCount ( epicsGuard < epicsMutex > & ) const;
void resubscribe ( epicsGuard < epicsMutex > & );
void sendSubscriptionUpdateRequests ( epicsGuard < epicsMutex > & );
void disconnectAllIO (
epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > & );
bool connected ( epicsGuard < epicsMutex > & ) const;
private:
tsDLList < class baseNMIU > eventq;
caAccessRights accessRightState;
cac & cacCtx;
char * pNameStr;
netiiu * piiu;
ca_uint32_t sid; // server id
unsigned count;
unsigned retry; // search retry number
unsigned short nameLength; // channel name length
ca_uint16_t typeCode;
ca_uint8_t priority;
virtual void destroy (
epicsGuard < epicsMutex > & callbackControlGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard );
void initiateConnect (
epicsGuard < epicsMutex > & );
void eliminateExcessiveSendBacklog (
epicsGuard < epicsMutex > * pCallbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard );
ioStatus read (
epicsGuard < epicsMutex > &,
unsigned type, arrayElementCount count,
cacReadNotify &, ioid * );
void write (
epicsGuard < epicsMutex > &,
unsigned type, arrayElementCount count,
const void *pValue );
ioStatus write (
epicsGuard < epicsMutex > &,
unsigned type, arrayElementCount count,
const void *pValue, cacWriteNotify &, ioid * );
void subscribe (
epicsGuard < epicsMutex > & guard,
unsigned type, arrayElementCount nElem,
unsigned mask, cacStateNotify &notify, ioid * );
virtual void ioCancel (
epicsGuard < epicsMutex > & callbackControlGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const ioid & );
void ioShow (
epicsGuard < epicsMutex > &,
const ioid &, unsigned level ) const;
short nativeType (
epicsGuard < epicsMutex > & ) const;
caAccessRights accessRights (
epicsGuard < epicsMutex > & ) const;
unsigned searchAttempts (
epicsGuard < epicsMutex > & ) const;
double beaconPeriod (
epicsGuard < epicsMutex > & ) const;
double receiveWatchdogDelay (
epicsGuard < epicsMutex > & ) const;
bool ca_v42_ok (
epicsGuard < epicsMutex > & ) const;
arrayElementCount nativeElementCount (
epicsGuard < epicsMutex > & ) const;
static void stringVerify ( const char *pStr, const unsigned count );
virtual void ioCompletionNotify (
epicsGuard < epicsMutex > &, class baseNMIU & );
nciu ( const nciu & );
nciu & operator = ( const nciu & );
void * operator new ( size_t );
void operator delete ( void * );
};
inline void * nciu::operator new ( size_t size,
tsFreeList < class nciu, 1024, epicsMutexNOOP > & freeList )
{
return freeList.allocate ( size );
}
#ifdef CXX_PLACEMENT_DELETE
inline void nciu::operator delete ( void * pCadaver,
tsFreeList < class nciu, 1024, epicsMutexNOOP > & freeList )
{
freeList.release ( pCadaver, sizeof ( nciu ) );
}
#endif
inline ca_uint32_t nciu::getSID (
epicsGuard < epicsMutex > & ) const
{
return this->sid;
}
inline ca_uint32_t nciu::getCID (
epicsGuard < epicsMutex > & ) const
{
return this->id;
}
// this is to only be used by early protocol revisions
inline void nciu::connect ( epicsGuard < epicsMutex > & cbGuard,
epicsGuard < epicsMutex > & guard )
{
this->connect ( this->typeCode, this->count,
this->sid, cbGuard, guard );
}
inline void nciu::searchReplySetUp ( netiiu &iiu, unsigned sidIn,
ca_uint16_t typeIn, arrayElementCount countIn,
epicsGuard < epicsMutex > & )
{
this->piiu = & iiu;
this->typeCode = typeIn;
this->count = countIn;
this->sid = sidIn;
}
inline netiiu * nciu::getPIIU (
epicsGuard < epicsMutex > & )
{
return this->piiu;
}
inline void nciu::writeException (
epicsGuard < epicsMutex > & /* cbGuard */,
epicsGuard < epicsMutex > & guard,
int status, const char * pContext,
unsigned typeIn, arrayElementCount countIn )
{
this->notify().writeException ( guard,
status, pContext, typeIn, countIn );
}
inline const netiiu * nciu::getConstPIIU (
epicsGuard < epicsMutex > & ) const
{
return this->piiu;
}
inline cac & nciu::getClient ()
{
return this->cacCtx;
}
inline cacChannel::priLev nciu::getPriority (
epicsGuard < epicsMutex > & ) const
{
return this->priority;
}
inline channelNode::channelNode () :
listMember ( cs_none )
{
}
inline bool channelNode::isConnectedAtOrAfterV42 ( epicsGuard < epicsMutex > & ) const
{
return
this->listMember == cs_connected ||
this->listMember == cs_subscripReqPend ||
this->listMember == cs_subscripUpdateReqPend;
}
inline bool channelNode::isConnectedBeforeV42 ( epicsGuard < epicsMutex > & ) const
{
return
this->listMember == cs_connected ||
this->listMember == cs_subscripReqPend ||
this->listMember == cs_subscripUpdateReqPend ||
this->listMember == cs_createReqPend;
}
inline bool channelNode::isInstalledInServer ( epicsGuard < epicsMutex > & ) const
{
return
this->listMember == cs_connected ||
this->listMember == cs_subscripReqPend ||
this->listMember == cs_unrespCircuit ||
this->listMember == cs_subscripUpdateReqPend;
}
#endif // ifdef nciuh