better diagnostics and disconnect claims pending channels

in tcpiiu::~tcpiiu
This commit is contained in:
Jeff Hill
2000-09-06 00:33:14 +00:00
parent 6387924a87
commit 87a8230100
25 changed files with 427 additions and 168 deletions

View File

@@ -77,11 +77,12 @@ Com_DIR = $(INSTALL_LIB)
caRepeater_SRCS = caRepeater.cpp
PROD += caRepeater
PROD_DEFAULT += catime acctst
PROD_DEFAULT += catime acctst caConnTest
catime_SRCS = catimeMain.c catime.c
acctst_SRCS = acctstMain.c acctst.c
caConnTest_SRCS = caConnTestMain.c caConnTest.c
PROD_vxWorks = catime acctst
PROD_vxWorks = catime acctst caConnTest
include $(TOP)/configure/RULES

View File

@@ -790,19 +790,25 @@ unsigned epicsShareAPI ca_get_ioc_connection_count ()
return pcac->connectionCount ();
}
epicsShareFunc int epicsShareAPI ca_channel_status (threadId /* tid */)
epicsShareFunc int epicsShareAPI ca_channel_status ( threadId tid )
{
printf ("new OSI API does not allow peeking at thread private storage of another thread\n");
printf ("please call \"ca_client_status ( unsigned level )\" from the subsystem specific diagnostic code.\n");
return ECA_ANACHRONISM;
}
epicsShareFunc int epicsShareAPI ca_client_status ( unsigned level )
{
cac *pcac;
int caStatus;
caStatus = fetchClientContext (&pcac);
caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
pcac->show (10u);
return ECA_NORMAL;
pcac->show ( level );
return ECA_NORMAL;
}
/*
@@ -1079,7 +1085,7 @@ extern "C" epicsShareDef const unsigned short dbr_value_offset[LAST_BUFFER_TYPE+
0, /* string */
};
extern "C" epicsShareDef const char *db_field_text[] = {
extern "C" epicsShareDef const char *dbf_text[LAST_TYPE+1] = {
"DBF_STRING",
"DBF_SHORT",
"DBF_FLOAT",

View File

@@ -302,8 +302,14 @@ void verifyBlockingConnect ( appChan *pChans, unsigned chanCount, unsigned repet
assert ( VALID_DB_REQ ( ca_field_type ( pChans[j].channel ) ) == TRUE );
}
else {
assert ( INVALID_DB_REQ ( ca_field_type ( pChans[j].channel ) ) == TRUE );
assert ( ca_test_io () == ECA_IOINPROGRESS );
/*
* its possible for the channel to connect while this test is going on
*/
unsigned ctr;
for ( ctr = 0u; ctr < 100u; ctr ++ ) {
assert ( INVALID_DB_REQ ( ca_field_type ( pChans[j].channel ) ) == TRUE );
assert ( ca_test_io () == ECA_IOINPROGRESS );
}
}
status = ca_replace_access_rights_event (

View File

@@ -32,3 +32,8 @@ int baseNMIU::subscriptionMsg ()
{
return ECA_NORMAL;
}
void baseNMIU::show ( unsigned /* level */ ) const
{
printf ( "CA IO primitive at %p for channel %s\n", this, chan.pName () );
}

View File

@@ -139,3 +139,10 @@ bool bhe::updateBeaconPeriod (osiTime programBeginTime)
return netChange;
}
void bhe::show ( unsigned level ) const
{
printf ( "CA beacon hash entry at %p with average period %f\n", this, this->averagePeriod );
if ( level > 0u ) {
printf ( "network IO pointer %p, client pointer %p\n", this->piiu, &this->cac );
}
}

View File

@@ -50,8 +50,7 @@ void caConnTest ( const char *pNameIn, unsigned channelCountIn, double delayIn )
status = ca_pend_io ( 60.0 * 10.0 );
SEVCHK ( status, "channels didnt connect" );
status = ca_pend_event ( delayIn );
SEVCHK ( status, "CA pend event failed" );
ca_pend_event ( delayIn );
status = ca_task_exit();
SEVCHK ( status, "task exit problems" );

View File

@@ -5,6 +5,8 @@ int catime ( char *channelName, unsigned channelCount, enum appendNumberFlag app
int acctst ( char *pname, unsigned channelCount, unsigned repititionCount );
void caConnTest ( const char *pNameIn, unsigned channelCountIn, double delayIn );
#define CATIME_OK 0
#define CATIME_ERROR -1

View File

@@ -87,11 +87,6 @@ cac::cac ( bool enablePreemptiveCallbackIn ) :
this->ca_exception_arg = NULL;
this->readSeq = 0u;
this->ca_blockSem = semBinaryCreate(semEmpty);
if (!this->ca_blockSem) {
throwWithLocation ( caErrorCode (ECA_ALLOCMEM) );
}
installSigPipeIgnore ();
{
@@ -106,7 +101,6 @@ cac::cac ( bool enablePreemptiveCallbackIn ) :
len = strlen ( tmp ) + 1;
this->pUserName = new char [len];
if ( ! this->pUserName ) {
semBinaryDestroy (this->ca_blockSem);
throwWithLocation ( caErrorCode (ECA_ALLOCMEM) );
}
strncpy ( this->pUserName, tmp, len );
@@ -209,7 +203,6 @@ cac::~cac ()
this->beaconTable.destroyAllEntries ();
this->chanTable.destroyAllEntries ();
this->ioTable.destroyAllEntries ();
semBinaryDestroy ( this->ca_blockSem );
osiSockRelease ();
@@ -275,21 +268,89 @@ unsigned cac::connectionCount () const
return this->iiuList.count ();
}
void cac::show (unsigned level) const
void cac::show ( unsigned level ) const
{
if ( this->pudpiiu ) {
this->pudpiiu->show (level);
::printf ( "Channel Access Client Context at %p for user %s\n",
this, this->pUserName );
if (level > 0u ) {
this->iiuListMutex.lock ();
tsDLIterConstBD < tcpiiu > piiu ( this->iiuList.first () );
while ( piiu.valid () ) {
piiu->show ( level - 1u );
piiu++;
}
this->iiuListMutex.unlock ();
this->defaultMutex.lock ();
tsDLIterConstBD < cacLocalChannelIO > pChan ( this->localChanList.first () );
while ( pChan.valid () ) {
pChan->show ( level - 1u );
pChan++;
}
this->defaultMutex.unlock ();
::printf ( "\tconnection time out watchdog period %f\n", this->connTMO );
::printf ( "\tthere are %u unsatisfied IO operations blocking ca_pend_io()\n",
this->pndrecvcnt );
::printf ( "\tpreemptive calback is %s\n",
this->enablePreemptiveCallback ? "enabled" : "disabled" );
::printf ( "list of installed services:\n" );
this->services.show ( level - 1u );
}
this->iiuListMutex.lock ();
if ( level > 1u ) {
if ( this->pudpiiu ) {
this->pudpiiu->show ( level - 2u );
}
::printf ( "\texception function %p, exception arg %p\n",
this->ca_exception_func, this->ca_exception_arg );
::printf ( "\tCA printf function %p\n",
this->pVPrintfFunc);
::printf ( "\tfile descriptor registration function %p, file descriptor registration arg %p\n",
this->fdRegFunc, this->fdRegArg );
}
tsDLIterConstBD <tcpiiu> piiu ( this->iiuList.first () );
while ( piiu.valid () ) {
piiu->show (level);
piiu++;
}
if ( level > 2u ) {
::printf ( "Program begin time:\n");
::printf ( "the current read sequence for ca_pend_io() is %u\n",
this->readSeq );
this->programBeginTime.show ( level - 3u );
::printf ( "IO identifier hash table:\n" );
this->ioTable.show ( level - 3u );
::printf ( "Channel identifier hash table:\n" );
this->chanTable.show ( level - 3u );
::printf ( "Synchronous group identifier hash table:\n" );
this->sgTable.show ( level - 3u );
::printf ( "Beacon source identifier hash table:\n" );
this->beaconTable.show ( level - 3u );
if ( this->pTimerQueue ) {
::printf ( "Timer queue:\n" );
this->pTimerQueue->show ( level - 3u );
}
if ( this->pRecvProcThread ) {
::printf ( "incoming messages processing thread:\n" );
this->pRecvProcThread->show ( level - 3u );
}
if ( this->pSearchTmr ) {
::printf ( "search message timer:\n" );
this->pSearchTmr->show ( level - 3u );
}
if ( this->pRepeaterSubscribeTmr ) {
::printf ( "repeater subscribee timer:\n" );
this->pRepeaterSubscribeTmr->show ( level - 3u );
}
::printf ( "IP address to name conversion engine:\n" );
this->ipToAEngine.show ( level - 3u );
}
this->iiuListMutex.unlock ();
if ( level > 3u ) {
::printf ( "IO done event:\n");
this->ioDone.show ( level - 4u );
::printf ( "Default mutex:\n");
this->defaultMutex.show ( level - 4u );
::printf ( "Virtual circuit list mutex:\n");
this->iiuListMutex.show ( level - 4u );
}
}
void cac::installIIU ( tcpiiu &iiu )
@@ -451,8 +512,8 @@ void cac::beaconNotify ( const inetAddrID &addr )
delay /= MSEC_PER_SEC;
delay += CA_RECAST_DELAY;
if ( this->pSearchTmr ) {
this->pSearchTmr->reset ( delay );
if ( this->pudpiiu->channelCount () > 0u && this->pSearchTmr ) {
this->pSearchTmr->resetPeriod ( delay );
}
}
@@ -1054,7 +1115,7 @@ void cac::installDisconnectedChannel ( nciu &chan )
chan.attachChanToIIU ( *this->pudpiiu );
chan.resetRetryCount ();
this->pSearchTmr->reset ( CA_RECAST_DELAY );
this->pSearchTmr->resetPeriod ( CA_RECAST_DELAY );
}
void cac::notifySearchResponse ( unsigned short retrySeqNo )

View File

@@ -119,6 +119,8 @@ public:
virtual void lockOutstandingIO () const = 0;
virtual void unlockOutstandingIO () const = 0;
virtual void show ( unsigned level ) const = 0u;
private:
virtual int read ( unsigned type, unsigned long count, void *pValue) = 0;
virtual int read ( unsigned type, unsigned long count, cacNotify &notify ) = 0;
@@ -144,15 +146,16 @@ private:
};
class cacLocalChannelIO :
public cacChannelIO, public tsDLNode <cacLocalChannelIO> {
public cacChannelIO, public tsDLNode < cacLocalChannelIO > {
public:
epicsShareFunc cacLocalChannelIO ( cacChannel &chan );
epicsShareFunc virtual ~cacLocalChannelIO () = 0;
};
struct cacServiceIO : public tsDLNode <cacServiceIO> {
struct cacServiceIO : public tsDLNode < cacServiceIO > {
public:
epicsShareFunc virtual cacLocalChannelIO *createChannelIO ( cacChannel &chan, const char *pName ) = 0;
epicsShareFunc virtual void show ( unsigned level ) const = 0u;
private:
};
@@ -160,9 +163,10 @@ class cacServiceList : private osiMutex {
public:
epicsShareFunc cacServiceList ();
epicsShareFunc void registerService ( cacServiceIO &service );
epicsShareFunc cacLocalChannelIO * createChannelIO (const char *pName, cacChannel &chan);
epicsShareFunc cacLocalChannelIO * createChannelIO ( const char *pName, cacChannel &chan );
epicsShareFunc void show ( unsigned level ) const;
private:
tsDLList <cacServiceIO> services;
tsDLList < cacServiceIO > services;
};
epicsShareExtern cacServiceList cacGlobalServiceList;

View File

@@ -48,3 +48,16 @@ cacLocalChannelIO * cacServiceList::createChannelIO (const char *pName, cacChann
return pChanIO;
}
void cacServiceList::show ( unsigned level ) const
{
cacLocalChannelIO *pChanIO = 0;
this->lock ();
tsDLIterConstBD < cacServiceIO > iter ( this->services.first () );
while ( iter.valid () ) {
iter->show ( level );
iter++;
}
this->unlock ();
}

View File

@@ -940,6 +940,7 @@ epicsShareFunc int epicsShareAPI ca_current_context (caClientCtx *pCurrentContex
epicsShareFunc int epicsShareAPI ca_attach_context (caClientCtx context);
epicsShareFunc int epicsShareAPI ca_channel_status (threadId tid);
epicsShareFunc int epicsShareAPI ca_client_status (threadId tid, unsigned level);
/*
* deprecated
@@ -996,6 +997,7 @@ epicsShareFunc char * epicsShareAPI ca_version();
epicsShareFunc int epicsShareAPI ca_import();
epicsShareFunc int epicsShareAPI ca_import_cancel();
epicsShareFunc int epicsShareAPI ca_channel_status ();
epicsShareFunc int epicsShareAPI ca_client_status ();
#define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\
ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0)
#define ca_array_build(NAME,XXXXX, ZZZZZZ, CHIDPTR,YYYYY)\

View File

@@ -736,7 +736,7 @@ union db_access_val{
#define dbf_type_to_text(type) \
( ((type) >= 0 && (type) < dbf_text_dim) ? \
db_field_text[type] : dbf_text_invalid )
dbf_text[type] : dbf_text_invalid )
#define dbf_text_to_type(text, type) \
for (type=dbf_text_dim-1; type>=0; type--) { \
@@ -775,7 +775,7 @@ union db_access_val{
(type) + 4*(dbf_text_dim-2) : -1 )
epicsShareExtern READONLY char *dbf_text[LAST_TYPE+2];
epicsShareExtern READONLY char *dbf_text[LAST_TYPE+1];
epicsShareExtern READONLY short dbf_text_dim;
epicsShareExtern READONLY char *dbf_text_invalid;

View File

@@ -320,21 +320,23 @@ public:
void ioInstall ( class baseNMIU & );
void ioDestroy ( unsigned id );
void show ( unsigned level ) const;
private:
caar ar; /* access rights */
caar ar; // access rights
unsigned count;
char *pNameStr;
netiiu *piiu;
unsigned sid; /* server id */
unsigned retry; /* search retry number */
mutable unsigned short ptrLockCount; /* number of times IIU pointer was locked */
mutable unsigned short ptrUnlockWaitCount; /* number of threads waiting for IIU pointer unlock */
unsigned short retrySeqNo; /* search retry seq number */
unsigned short nameLength; /* channel name length */
unsigned sid; // server id
unsigned retry; // search retry number
mutable unsigned short ptrLockCount; // number of times IIU pointer was locked
mutable unsigned short ptrUnlockWaitCount; // number of threads waiting for IIU pointer unlock
unsigned short retrySeqNo; // search retry seq number
unsigned short nameLength; // channel name length
unsigned short typeCode;
unsigned f_connected:1;
unsigned f_fullyConstructed:1;
unsigned previousConn:1; /* T if connected in the past */
unsigned previousConn:1; // T if connected in the past
static tsFreeList < class nciu, 1024 > freeList;
@@ -358,8 +360,9 @@ public:
virtual void completionNotify ( unsigned type, unsigned long count, const void *pData ) = 0;
virtual void exceptionNotify ( int status, const char *pContext ) = 0;
virtual void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count ) = 0;
virtual int subscriptionMsg ();
virtual void disconnect ( const char *pHostName ) = 0;
virtual void show ( unsigned level ) const;
virtual int subscriptionMsg ();
void destroy ();
protected:
virtual ~baseNMIU (); // must be allocated from pool
@@ -372,6 +375,7 @@ public:
void disconnect ( const char *pHostName );
static bool factory ( nciu &chan, chtype type, unsigned long count,
unsigned short mask, cacNotify &notify, unsigned &id );
void show ( unsigned level ) const;
private:
chtype type;
unsigned long count;
@@ -396,6 +400,7 @@ public:
void disconnect ( const char *pHostName );
static bool factory ( nciu &chan, unsigned type, unsigned long count,
void *pValue, unsigned seqNumber, ca_uint32_t &id );
void show ( unsigned level ) const;
private:
unsigned type;
unsigned long count;
@@ -418,6 +423,7 @@ class netReadNotifyIO : public cacNotifyIO, private baseNMIU {
public:
void disconnect ( const char *pHostName );
static bool factory ( nciu &chan, cacNotify &notify, ca_uint32_t &id );
void show ( unsigned level ) const;
private:
netReadNotifyIO ( nciu &chan, cacNotify &notify );
~netReadNotifyIO ();
@@ -435,6 +441,7 @@ class netWriteNotifyIO : public cacNotifyIO, private baseNMIU {
public:
void disconnect ( const char *pHostName );
static bool factory ( nciu &chan, cacNotify &notify, ca_uint32_t &id );
void show ( unsigned level ) const;
private:
netWriteNotifyIO ( nciu &chan, cacNotify &notify );
~netWriteNotifyIO ();
@@ -529,7 +536,7 @@ protected:
void lock () const;
void unlock () const;
private:
tsDLList < nciu > chidList;
tsDLList < nciu > channelList;
class cac &cacRef;
osiMutex mutex;
@@ -545,15 +552,14 @@ class searchTimer : private osiTimer, private osiMutex {
public:
searchTimer ( udpiiu &iiu, osiTimerQueue &queue );
void notifySearchResponse ( unsigned short retrySeqNo );
void reset ( double delayToNextTry );
void resetPeriod ( double delayToNextTry );
void show ( unsigned level ) const;
private:
virtual void expire ();
virtual void destroy ();
virtual bool again () const;
virtual double delay () const;
virtual void show (unsigned level) const;
virtual const char *name () const;
void expire ();
void destroy ();
bool again () const;
double delay () const;
const char *name () const;
void setRetryInterval (unsigned retryNo);
@@ -573,14 +579,14 @@ class repeaterSubscribeTimer : private osiTimer {
public:
repeaterSubscribeTimer (udpiiu &iiu, osiTimerQueue &queue);
void confirmNotify ();
void show (unsigned level) const;
private:
virtual void expire ();
virtual void destroy ();
virtual bool again () const;
virtual double delay () const;
virtual void show (unsigned level) const;
virtual const char *name () const;
void expire ();
void destroy ();
bool again () const;
double delay () const;
const char *name () const;
udpiiu &iiu;
unsigned attempts;
@@ -602,12 +608,12 @@ public:
void flush ();
SOCKET getSock () const;
bool repeaterInstalled ();
void show ( unsigned level ) const;
// exceptions
class noSocket {};
class noMemory {};
private:
osiTime recvTime;
char xmitBuf [MAX_UDP_SEND];
char recvBuf [MAX_UDP_RECV];
ELLLIST dest;
@@ -649,6 +655,7 @@ public:
void beaconArrivalNotify ();
void beaconAnomalyNotify ();
void connectNotify ();
void show (unsigned level ) const;
private:
void expire ();
@@ -764,15 +771,8 @@ private:
unsigned long curDataMax;
class bhe &bhe;
void *pCurData;
unsigned minor_version_number;
unsigned minorProtocolVersionNumber;
iiu_conn_state state;
bool ca_v42_ok () const;
void postMsg ();
unsigned sendBytes ( const void *pBuf, unsigned nBytesInBuf );
unsigned recvBytes ( void *pBuf, unsigned nBytesInBuf );
bool flushToWirePermit ();
claimsPendingIIU *pClaimsPendingIIU;
semBinaryId sendThreadFlushSignal;
semBinaryId recvThreadRingBufferSpaceAvailableSignal;
@@ -783,12 +783,16 @@ private:
bool fullyConstructedFlag;
bool busyStateDetected; // only modified by the recv thread
bool flowControlActive; // only modified by the send process thread
bool flowControlStateChange;
bool echoRequestPending;
bool recvPending;
bool recvMessagePending;
bool flushPending;
bool msgHeaderAvailable;
static tsFreeList < class tcpiiu, 16 > freeList;
bool ca_v42_ok () const;
void postMsg ();
unsigned sendBytes ( const void *pBuf, unsigned nBytesInBuf );
unsigned recvBytes ( void *pBuf, unsigned nBytesInBuf );
bool flushToWirePermit ();
friend void cacSendThreadTCP ( void *pParam );
friend void cacRecvThreadTCP ( void *pParam );
@@ -812,6 +816,7 @@ private:
typedef void ( tcpiiu::*pProtoStubTCP ) ();
static const pProtoStubTCP tcpJumpTableCAC [];
static tsFreeList < class tcpiiu, 16 > freeList;
};
class inetAddrID {
@@ -825,13 +830,14 @@ private:
struct sockaddr_in addr;
};
class bhe : public tsSLNode <bhe>, public inetAddrID {
class bhe : public tsSLNode < bhe >, public inetAddrID {
public:
bhe ( class cac &cacIn, const osiTime &initialTimeStamp, const inetAddrID &addr );
tcpiiu *getIIU () const;
void bindToIIU ( tcpiiu & );
void destroy ();
bool updateBeaconPeriod ( osiTime programBeginTime );
void show ( unsigned level) const;
static void * operator new ( size_t size );
static void operator delete ( void *pCadaver, size_t size );
@@ -848,7 +854,7 @@ private:
class caErrorCode {
public:
caErrorCode (int status) : code (status) {};
caErrorCode ( int status ) : code ( status ) {};
private:
int code;
};
@@ -862,6 +868,7 @@ public:
void enable ();
void disable ();
void signalActivity ();
void show ( unsigned level ) const;
private:
//
// The additional complexity associated with
@@ -1052,7 +1059,6 @@ public:
private:
ipAddrToAsciiEngine ipToAEngine;
char ca_new_err_code_msg_buf[128u];
cacServiceList services;
tsDLList <tcpiiu> iiuList;
tsDLList
@@ -1067,21 +1073,20 @@ private:
< bhe, inetAddrID > beaconTable;
osiTime programBeginTime;
double connTMO;
osiEvent ioDone;
osiMutex defaultMutex;
osiMutex iiuListMutex;
osiTimerQueue *pTimerQueue;
caExceptionHandler *ca_exception_func;
void *ca_exception_arg;
caPrintfFunc *pVPrintfFunc;
char *pUserName;
osiEvent ioDone;
recvProcessThread *pRecvProcThread;
CAFDHANDLER *fdRegFunc;
void *fdRegArg;
udpiiu *pudpiiu;
searchTimer *pSearchTmr;
repeaterSubscribeTimer *pRepeaterSubscribeTmr;
semBinaryId ca_blockSem;
osiMutex defaultMutex;
osiMutex iiuListMutex;
unsigned pndrecvcnt;
unsigned readSeq;
bool enablePreemptiveCallback;

View File

@@ -515,31 +515,36 @@ void nciu::disconnect ()
{
char hostNameBuf[64];
this->hostName ( hostNameBuf, sizeof (hostNameBuf) );
bool wasConnected;
this->lock ();
if ( ! this->f_connected ) {
this->unlock ();
return;
}
this->retry = 0u;
this->typeCode = USHRT_MAX;
this->count = 0u;
this->sid = UINT_MAX;
this->ar.read_access = false;
this->ar.write_access = false;
if ( this->f_connected ) {
wasConnected = true;
}
else {
wasConnected = false;
}
this->f_connected = false;
this->unlock ();
/*
* look for events that have an event cancel in progress
*/
disconnectAllIO ( hostNameBuf );
this->disconnectNotify ();
this->accessRightsNotify ( this->ar );
if ( wasConnected ) {
/*
* look for events that have an event cancel in progress
*/
disconnectAllIO ( hostNameBuf );
this->disconnectNotify ();
this->accessRightsNotify ( this->ar );
}
this->cacCtx.installDisconnectedChannel ( *this );
}
@@ -626,8 +631,8 @@ void nciu::attachChanToIIU ( netiiu &iiu )
if ( this->piiu ) {
this->piiu->mutex.lock ();
this->piiu->chidList.remove ( *this );
if ( this->piiu->chidList.count () == 0u ) {
this->piiu->channelList.remove ( *this );
if ( this->piiu->channelList.count () == 0u ) {
this->piiu->lastChannelDetachNotify ();
}
this->piiu->mutex.unlock ();
@@ -637,7 +642,7 @@ void nciu::attachChanToIIU ( netiiu &iiu )
// add to the front of the list so that
// search requests for new channels will be sent first
iiu.chidList.push ( *this );
iiu.channelList.push ( *this );
this->piiu = &iiu;
iiu.mutex.unlock ();
@@ -650,8 +655,8 @@ void nciu::detachChanFromIIU ()
this->lockPIIU ();
if ( this->piiu ) {
this->piiu->mutex.lock ();
this->piiu->chidList.remove ( *this );
if ( this->piiu->chidList.count () == 0u ) {
this->piiu->channelList.remove ( *this );
if ( this->piiu->channelList.count () == 0u ) {
this->piiu->lastChannelDetachNotify ();
}
this->piiu->mutex.unlock ();
@@ -808,3 +813,37 @@ int nciu::subscribe ( unsigned type, unsigned long countIn,
return ECA_ALLOCMEM;
}
}
void nciu::show ( unsigned level ) const
{
if ( this->f_connected ) {
char hostNameTmp [256];
this->hostName ( hostNameTmp, sizeof ( hostNameTmp ) );
printf ( "Channel \"%s\", connected to server %s",
this->pNameStr, hostNameTmp );
if ( level > 1u ) {
printf ( ", native type %s, native element count %u",
dbf_type_to_text ( this->typeCode ), this->count );
printf ( ", %sread access, %swrite access",
this->ar.read_access ? "" : "no ",
this->ar.write_access ? "" : "no ");
}
printf ( "\n" );
}
else if ( this->previousConn ) {
printf ( "Channel \"%s\" (previously connected to a server)\n", this->pNameStr, hostName );
}
else {
printf ( "Channel \"%s\" (unable to locate server)\n", this->pNameStr, hostName );
}
if ( level > 2u ) {
printf ( "\tnetwork IO pointer=%p, ptr lock count=%u, ptr unlock wait count=%u\n",
this->piiu, this->ptrLockCount, this->ptrUnlockWaitCount );
printf ( "\tserver identifier %u\n", this->sid );
printf ( "\tsearch retry number=%u, search retry sequence number=%u\n",
this->retry, this->retrySeqNo );
printf ( "\tname length=%u\n", this->nameLength );
printf ( "\tfully cunstructed boolean=%u\n", this->f_fullyConstructed );
}
}

View File

@@ -70,3 +70,14 @@ void netReadCopyIO::exceptionNotify ( int status,
"%s type=%d count=%ld\n",
pContextIn, typeIn, countIn);
}
void netReadCopyIO::show ( unsigned level ) const
{
printf ( "read copy IO at %p, type %s, element count %u\n",
this, this->type, this->count );
if ( level > 0u ) {
printf ( "\tsequence number %u, user's storage %p\n",
this->seqNumber, this->pValue );
this->baseNMIU::show ( level - 1u );
}
}

View File

@@ -57,3 +57,11 @@ void netReadNotifyIO::exceptionNotify ( int status, const char *pContext,
{
this->cacNotifyIO::exceptionNotify ( status, pContext, type ,count );
}
void netReadNotifyIO::show ( unsigned level ) const
{
printf ( "read notify IO at %p\n", this );
if ( level > 0u ) {
this->baseNMIU::show ( level - 1u );
}
}

View File

@@ -67,3 +67,11 @@ void netSubscription::exceptionNotify ( int statusIn,
pContextIn, typeIn, countIn );
}
void netSubscription::show ( unsigned level ) const
{
printf ( "event subscription IO at %p, type %s, element count %lu, mask %u\n",
this, dbf_type_to_text ( this->type ), this->count, this->mask );
if ( level > 0u ) {
this->baseNMIU::show ( level - 1u );
}
}

View File

@@ -57,3 +57,11 @@ void netWriteNotifyIO::exceptionNotify ( int status, const char *pContext, unsig
{
this->cacNotifyIO::exceptionNotify (status, pContext, type, count);
}
void netWriteNotifyIO::show ( unsigned level ) const
{
printf ( "read write notify IO at %p\n", this );
if ( level > 0u ) {
this->baseNMIU::show ( level - 1u );
}
}

View File

@@ -18,46 +18,30 @@
netiiu::~netiiu ()
{
assert ( this->channelList.count () == 0u );
}
void netiiu::show ( unsigned /* level */ ) const
void netiiu::show ( unsigned level ) const
{
this->lock ();
tsDLIterConstBD <nciu> pChan ( this->chidList.first () );
while ( pChan.valid () ) {
char hostName [256];
printf( "%s native type=%d ",
pChan->pName (), pChan->nativeType () );
pChan->hostName ( hostName, sizeof (hostName) );
printf( "N elements=%lu server=%s state=",
pChan->nativeElementCount (), hostName );
switch ( pChan->state () ) {
case cs_never_conn:
printf ( "never connected to an IOC" );
break;
case cs_prev_conn:
printf ( "disconnected from IOC" );
break;
case cs_conn:
printf ( "connected to an IOC" );
break;
case cs_closed:
printf ( "invalid channel" );
break;
default:
break;
}
printf ( "\n" );
}
printf ( "network IO base class\n" );
if ( level > 1 ) {
tsDLIterConstBD < nciu > pChan ( this->channelList.first () );
while ( pChan.valid () ) {
pChan->show ( level - 1u );
pChan = pChan.itemAfter ();
}
}
if ( level > 2u ) {
printf ("\tcac pointer %p\n", &this->cacRef );
this->mutex.show ( level - 2u );
}
this->unlock ();
}
unsigned netiiu::channelCount () const
{
return this->chidList.count ();
return this->channelList.count ();
}
void netiiu::lock () const
@@ -73,7 +57,7 @@ void netiiu::unlock () const
void netiiu::detachAllChan ()
{
this->lock ();
tsDLIterBD <nciu> chan ( this->chidList.first () );
tsDLIterBD <nciu> chan ( this->channelList.first () );
while ( chan.valid () ) {
tsDLIterBD <nciu> next = chan.itemAfter ();
chan->detachChanFromIIU ();
@@ -85,7 +69,7 @@ void netiiu::detachAllChan ()
void netiiu::disconnectAllChan ()
{
this->lock ();
tsDLIterBD <nciu> chan ( this->chidList.first () );
tsDLIterBD <nciu> chan ( this->channelList.first () );
while ( chan.valid () ) {
tsDLIterBD <nciu> next = chan.itemAfter ();
chan->disconnect ();
@@ -97,7 +81,7 @@ void netiiu::disconnectAllChan ()
void netiiu::connectTimeoutNotify ()
{
this->lock ();
tsDLIterBD <nciu> chan ( this->chidList.first () );
tsDLIterBD <nciu> chan ( this->channelList.first () );
while ( chan.valid () ) {
chan->connectTimeoutNotify ();
chan++;
@@ -108,7 +92,7 @@ void netiiu::connectTimeoutNotify ()
void netiiu::resetChannelRetryCounts ()
{
this->lock ();
tsDLIterBD <nciu> chan ( this->chidList.first () );
tsDLIterBD <nciu> chan ( this->channelList.first () );
while ( chan.valid () ) {
chan->resetRetryCount ();
chan++;
@@ -122,12 +106,12 @@ bool netiiu::searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThis
this->lock ();
tsDLIterBD <nciu> chan = this->chidList.first ();
tsDLIterBD <nciu> chan = this->channelList.first ();
if ( chan.valid () ) {
status = chan->searchMsg ( retrySeqNumber, retryNoForThisChannel );
if ( status ) {
this->chidList.remove ( *chan );
this->chidList.add ( *chan );
this->channelList.remove ( *chan );
this->channelList.add ( *chan );
}
}
else {
@@ -149,7 +133,7 @@ void netiiu::sendPendingClaims ( tcpiiu &iiu, bool v42Ok, claimMsgCache &cache )
while ( 1 ) {
while (1) {
this->lock ();
tsDLIterBD < nciu > chan ( this->chidList.last () );
tsDLIterBD < nciu > chan ( this->channelList.last () );
if ( ! chan.valid () ) {
this->unlock ();
return;
@@ -172,7 +156,7 @@ void netiiu::sendPendingClaims ( tcpiiu &iiu, bool v42Ok, claimMsgCache &cache )
this->lock ();
// if the channel was not deleted while the lock was off
tsDLIterBD < nciu > chan ( this->chidList.last () );
tsDLIterBD < nciu > chan ( this->channelList.last () );
if ( chan.valid () ) {
if ( cache.channelMatches ( *chan ) ) {
if ( ! v42Ok ) {

View File

@@ -115,3 +115,29 @@ void recvProcessThread::signalActivity ()
{
this->recvActivity.signal ();
}
void recvProcessThread::show ( unsigned level ) const
{
this->mutex.lock ();
printf ( "CA receive processing thread at %p state=%s\n",
this, this->processing ? "busy" : "idle");
if ( level > 0u ) {
printf ( "enable count %u\n", this->enableRefCount );
printf ( "blocking for completion count %u\n", this->blockingForCompletion );
}
if ( level > 1u ) {
printf ( "\tCA client at %p\n", this->pcac );
printf ( "\tshutdown command boolean %u\n", this->shutDown );
}
if ( level > 2u ) {
printf ( "Receive activity event:\n" );
this->recvActivity.show ( level - 3u );
printf ( "exit event:\n" );
this->exit.show ( level - 3u );
printf ( "processing done event:\n" );
this->processingDone.show ( level - 3u );
printf ( "mutex:\n" );
this->mutex.show ( level - 3u );
}
this->mutex.unlock ();
}

View File

@@ -37,9 +37,9 @@ searchTimer::searchTimer (udpiiu &iiuIn, osiTimerQueue &queueIn) :
}
//
// searchTimer::reset ()
// searchTimer::resetPeriod ()
//
void searchTimer::reset ( double delayToNextTry )
void searchTimer::resetPeriod ( double delayToNextTry )
{
bool reschedule;

View File

@@ -100,3 +100,16 @@ const char *tcpRecvWatchdog::name () const
return "TCP Receive Watchdog";
}
void tcpRecvWatchdog::show ( unsigned level ) const
{
printf ( "Receive virtual circuit watchdog at %p, period %s\n",
this, this->period );
if ( level > 0u ) {
printf ( "\tresponse pending boolean %u, beacon anomaly boolean %u\n",
this->responsePending, this->beaconAnomaly );
}
if ( level > 1u ) {
printf ( "\techo protocol accepted boolean %u\n",
this->echoProtocolAccepted );
}
}

View File

@@ -132,7 +132,7 @@ void tcpiiu::connect ()
extern "C" void cacSendThreadTCP ( void *pParam )
{
tcpiiu *piiu = ( tcpiiu * ) pParam;
claimMsgCache cache ( CA_V44 ( CA_PROTOCOL_VERSION, piiu->minor_version_number ) );
claimMsgCache cache ( CA_V44 ( CA_PROTOCOL_VERSION, piiu->minorProtocolVersionNumber ) );
while ( true ) {
@@ -144,7 +144,7 @@ extern "C" void cacSendThreadTCP ( void *pParam )
if ( piiu->pClaimsPendingIIU->channelCount () > 0u ) {
piiu->pClaimsPendingIIU->sendPendingClaims ( *piiu,
CA_V42 ( CA_PROTOCOL_VERSION, piiu->minor_version_number ), cache );
CA_V42 ( CA_PROTOCOL_VERSION, piiu->minorProtocolVersionNumber ), cache );
piiu->flushPending = true;
}
@@ -281,10 +281,6 @@ unsigned tcpiiu::recvBytes ( void *pBuf, unsigned nBytesInBuf )
this->contigRecvMsgCount = 0u;
this->busyStateDetected = false;
}
// care is taken not to post the busy/ready message to the send buffer
// here so that we avoid push/pull deadlocks
this->flowControlStateChange = this->busyStateDetected != this->flowControlActive;
this->messageArrivalNotify (); // reschedule connection activity watchdog
@@ -319,7 +315,7 @@ extern "C" void cacRecvThreadTCP (void *pParam)
else {
unsigned nBytesIn = piiu->fillFromWire ();
if ( nBytesIn ) {
piiu->recvPending = true;
piiu->recvMessagePending = true;
piiu->clientCtx ().signalRecvActivity ();
}
}
@@ -351,8 +347,7 @@ tcpiiu::tcpiiu ( cac &cac, const osiSockAddr &addrIn,
contigRecvMsgCount ( 0u ),
busyStateDetected ( false ),
flowControlActive ( false ),
flowControlStateChange ( false ),
recvPending ( false ),
recvMessagePending ( false ),
flushPending ( false ),
msgHeaderAvailable ( false )
{
@@ -414,7 +409,7 @@ tcpiiu::tcpiiu ( cac &cac, const osiSockAddr &addrIn,
#endif
this->sock = newSocket;
this->minor_version_number = minorVersion;
this->minorProtocolVersionNumber = minorVersion;
this->echoRequestPending = false;
this->curDataMax = 0ul;
memset ( (void *) &this->curMsg, '\0', sizeof (this->curMsg) );
@@ -524,7 +519,6 @@ void tcpiiu::cleanShutdown ()
}
semBinaryGive ( this->sendThreadFlushSignal );
semBinaryGive ( this->recvThreadRingBufferSpaceAvailableSignal );
this->recvPending = true;
this->clientCtx ().signalRecvActivity ();
}
this->unlock ();
@@ -545,7 +539,6 @@ void tcpiiu::forcedShutdown ()
}
semBinaryGive ( this->sendThreadFlushSignal );
semBinaryGive ( this->recvThreadRingBufferSpaceAvailableSignal );
this->recvPending = true;
this->clientCtx ().signalRecvActivity ();
}
this->unlock ();
@@ -563,8 +556,6 @@ tcpiiu::~tcpiiu ()
this->fullyConstructedFlag = false;
this->cleanShutdown ();
if ( this->channelCount () ) {
char hostNameTmp[64];
this->ipToA.hostName ( hostNameTmp, sizeof ( hostNameTmp ) );
@@ -573,14 +564,17 @@ tcpiiu::~tcpiiu ()
this->disconnectAllChan ();
if ( this->pClaimsPendingIIU ) {
this->pClaimsPendingIIU->disconnectAllChan ();
delete this->pClaimsPendingIIU;
}
this->cleanShutdown ();
// wait for send and recv threads to exit
semBinaryMustTake ( this->sendThreadExitSignal );
semBinaryMustTake ( this->recvThreadExitSignal );
if ( this->pClaimsPendingIIU ) {
delete this->pClaimsPendingIIU;
}
semBinaryDestroy ( this->sendThreadExitSignal );
semBinaryDestroy ( this->recvThreadExitSignal );
semBinaryDestroy ( this->sendThreadFlushSignal );
@@ -617,8 +611,44 @@ bool tcpiiu::connectionInProgress ( const char *pChannelName, const osiSockAddr
return true;
}
void tcpiiu::show ( unsigned /* level */ ) const
void tcpiiu::show ( unsigned level ) const
{
this->lock ();
char buf[256];
this->ipToA.hostName ( buf, sizeof ( buf ) );
printf ( "Virtual circuit to \"%s\" at version %u.%u state %u\n",
buf, CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber,
this->state );
if ( level > 1u ) {
this->netiiu::show ( level - 1u );
}
if ( level > 2u ) {
printf ( "\tcurrent data cache pointer = %p current data cache size = %u\n",
this->pCurData, this->curDataMax );
printf ( "\tcontiguous receive message count=%u, busy detect bool=%u, flow control bool=%u\n",
this->contigRecvMsgCount, this->busyStateDetected, this->flowControlActive );
}
if ( level > 3u ) {
printf ( "\tvirtual circuit socket identifier %d\n", this->sock );
printf ( "\tsend thread flush signal:\n" );
semBinaryShow ( this->sendThreadFlushSignal, level-3u );
printf ( "\trecv thread buffer space available signal:\n" );
semBinaryShow ( this->recvThreadRingBufferSpaceAvailableSignal, level-3u );
printf ( "\tsend thread exit signal:\n" );
semBinaryShow ( this->sendThreadExitSignal, level-3u );
printf ( "\trecv thread exit signal:\n" );
semBinaryShow ( this->recvThreadExitSignal, level-3u );
printf ( "\tfully constructed bool %u\n", this->fullyConstructedFlag );
printf ("\techo pending bool = %u\n", this->echoRequestPending );
printf ("\treceive message pending bool = %u\n", this->recvMessagePending );
printf ("\tflush pending bool = %u\n", this->flushPending );
printf ("\treceive message header available bool = %u\n", this->msgHeaderAvailable );
if ( this->pClaimsPendingIIU ) {
this->pClaimsPendingIIU->show ( level - 3u );
}
this->bhe.show ( level - 3u );
}
this->unlock ();
}
void tcpiiu::echoRequest ()
@@ -632,7 +662,7 @@ void tcpiiu::echoRequest ()
*/
void tcpiiu::echoRequestMsg ()
{
if ( CA_V43 ( CA_PROTOCOL_VERSION, this->minor_version_number ) ) {
if ( CA_V43 ( CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber ) ) {
this->comQueSend::echoRequest ();
}
else {
@@ -671,7 +701,7 @@ void tcpiiu::disableFlowControlMsg ()
*/
void tcpiiu::hostNameSetMsg ()
{
if ( ! CA_V41 ( CA_PROTOCOL_VERSION, this->minor_version_number ) ) {
if ( ! CA_V41 ( CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber ) ) {
return;
}
@@ -683,7 +713,7 @@ void tcpiiu::hostNameSetMsg ()
*/
void tcpiiu::userNameSetMsg ()
{
if ( ! CA_V41 ( CA_PROTOCOL_VERSION, this->minor_version_number ) ) {
if ( ! CA_V41 ( CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber ) ) {
return;
}
@@ -736,7 +766,7 @@ void tcpiiu::readNotifyRespAction ()
* read notify status starting
* with CA V4.1
*/
v41 = CA_V41 ( CA_PROTOCOL_VERSION, this->minor_version_number );
v41 = CA_V41 ( CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber );
if (v41) {
status = this->curMsg.m_cid;
}
@@ -789,7 +819,7 @@ void tcpiiu::eventRespAction ()
* read notify status starting
* with CA V4.1
*/
v41 = CA_V41 ( CA_PROTOCOL_VERSION, this->minor_version_number );
v41 = CA_V41 ( CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber );
if (v41) {
status = this->curMsg.m_cid;
}
@@ -1065,8 +1095,8 @@ void tcpiiu::processIncomingAndDestroySelfIfDisconnected ()
if ( this->state == iiu_disconnected ) {
this->suicide ();
}
else if ( this->recvPending ) {
this->recvPending = false;
else if ( this->recvMessagePending ) {
this->recvMessagePending = false;
this->postMsg ();
}
}

View File

@@ -62,17 +62,17 @@ inline void tcpiiu::flush ()
inline bool tcpiiu::ca_v44_ok () const
{
return CA_V44 ( CA_PROTOCOL_VERSION, this->minor_version_number );
return CA_V44 ( CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber );
}
inline bool tcpiiu::ca_v42_ok () const
{
return CA_V42 ( CA_PROTOCOL_VERSION, this->minor_version_number );
return CA_V42 ( CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber );
}
inline bool tcpiiu::ca_v41_ok () const
{
return CA_V41 ( CA_PROTOCOL_VERSION, this->minor_version_number );
return CA_V41 ( CA_PROTOCOL_VERSION, this->minorProtocolVersionNumber );
}
inline bool tcpiiu::alive () const

View File

@@ -822,4 +822,25 @@ SOCKET udpiiu::getSock () const
return this->sock;
}
void udpiiu::show ( unsigned level ) const
{
this->lock ();
printf ( "Datagram IO circuit (and disconnected channel repository)\n");
if ( level > 1u ) {
this->netiiu::show ( level - 1u );
}
if ( level > 2u ) {
printf ("\trepeater port %u\n", this->repeaterPort );
printf ("\tdefault server port %u\n", this->serverPort );
printChannelAccessAddressList ( &this->dest );
}
if ( level > 3u ) {
printf ("\tsocket identifier %d\n", this->sock );
printf ("\tbytes in xmit buffer %u\n", this->nBytesInXmitBuf );
printf ("\tshut down command bool %u\n", this->shutdownCmd );
printf ( "\trecv thread exit signal:\n" );
semBinaryShow ( this->recvThreadExitSignal, level-3u );
}
this->unlock ();
}