diff --git a/src/cas/generic/casStrmClient.cc b/src/cas/generic/casStrmClient.cc index c1bd950bb..9100392ad 100644 --- a/src/cas/generic/casStrmClient.cc +++ b/src/cas/generic/casStrmClient.cc @@ -887,6 +887,32 @@ caStatus casStrmClient::monitorResponse ( return S_cas_success; } +/* + * casStrmClient::writeActionSendFailureStatus() + */ +caStatus casStrmClient :: + writeActionSendFailureStatus ( epicsGuard < casClientMutex > & guard, + const caHdrLargeArray & msg, ca_uint32_t cid, caStatus status ) +{ + caStatus ecaStatus; + if ( status == S_cas_noMemory ) { + ecaStatus = ECA_ALLOCMEM; + } + else if ( status == S_cas_noConvert ) { + ecaStatus = ECA_NOCONVERT; + } + else if ( status == S_cas_badType ) { + ecaStatus = ECA_BADTYPE; + } + else { + ecaStatus = ECA_PUTFAIL; + } + status = this->sendErrWithEpicsStatus ( guard, & msg, cid, + status, ecaStatus ); + return status; +} + + /* * casStrmClient::writeAction() */ @@ -907,6 +933,19 @@ caStatus casStrmClient::writeAction ( epicsGuard < casClientMutex > & guard ) status, "get request" ); } } + + // dont allow a request that completed with the service in the + // past, but was incomplete because no response was sent be + // executed twice with the service + if ( this->responseIsPending ) { + status = this->writeActionSendFailureStatus ( guard, *mp, + pChan->getCID(), this->pendingResponseStatus ); + if ( status == S_cas_success ) { + this->pendingResponseStatus = S_cas_success; + this->responseIsPending = false; + } + return status; + } // // verify write access @@ -937,24 +976,13 @@ caStatus casStrmClient::writeAction ( epicsGuard < casClientMutex > & guard ) pChan->getPVI().addItemToIOBLockedList ( *this ); } else { - caStatus ecaStatus; - if ( status == S_cas_noMemory ) { - ecaStatus = ECA_ALLOCMEM; - } - else if ( status == S_cas_noConvert ) { - ecaStatus = ECA_NOCONVERT; - } - else if ( status == S_cas_badType ) { - ecaStatus = ECA_BADTYPE; - } - else { - ecaStatus = ECA_PUTFAIL; - } - status = this->sendErrWithEpicsStatus ( guard, mp, pChan->getCID(), - status, ecaStatus ); - // - // I have assumed that the server tool has deleted the gdd here - // + int writeServiceStatus = status; + status = this->writeActionSendFailureStatus ( guard, *mp, + pChan->getCID(), writeServiceStatus ); + if ( status != S_cas_success ) { + this->pendingResponseStatus = writeServiceStatus; + this->responseIsPending = true; + } } // @@ -1037,8 +1065,8 @@ caStatus casStrmClient::writeNotifyAction ( } else { int writeNotifyServiceStatus = status; - status = this->writeNotifyResponse ( - guard, *pChan, *mp, status ); + status = this->writeNotifyResponse ( guard, *pChan, *mp, + writeNotifyServiceStatus ); if ( status != S_cas_success ) { this->pendingResponseStatus = writeNotifyServiceStatus; this->responseIsPending = true; diff --git a/src/cas/generic/casStrmClient.h b/src/cas/generic/casStrmClient.h index 72e1e8cbb..d0c987b4a 100644 --- a/src/cas/generic/casStrmClient.h +++ b/src/cas/generic/casStrmClient.h @@ -103,9 +103,11 @@ private: const caHdrLargeArray & msg, const caStatus ECA_XXXX ); caStatus writeNotifyResponseECA_XXX ( epicsGuard < casClientMutex > &, const caHdrLargeArray & msg, const caStatus status ); - caStatus sendErrWithEpicsStatus ( epicsGuard < casClientMutex > &, + caStatus sendErrWithEpicsStatus ( epicsGuard < casClientMutex > &, const caHdrLargeArray * pMsg, ca_uint32_t cid, caStatus epicsStatus, caStatus clientStatus ); + caStatus writeActionSendFailureStatus ( epicsGuard < casClientMutex > &, + const caHdrLargeArray &, ca_uint32_t cid, caStatus ); // // one function for each CA request type that has