382 lines
12 KiB
C++
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 ¬ify, 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
|