improved IIU shutdown seq for IO
This commit is contained in:
@@ -26,7 +26,3 @@ cacNotifyIO::~cacNotifyIO ()
|
||||
}
|
||||
}
|
||||
|
||||
void cacNotifyIO::destroy ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
+14
-13
@@ -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
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -127,9 +127,3 @@ inline netiiu * nciu::getPIIU ()
|
||||
return this->piiu;
|
||||
}
|
||||
|
||||
inline void nciu::unistallSubscription ( netSubscription &subscr )
|
||||
{
|
||||
this->piiu->unistallSubscription ( subscr );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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?" );
|
||||
|
||||
@@ -28,5 +28,4 @@ inline void netReadCopyIO::operator delete ( void *pCadaver, size_t size )
|
||||
netReadCopyIO::freeList.release ( pCadaver, size );
|
||||
}
|
||||
|
||||
|
||||
#endif // netReadCopyIO_ILh
|
||||
|
||||
@@ -16,18 +16,14 @@
|
||||
tsFreeList < class netReadNotifyIO, 1024 > netReadNotifyIO::freeList;
|
||||
|
||||
netReadNotifyIO::netReadNotifyIO ( nciu &chan, cacNotify ¬ifyIn ) :
|
||||
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 ()
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user