o block if unable to get buffer space for the exception message

o subtle changes related to properly dealing with situations where
both the server tool and the client tool delete the same PV simultaneously
This commit is contained in:
Jeff Hill
1998-09-24 20:40:07 +00:00
parent 608228b328
commit 857a19ddef

View File

@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.24 1998/07/08 15:38:07 jhill
* fixed lost monitors during flow control problem
*
* Revision 1.23 1998/06/16 02:32:30 jhill
* use smart gdd ptr
*
@@ -831,6 +834,7 @@ caStatus casStrmClient::hostNameAction()
char *pName = (char *) this->ctx.getData();
unsigned size;
char *pMalloc;
caStatus status;
size = strlen(pName)+1u;
/*
@@ -838,7 +842,10 @@ caStatus casStrmClient::hostNameAction()
*/
pMalloc = new char [size];
if(!pMalloc){
this->sendErr(mp, ECA_ALLOCMEM, pName);
status = this->sendErr(mp, ECA_ALLOCMEM, pName);
if (status) {
return status;
}
return S_cas_internal;
}
strncpy(
@@ -876,6 +883,7 @@ caStatus casStrmClient::clientNameAction()
char *pName = (char *) this->ctx.getData();
unsigned size;
char *pMalloc;
caStatus status;
size = strlen(pName)+1;
@@ -884,7 +892,10 @@ caStatus casStrmClient::clientNameAction()
*/
pMalloc = new char [size];
if(!pMalloc){
this->sendErr(mp, ECA_ALLOCMEM, pName);
status = this->sendErr(mp, ECA_ALLOCMEM, pName);
if (status) {
return status;
}
return S_cas_internal;
}
strncpy(
@@ -942,8 +953,11 @@ caStatus casStrmClient::claimChannelAction()
// new API was added to the server (they must
// now use clients at EPICS 3.12 or higher)
//
this->sendErr(mp, ECA_DEFUNCT,
status = this->sendErr(mp, ECA_DEFUNCT,
"R3.11 connect sequence from old client was ignored");
if (status) {
return status;
}
return S_cas_badProtocol; // disconnect client
}
@@ -1123,8 +1137,8 @@ caStatus casStrmClient::channelCreateFailed(
const caHdr *mp,
caStatus createStatus)
{
caStatus status;
caHdr *reply;
caStatus status;
caHdr *reply;
if (createStatus == S_casApp_asyncCompletion) {
errMessage(S_cas_badParameter,
@@ -1148,7 +1162,10 @@ caStatus createStatus)
createStatus = S_cas_success;
}
else {
this->sendErrWithEpicsStatus(mp, createStatus, ECA_ALLOCMEM);
status = this->sendErrWithEpicsStatus(mp, createStatus, ECA_ALLOCMEM);
if (status) {
return status;
}
}
return createStatus;
@@ -1248,8 +1265,7 @@ caStatus casStrmClient::eventAddAction ()
if (mask.noEventsSelected()) {
char errStr[40];
sprintf(errStr, "event add req with mask=0X%X\n", caProtoMask);
this->sendErr(mp, ECA_BADMASK, errStr);
return S_cas_success;
return this->sendErr(mp, ECA_BADMASK, errStr);
}
//
@@ -1292,13 +1308,15 @@ caStatus casStrmClient::eventAddAction ()
pMonitor = new casClientMon(*pciu, mp->m_available,
mp->m_count, mp->m_type, mask, *this);
if (!pMonitor) {
this->sendErr(mp, ECA_ALLOCMEM, NULL);
//
// If we cant allocate space for a monitor then
// delete (disconnect) the channel
//
(*pciu)->destroy();
status = S_cas_success;
status = this->sendErr(mp, ECA_ALLOCMEM, NULL);
if (status==S_cas_success) {
//
// If we cant allocate space for a monitor then
// delete (disconnect) the channel
//
(*pciu)->destroy();
}
return status;
}
}
@@ -1323,10 +1341,25 @@ caStatus casStrmClient::clearChannelAction ()
*/
pciu = this->resIdToChannel (mp->m_cid);
if (pciu==NULL) {
logBadId (mp, dp, ECA_BADCHID);
}
else {
pciu->clientDestroy ();
/*
* it is possible that the channel delete arrives just
* after the server tool has deleted the PV so we will
* not disconnect the client in this case. Nevertheless,
* we send a warning message in case either the client
* or server has become corrupted
*
* return early here if we are unable to send the warning
* so that send block conditions will be handled
*/
status = logBadId (mp, dp, ECA_BADCHID, mp->m_cid);
if (status) {
return status;
}
//
// after sending the warning then go ahead and send the
// delete confirm message even if the channel couldnt be
// located so that the client can finish cleaning up
//
}
/*
@@ -1336,6 +1369,15 @@ caStatus casStrmClient::clearChannelAction ()
if (status) {
return status;
}
//
// only execute the request after we have allocated
// space for the response
//
if (pciu) {
pciu->clientDestroy ();
}
*reply = *mp;
this->commitMsg ();
@@ -1359,17 +1401,17 @@ caStatus casStrmClient::eventCancelAction ()
/*
* Verify the channel
*
* if the monitor delete arrives just after the server tool
* has deleted the PV then the client will deallocate the
* monitor structure when it receives the PV disconnect message.
*
* otherwise the client or server ha become corrupted
*/
pciu = this->resIdToChannel (mp->m_cid);
if (!pciu) {
logBadId (mp, dp, ECA_BADCHID);
return S_cas_success;
/*
* it is possible that the event delete arrives just
* after the server tool has deleted the PV. In this
* rare situation we are unable to look up the client's
* resource id for the return message and so we must force
* the client to reconnect.
*/
return logBadId (mp, dp, ECA_BADCHID, mp->m_cid);
}
/*
@@ -1377,10 +1419,12 @@ caStatus casStrmClient::eventCancelAction ()
*/
pMon = pciu->findMonitor (mp->m_available);
if (!pMon) {
logBadId (mp, dp, ECA_BADMONID);
return S_cas_success;
//
// this indicates client or server library corruption
//
return logBadId (mp, dp, ECA_BADMONID, mp->m_cid);
}
/*
* allocate delete confirmed message
*/
@@ -1430,8 +1474,7 @@ caStatus casStrmClient::noReadAccessEvent(casClientMon *pMon)
status = this->allocMsg(size, &reply);
if (status) {
if(status == S_cas_hugeRequest){
status = this->sendErr(&falseReply, ECA_TOLARGE, NULL);
return status;
return this->sendErr(&falseReply, ECA_TOLARGE, NULL);
}
return status;
}