improved IIU shutdown seq for IO

This commit is contained in:
Jeff Hill
2001-01-25 02:14:59 +00:00
parent c50d84e50d
commit 1cfca09aa1
12 changed files with 104 additions and 95 deletions
-4
View File
@@ -26,7 +26,3 @@ cacNotifyIO::~cacNotifyIO ()
}
}
void cacNotifyIO::destroy ()
{
delete this;
}
+14 -13
View File
@@ -298,7 +298,6 @@ public:
bool identifierEquivelence ( unsigned idToMatch );
void * operator new ( size_t size );
void operator delete ( void *pCadaver, size_t size );
void unistallSubscription ( class netSubscription & );
void resetRetryCount ();
unsigned getRetrySeqNo () const;
void accessRightsStateChange ( const caar &arIn );
@@ -348,8 +347,9 @@ public:
virtual void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count ) = 0;
virtual class netSubscription * isSubscription ();
virtual void show ( unsigned level ) const;
virtual void uninstall () = 0;
ca_uint32_t getID () const;
nciu & channel ();
nciu & channel () const;
void destroy ();
protected:
nciu &chan;
@@ -362,15 +362,15 @@ public:
void show ( unsigned level ) const;
void * operator new ( size_t size );
void operator delete ( void *pCadaver, size_t size );
void destroy ();
unsigned long getCount ();
unsigned getType ();
unsigned getMask ();
unsigned long getCount () const;
unsigned getType () const;
unsigned getMask () const;
private:
unsigned long count;
unsigned type;
unsigned mask;
void uninstall ();
void completionNotify ();
void completionNotify ( unsigned type, unsigned long count, const void *pData );
void exceptionNotify ( int status, const char *pContext );
@@ -392,11 +392,11 @@ private:
unsigned long count;
void *pValue;
unsigned seqNumber;
void destroy ();
void completionNotify ();
void completionNotify ( unsigned type, unsigned long count, const void *pData );
void exceptionNotify ( int status, const char *pContext );
void exceptionNotify ( int status, const char *pContext, unsigned type, unsigned long count );
void uninstall ();
~netReadCopyIO (); // must be allocated from pool
static tsFreeList < class netReadCopyIO, 1024 > freeList;
};
@@ -408,7 +408,7 @@ public:
void * operator new ( size_t size );
void operator delete ( void *pCadaver, size_t size );
private:
void destroy ();
void uninstall ();
void completionNotify ();
void completionNotify ( unsigned type, unsigned long count, const void *pData );
void exceptionNotify ( int status, const char *pContext );
@@ -424,7 +424,7 @@ public:
void * operator new ( size_t size );
void operator delete ( void *pCadaver, size_t size );
private:
void destroy ();
void uninstall ();
void completionNotify ();
void completionNotify ( unsigned type, unsigned long count, const void *pData );
void exceptionNotify ( int status, const char *pContext );
@@ -488,19 +488,18 @@ public:
void show ( unsigned level ) const;
unsigned channelCount () const;
void disconnectAllChan ( netiiu & newiiu );
void destroyAllIO ( nciu &chan );
void connectTimeoutNotify ();
bool searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThisChannel );
void resetChannelRetryCounts ();
void attachChannel ( nciu &chan );
void detachChannel ( nciu &chan );
int installSubscription ( netSubscription &subscr );
void unistallSubscription ( netSubscription &subscr );
virtual void hostName (char *pBuf, unsigned bufLength) const;
virtual const char * pHostName () const; // deprecated - please do not use
virtual bool isVirtaulCircuit ( const char *pChannelName, const osiSockAddr &addr ) const;
virtual bool ca_v42_ok () const;
virtual bool ca_v41_ok () const;
virtual bool pushDatagramMsg ( const caHdr &hdr, const void *pExt, ca_uint16_t extsize);
virtual int writeRequest ( nciu &, unsigned type, unsigned nElem, const void *pValue);
virtual int writeNotifyRequest ( nciu &, cacNotify &, unsigned type, unsigned nElem, const void *pValue );
@@ -510,6 +509,8 @@ public:
virtual void connectAllIO ( nciu &chan );
virtual void disconnectAllIO ( nciu &chan );
virtual int clearChannelRequest ( nciu & );
virtual void uninstallIO ( baseNMIU & );
virtual void subscriptionCancelRequest ( netSubscription &subscr, bool userThread );
protected:
cac * pCAC () const;
@@ -521,7 +522,6 @@ private:
virtual void lastChannelDetachNotify ();
virtual int subscriptionRequest ( netSubscription &subscr, bool userThread );
virtual int subscriptionCancelRequest ( netSubscription &subscr, bool userThread );
};
class limboiiu : public netiiu {
@@ -831,9 +831,10 @@ private:
int status, const char *pContext, unsigned type, unsigned long count );
void connectAllIO ( nciu &chan );
void disconnectAllIO ( nciu &chan );
void uninstallIO ( baseNMIU & );
int subscriptionRequest ( netSubscription &subscr, bool userThread );
int subscriptionCancelRequest ( netSubscription &subscr, bool userThread );
void subscriptionCancelRequest ( netSubscription &subscr, bool userThread );
typedef void ( tcpiiu::*pProtoStubTCP ) ();
static const pProtoStubTCP tcpJumpTableCAC [];
+1 -1
View File
@@ -67,7 +67,7 @@ void nciu::destroy ()
{
// this occurs here so that it happens when
// a lock is not applied
this->piiu->disconnectAllIO ( *this );
this->piiu->destroyAllIO ( *this );
this->piiu->clearChannelRequest ( *this );
this->cacCtx.destroyNCIU ( *this );
}
-6
View File
@@ -127,9 +127,3 @@ inline netiiu * nciu::getPIIU ()
return this->piiu;
}
inline void nciu::unistallSubscription ( netSubscription &subscr )
{
this->piiu->unistallSubscription ( subscr );
}
+5
View File
@@ -29,6 +29,11 @@ netReadCopyIO::~netReadCopyIO ()
}
void netReadCopyIO::uninstall ()
{
this->chan.getPIIU ()->uninstallIO ( *this );
}
void netReadCopyIO::completionNotify ()
{
this->exceptionNotify ( ECA_INTERNAL, "get completion callback with no data?" );
-1
View File
@@ -28,5 +28,4 @@ inline void netReadCopyIO::operator delete ( void *pCadaver, size_t size )
netReadCopyIO::freeList.release ( pCadaver, size );
}
#endif // netReadCopyIO_ILh
+5 -9
View File
@@ -16,18 +16,14 @@
tsFreeList < class netReadNotifyIO, 1024 > netReadNotifyIO::freeList;
netReadNotifyIO::netReadNotifyIO ( nciu &chan, cacNotify &notifyIn ) :
cacNotifyIO ( notifyIn ), baseNMIU ( chan )
{
}
cacNotifyIO ( notifyIn ), baseNMIU ( chan ) {}
netReadNotifyIO::~netReadNotifyIO ()
{
// private NOOP forces pool allocation
}
// private NOOP forces pool allocation
netReadNotifyIO::~netReadNotifyIO () {}
void netReadNotifyIO::destroy ()
void netReadNotifyIO::uninstall ()
{
this->baseNMIU::destroy ();
this->chan.getPIIU ()->uninstallIO ( *this );
}
void netReadNotifyIO::completionNotify ()
+5 -3
View File
@@ -25,12 +25,14 @@ netSubscription::netSubscription ( nciu &chan, unsigned typeIn, unsigned long co
netSubscription::~netSubscription ()
{
this->chan.unistallSubscription ( *this );
// o netiiu lock must _not_ be applied when calling this
// o uninstall from channel and IIU occur in uninstall method
this->chan.getPIIU ()->subscriptionCancelRequest ( *this, true );
}
void netSubscription::destroy ()
void netSubscription::uninstall ()
{
delete this;
this->chan.getPIIU ()->uninstallIO ( *this );
}
class netSubscription * netSubscription::isSubscription ()
+3 -3
View File
@@ -28,7 +28,7 @@ inline void netSubscription::operator delete ( void *pCadaver, size_t size )
netSubscription::freeList.release ( pCadaver, size );
}
inline unsigned long netSubscription::getCount ()
inline unsigned long netSubscription::getCount () const
{
if ( this->chan.connected () ) {
unsigned long nativeCount = chan.nativeElementCount ();
@@ -47,12 +47,12 @@ inline unsigned long netSubscription::getCount ()
}
}
inline unsigned netSubscription::getType ()
inline unsigned netSubscription::getType () const
{
return this->type;
}
inline unsigned netSubscription::getMask ()
inline unsigned netSubscription::getMask () const
{
return this->mask;
}
+2 -2
View File
@@ -25,9 +25,9 @@ netWriteNotifyIO::~netWriteNotifyIO ()
// private NOOP forces pool allocation
}
void netWriteNotifyIO::destroy ()
void netWriteNotifyIO::uninstall ()
{
this->baseNMIU::destroy ();
this->chan.getPIIU ()->uninstallIO ( *this );
}
void netWriteNotifyIO::completionNotify ()
+32 -13
View File
@@ -95,6 +95,28 @@ void netiiu::disconnectAllChan ( netiiu & newiiu )
}
}
//
// netiiu::destroyAllIO ()
//
// care is taken not to not hold the lock while sending event
// subscription delete ( when the IO is deleted )
//
void netiiu::destroyAllIO ( nciu &chan )
{
baseNMIU *pIO;
while ( true ) {
{
epicsAutoMutex autoMutex ( this->mutex );
pIO = chan.tcpiiuPrivateListOfIO::eventq.first ();
if ( ! pIO ) {
break;
}
pIO->uninstall ();
}
pIO->destroy ();
}
}
void netiiu::connectTimeoutNotify ()
{
epicsAutoMutex autoMutex ( this->mutex );
@@ -133,7 +155,6 @@ bool netiiu::searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThis
status = false;
}
return status;
}
@@ -196,9 +217,8 @@ int netiiu::subscriptionRequest ( netSubscription &subscr, bool )
return ECA_NORMAL;
}
int netiiu::subscriptionCancelRequest ( netSubscription &, bool userThread )
void netiiu::subscriptionCancelRequest ( netSubscription &, bool userThread )
{
return ECA_NORMAL;
}
int netiiu::installSubscription ( netSubscription &subscr )
@@ -210,19 +230,12 @@ int netiiu::installSubscription ( netSubscription &subscr )
epicsAutoMutex autoMutex ( this->mutex );
subscr.channel ().tcpiiuPrivateListOfIO::eventq.add ( subscr );
}
return this->subscriptionRequest ( subscr, true );
}
void netiiu::unistallSubscription ( netSubscription &subscr )
{
// we must cancel the subscription first so that clean up
// is guaranteed to occur if a disconnect occurs beteen
// these two steps
this->subscriptionCancelRequest ( subscr, true );
{
int status = this->subscriptionRequest ( subscr, true );
if ( status != ECA_NORMAL ) {
epicsAutoMutex autoMutex ( this->mutex );
subscr.channel ().tcpiiuPrivateListOfIO::eventq.remove ( subscr );
}
return status;
}
void netiiu::hostName ( char *pBuf, unsigned bufLength ) const
@@ -244,4 +257,10 @@ void netiiu::disconnectAllIO ( nciu & )
void netiiu::connectAllIO ( nciu & )
{
}
void netiiu::uninstallIO ( baseNMIU &io )
{
epicsAutoMutex autoMutex ( this->mutex );
io.channel ().tcpiiuPrivateListOfIO::eventq.remove ( io );
}
+37 -40
View File
@@ -1758,7 +1758,7 @@ int tcpiiu::subscriptionRequest ( netSubscription &subscr, bool userThread )
return status;
}
int tcpiiu::subscriptionCancelRequest ( netSubscription &subscr, bool userThread )
void tcpiiu::subscriptionCancelRequest ( netSubscription &subscr, bool userThread )
{
if ( this->sendQue.flushThreshold ( 16u ) ) {
if ( userThread ) {
@@ -1771,29 +1771,17 @@ int tcpiiu::subscriptionCancelRequest ( netSubscription &subscr, bool userThread
epicsAutoMutex autoMutex ( this->mutex );
int status;
baseNMIU *pIO = this->ioTable.remove ( subscr );
if ( pIO == &subscr ) {
status = this->sendQue.reserveSpace ( 16u );
if ( status == ECA_NORMAL ) {
if ( ! subscr.channel ().verifyConnected ( *this ) ) {
status = ECA_DISCONNCHID;
}
else {
this->sendQue.pushUInt16 ( CA_PROTO_EVENT_CANCEL ); // cmd
this->sendQue.pushUInt16 ( 0u ); // postsize
this->sendQue.pushUInt16 ( static_cast < ca_uint16_t > ( subscr.getType () ) ); // dataType
this->sendQue.pushUInt16 ( static_cast < ca_uint16_t > ( subscr.getCount () ) ); // count
this->sendQue.pushUInt32 ( subscr.channel ().getSID () ); // cid
this->sendQue.pushUInt32 ( subscr.getID () ); // available
}
int status = this->sendQue.reserveSpace ( 16u );
if ( status == ECA_NORMAL ) {
if ( subscr.channel ().verifyConnected ( *this ) ) {
this->sendQue.pushUInt16 ( CA_PROTO_EVENT_CANCEL ); // cmd
this->sendQue.pushUInt16 ( 0u ); // postsize
this->sendQue.pushUInt16 ( static_cast < ca_uint16_t > ( subscr.getType () ) ); // dataType
this->sendQue.pushUInt16 ( static_cast < ca_uint16_t > ( subscr.getCount () ) ); // count
this->sendQue.pushUInt32 ( subscr.channel ().getSID () ); // cid
this->sendQue.pushUInt32 ( subscr.getID () ); // available
}
}
else {
status = ECA_BADMONID;
}
return status;
}
void tcpiiu::lastChannelDetachNotify ()
@@ -1964,22 +1952,22 @@ void tcpiiu::connectAllIO ( nciu &chan )
{
epicsAutoMutex autoMutex ( this->mutex );
if ( chan.verifyConnected ( *this ) ) {
tsDLIterBD < baseNMIU > iter =
tsDLIterBD < baseNMIU > pNetIO =
chan.tcpiiuPrivateListOfIO::eventq.first ();
while ( iter.valid () ) {
tsDLIterBD < baseNMIU > next = iter.itemAfter ();
class netSubscription *pSubscr = iter->isSubscription ();
while ( pNetIO.valid () ) {
tsDLIterBD < baseNMIU > next = pNetIO.itemAfter ();
class netSubscription *pSubscr = pNetIO->isSubscription ();
if ( pSubscr ) {
this->subscriptionRequest ( *pSubscr, false );
}
else {
// it shouldnt be here at this point - so uninstall it
this->ioTable.remove ( *iter );
chan.tcpiiuPrivateListOfIO::eventq.remove ( *iter );
iter->exceptionNotify ( ECA_DISCONN, this->pHostName () );
iter->destroy ();
this->ioTable.remove ( *pNetIO );
chan.tcpiiuPrivateListOfIO::eventq.remove ( *pNetIO );
pNetIO->exceptionNotify ( ECA_DISCONN, this->pHostName () );
pNetIO->destroy ();
}
iter = next;
pNetIO = next;
}
}
this->flush ();
@@ -1990,24 +1978,33 @@ void tcpiiu::disconnectAllIO ( nciu &chan )
{
epicsAutoMutex autoMutex ( this->mutex );
if ( chan.verifyConnected ( *this ) ) {
tsDLIterBD < baseNMIU > iter =
tsDLIterBD < baseNMIU > pNetIO =
chan.tcpiiuPrivateListOfIO::eventq.first ();
while ( iter.valid () ) {
tsDLIterBD < baseNMIU > next = iter.itemAfter ();
class netSubscription *pSubscr = iter->isSubscription ();
while ( pNetIO.valid () ) {
tsDLIterBD < baseNMIU > next = pNetIO.itemAfter ();
class netSubscription *pSubscr = pNetIO->isSubscription ();
this->ioTable.remove ( *pNetIO );
if ( pSubscr ) {
this->subscriptionCancelRequest ( *pSubscr, false );
}
else {
// no use after disconnected - so uninstall it
this->ioTable.remove ( *iter );
chan.tcpiiuPrivateListOfIO::eventq.remove ( *iter );
iter->exceptionNotify ( ECA_DISCONN, this->pHostName () );
iter->destroy ();
chan.tcpiiuPrivateListOfIO::eventq.remove ( *pNetIO );
pNetIO->exceptionNotify ( ECA_DISCONN, this->pHostName () );
pNetIO->destroy ();
}
iter = next;
pNetIO = next;
}
}
}
void tcpiiu::uninstallIO ( baseNMIU &io )
{
epicsAutoMutex autoMutex ( this->mutex );
if ( io.channel ().verifyConnected ( *this ) ) {
this->ioTable.remove ( io );
}
io.channel ().tcpiiuPrivateListOfIO::eventq.remove ( io );
}