redesigned class hierarchy

This commit is contained in:
Jeff Hill
2001-02-09 17:38:00 +00:00
parent cebb5854cf
commit a1fbe85e7b
25 changed files with 819 additions and 879 deletions

View File

@@ -10,13 +10,13 @@
* Author: Jeff Hill
*
* Notes:
* 1) This class has a pointer to the IIU. Since it is possible
* for the channel to exist when no IIU exists (because the user
* created the channel), and because an IIU can disconnect and be
* destroyed at any time, then it is necessary to hold a mutex while
* the IIU pointer is in use. This mutex can not be the IIU's mutex
* because the IIU's lock must not be held while waiting for a
* message to be sent (otherwise a push pull deadlock can occur).
* 1) This class has a pointer to the IIU. This pointer always points at
* a valid IIU. If the client is deleted then the channel points at a
* static file scope IIU. IIU's that disconnect go into an inactive state
* and are stored on a list for later reuse. When the channel calls a
* member function of the IIU, the IIU verifies that the channel's IIU
* pointer is still pointing at itself only after it has acquired the IIU
* lock.
*/
#include "iocinf.h"
@@ -33,7 +33,7 @@ tsFreeList < class nciu, 1024 > nciu::freeList;
static const caar defaultAccessRights = { false, false };
nciu::nciu ( cac &cacIn, netiiu &iiuIn, cacChannel &chanIn,
nciu::nciu ( cac &cacIn, netiiu &iiuIn, cacChannelNotify &chanIn,
const char *pNameIn ) :
cacChannelIO ( chanIn ),
cacCtx ( cacIn ),
@@ -48,7 +48,9 @@ nciu::nciu ( cac &cacIn, netiiu &iiuIn, cacChannel &chanIn,
f_connected ( false ),
f_fullyConstructed ( true ),
f_previousConn ( false ),
f_claimSent ( false )
f_claimSent ( false ),
f_firstConnectDecrementsOutstandingIO ( false ),
f_connectTimeOutSeen ( false )
{
// second constraint is imposed by size field in protocol header
if ( this->nameLength > MAX_UDP_SEND - sizeof ( caHdr ) || this->nameLength > 0xffff ) {
@@ -67,13 +69,16 @@ void nciu::destroy ()
{
// this occurs here so that it happens when
// a lock is not applied
this->piiu->destroyAllIO ( *this );
unsigned i = 0u;
while ( ! this->piiu->destroyAllIO ( *this ) ) {
if ( i++ > 1000u ) {
this->cacCtx.printf (
"CAC: unable to destroy IO when channel destroyed?\n" );
break;
}
}
this->piiu->clearChannelRequest ( *this );
this->cacCtx.destroyNCIU ( *this );
}
void nciu::cacDestroy ()
{
this->cacCtx.uninstallChannel ( *this );
delete this;
}
@@ -83,9 +88,11 @@ nciu::~nciu ()
return;
}
// this must go in the derived class's destructor because
// this calls virtual functions in the cacChannelIO base
this->ioReleaseNotify ();
if ( ! this->f_connectTimeOutSeen && ! this->f_previousConn ) {
if ( this->f_firstConnectDecrementsOutstandingIO ) {
this->cacCtx.decrementOutstandingIO ();
}
}
delete [] this->pNameStr;
}
@@ -217,6 +224,12 @@ int nciu::write ( unsigned type, unsigned long countIn, const void *pValue, cacN
return this->piiu->writeNotifyRequest ( *this, notify, type, countIn, pValue );
}
void nciu::initiateConnect ()
{
this->notifyStateChangeFirstConnectInCountOfOutstandingIO ();
this->cacCtx.installNetworkChannel ( *this, this->piiu );
}
void nciu::connect ( unsigned nativeType,
unsigned long nativeCount, unsigned sidIn )
{
@@ -235,6 +248,13 @@ void nciu::connect ( unsigned nativeType,
}
this->lock ();
if ( ! this->f_connectTimeOutSeen && ! this->f_previousConn ) {
if ( this->f_firstConnectDecrementsOutstandingIO ) {
this->cacCtx.decrementOutstandingIO ();
}
}
bool v41Ok;
if ( this->piiu ) {
v41Ok = this->piiu->ca_v41_ok ();
@@ -263,7 +283,7 @@ void nciu::connect ( unsigned nativeType,
// resubscribe for monitors from this channel
this->piiu->connectAllIO ( *this );
this->connectNotify ();
this->notify ().connectNotify ( *this );
/*
* if less than v4.1 then the server will never
@@ -272,7 +292,16 @@ void nciu::connect ( unsigned nativeType,
* their call back here
*/
if ( ! v41Ok ) {
this->accessRightsNotify ( this->ar );
this->notify ().accessRightsNotify ( *this, this->ar );
}
}
void nciu::connectTimeoutNotify ()
{
if ( ! this->f_connectTimeOutSeen ) {
this->lock ();
this->f_connectTimeOutSeen = true;
this->unlock ();
}
}
@@ -309,8 +338,8 @@ void nciu::disconnect ( netiiu &newiiu )
/*
* look for events that have an event cancel in progress
*/
this->disconnectNotify ();
this->accessRightsNotify ( this->ar );
this->notify ().disconnectNotify ( *this );
this->notify ().accessRightsNotify ( *this, this->ar );
}
this->resetRetryCount ();
@@ -352,36 +381,6 @@ bool nciu::searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThisCh
return status;
}
void nciu::incrementOutstandingIO ()
{
this->cacCtx.incrementOutstandingIO ();
}
void nciu::decrementOutstandingIO ()
{
this->cacCtx.decrementOutstandingIO ();
}
void nciu::decrementOutstandingIO ( unsigned seqNumber )
{
this->cacCtx.decrementOutstandingIO ( seqNumber );
}
void nciu::lockOutstandingIO () const
{
this->cacCtx.lockOutstandingIO ();
}
void nciu::unlockOutstandingIO () const
{
this->cacCtx.unlockOutstandingIO ();
}
unsigned nciu::readSequence () const
{
return this->cacCtx.readSequenceOfOutstandingIO ();
}
void nciu::hostName ( char *pBuf, unsigned bufLength ) const
{
this->piiu->hostName ( pBuf, bufLength );
@@ -499,7 +498,8 @@ int nciu::createChannelRequest ()
}
int nciu::subscribe ( unsigned type, unsigned long nElem,
unsigned mask, cacNotify &notify )
unsigned mask, cacNotify &notify,
cacNotifyIO *&pNotifyIO )
{
netSubscription *pSubcr = new netSubscription ( *this,
type, nElem, mask, notify );
@@ -508,6 +508,9 @@ int nciu::subscribe ( unsigned type, unsigned long nElem,
if ( status != ECA_NORMAL ) {
pSubcr->destroy ();
}
else {
pNotifyIO = pSubcr;
}
return status;
}
else {
@@ -515,6 +518,27 @@ int nciu::subscribe ( unsigned type, unsigned long nElem,
}
}
void nciu::notifyStateChangeFirstConnectInCountOfOutstandingIO ()
{
this->lock ();
// test is performed via a callback so that locking is correct
if ( ! this->f_connectTimeOutSeen && ! this->f_previousConn ) {
if ( this->notify ().includeFirstConnectInCountOfOutstandingIO () ) {
if ( ! this->f_firstConnectDecrementsOutstandingIO ) {
this->cacCtx.incrementOutstandingIO ();
this->f_firstConnectDecrementsOutstandingIO = true;
}
}
else {
if ( this->f_firstConnectDecrementsOutstandingIO ) {
this->cacCtx.decrementOutstandingIO ();
this->f_firstConnectDecrementsOutstandingIO = false;
}
}
}
this->unlock ();
}
void nciu::show ( unsigned level ) const
{
if ( this->f_connected ) {