From d7ae0fbce64dae032d5765deb00f3e67a3aa6998 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Tue, 14 Jul 2009 22:39:41 +0000 Subject: [PATCH] made lib more robust if server sends duplicate connect channel response --- src/ca/cac.cpp | 13 ++++++++++--- src/ca/tcpiiu.cpp | 6 +++++- src/ca/virtualCircuit.h | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index b34d394c7..4205fc1f3 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -1046,9 +1046,16 @@ bool cac::createChannelRespAction ( else { sidTmp = pChan->getSID (guard); } - iiu.connectNotify ( guard, *pChan ); - pChan->connect ( hdr.m_dataType, hdr.m_count, sidTmp, - mgr.cbGuard, guard ); + bool wasExpected = iiu.connectNotify ( guard, *pChan ); + if ( wasExpected ) { + pChan->connect ( hdr.m_dataType, hdr.m_count, sidTmp, + mgr.cbGuard, guard ); + } + else { + errlogPrintf ( + "CA Client Library: Ignored duplicate create channel " + "response from CA server?\n" ); + } } else if ( iiu.ca_v44_ok ( guard ) ) { // this indicates a claim response for a resource that does diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp index 283efb1b4..2a0153888 100644 --- a/src/ca/tcpiiu.cpp +++ b/src/ca/tcpiiu.cpp @@ -1916,24 +1916,28 @@ void tcpiiu::nameResolutionMsgEndNotify () } } -void tcpiiu::connectNotify ( +bool tcpiiu :: connectNotify ( epicsGuard < epicsMutex > & guard, nciu & chan ) { guard.assertIdenticalMutex ( this->mutex ); + bool wasExpected = false; // this improves robustness in the face of a server sending // protocol that does not match its declared protocol revision if ( chan.channelNode::listMember == channelNode::cs_createRespPend ) { this->createRespPend.remove ( chan ); this->subscripReqPend.add ( chan ); chan.channelNode::listMember = channelNode::cs_subscripReqPend; + wasExpected = true; } else if ( chan.channelNode::listMember == channelNode::cs_v42ConnCallbackPend ) { this->v42ConnCallbackPend.remove ( chan ); this->subscripReqPend.add ( chan ); chan.channelNode::listMember = channelNode::cs_subscripReqPend; + wasExpected = true; } // the TCP send thread is awakened by its receive thread whenever the receive thread // is about to block if this->subscripReqPend has items in it + return wasExpected; } void tcpiiu::uninstallChan ( diff --git a/src/ca/virtualCircuit.h b/src/ca/virtualCircuit.h index b103c4a0c..0441e89e4 100644 --- a/src/ca/virtualCircuit.h +++ b/src/ca/virtualCircuit.h @@ -173,7 +173,7 @@ public: unsigned sidIn, ca_uint16_t typeIn, arrayElementCount countIn ); void uninstallChan ( epicsGuard < epicsMutex > & guard, nciu & chan ); - void connectNotify ( + bool connectNotify ( epicsGuard < epicsMutex > &, nciu & chan ); void nameResolutionMsgEndNotify ();