From 233dc670a3ccfd936ed7886aa2e01bf7b68f0a0e Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Tue, 16 Jun 1998 02:32:30 +0000 Subject: [PATCH] use smart gdd ptr --- src/cas/generic/casMonEvent.cc | 16 +- src/cas/generic/casMonEventIL.h | 37 +---- src/cas/generic/casMonitor.cc | 247 +++++++++++++++---------------- src/cas/generic/casStrmClient.cc | 206 +++++++++++++------------- 4 files changed, 233 insertions(+), 273 deletions(-) diff --git a/src/cas/generic/casMonEvent.cc b/src/cas/generic/casMonEvent.cc index 2688efa9f..295460da6 100644 --- a/src/cas/generic/casMonEvent.cc +++ b/src/cas/generic/casMonEvent.cc @@ -29,6 +29,9 @@ * * History * $Log$ + * Revision 1.4 1997/04/10 19:34:11 jhill + * API changes + * * Revision 1.3 1996/11/02 00:54:16 jhill * many improvements * @@ -81,17 +84,8 @@ caStatus casMonEvent::cbFunc(casEventSys &eSys) // void casMonEvent::assign (casMonitor &monitor, gdd *pValueIn) { - int gddStatus; - if (this->pValue) { - gddStatus = this->pValue->unreference(); - assert (!gddStatus); - } - if (pValueIn) { - gddStatus = pValueIn->reference(); - assert (!gddStatus); - } - this->pValue = pValueIn; - this->id = monitor.casRes::getId(); + this->pValue = pValueIn; + this->id = monitor.casRes::getId(); } // diff --git a/src/cas/generic/casMonEventIL.h b/src/cas/generic/casMonEventIL.h index d4eff2cb3..e1eac89b9 100644 --- a/src/cas/generic/casMonEventIL.h +++ b/src/cas/generic/casMonEventIL.h @@ -29,6 +29,9 @@ * * History * $Log$ + * Revision 1.3 1997/04/10 19:34:11 jhill + * API changes + * * Revision 1.2 1996/11/02 00:54:17 jhill * many improvements * @@ -46,48 +49,27 @@ // casMonEvent::casMonEvent() // inline casMonEvent::casMonEvent () : - pValue(NULL), id(0u) {} + id(0u) {} // // casMonEvent::casMonEvent() // inline casMonEvent::casMonEvent (casMonitor &monitor, gdd &newValue) : pValue(&newValue), - id(monitor.casRes::getId()) -{ - int gddStatus; - gddStatus = this->pValue->reference(); - assert (!gddStatus); -} + id(monitor.casRes::getId()) {} // // casMonEvent::casMonEvent() // inline casMonEvent::casMonEvent (casMonEvent &initValue) : pValue(initValue.pValue), - id(initValue.id) -{ - int gddStatus; - if (this->pValue) { - gddStatus = this->pValue->reference(); - assert (!gddStatus); - } -} + id(initValue.id) {} // // casMonEvent::operator = () // inline void casMonEvent::operator = (class casMonEvent &monEventIn) { - int gddStatus; - if (this->pValue) { - gddStatus = this->pValue->unreference(); - assert (!gddStatus); - } - if (monEventIn.pValue) { - gddStatus = monEventIn.pValue->reference(); - assert (!gddStatus); - } this->pValue = monEventIn.pValue; this->id = monEventIn.id; } @@ -97,12 +79,7 @@ inline void casMonEvent::operator = (class casMonEvent &monEventIn) // inline void casMonEvent::clear() { - int gddStatus; - if (this->pValue) { - gddStatus = this->pValue->unreference(); - assert (!gddStatus); - this->pValue = NULL; - } + this->pValue = NULL; this->id = 0u; } diff --git a/src/cas/generic/casMonitor.cc b/src/cas/generic/casMonitor.cc index 0e70e0695..bd630bbce 100644 --- a/src/cas/generic/casMonitor.cc +++ b/src/cas/generic/casMonitor.cc @@ -29,6 +29,9 @@ * * History * $Log$ + * Revision 1.8 1997/05/05 04:50:11 jhill + * moved pLog = NULL down + * * Revision 1.7 1997/04/10 19:34:12 jhill * API changes * @@ -65,27 +68,27 @@ // casMonitor::casMonitor() // casMonitor::casMonitor(caResId clientIdIn, casChannelI &chan, - unsigned long nElemIn, unsigned dbrTypeIn, + unsigned long nElemIn, unsigned dbrTypeIn, const casEventMask &maskIn, osiMutex &mutexIn) : - nElem(nElemIn), - mutex(mutexIn), - ciu(chan), - mask(maskIn), - pModifiedValue(NULL), - clientId(clientIdIn), - dbrType(dbrTypeIn), - nPend(0u), - ovf(FALSE), - enabled(FALSE) + nElem(nElemIn), + mutex(mutexIn), + ciu(chan), + mask(maskIn), + pModifiedValue(NULL), + clientId(clientIdIn), + dbrType(dbrTypeIn), + nPend(0u), + ovf(FALSE), + enabled(FALSE) { - // - // If these are nill it is a programmer error - // - assert (&this->ciu); - - this->ciu.addMonitor(*this); - - this->enable(); + // + // If these are nill it is a programmer error + // + assert (&this->ciu); + + this->ciu.addMonitor(*this); + + this->enable(); } // @@ -93,25 +96,22 @@ casMonitor::casMonitor(caResId clientIdIn, casChannelI &chan, // casMonitor::~casMonitor() { - casCoreClient &client = this->ciu.getClient(); - - this->mutex.osiLock(); - + casCoreClient &client = this->ciu.getClient(); + + this->mutex.osiLock(); + this->disable(); - - // - // remove from the event system - // - if (this->ovf) { - client.removeFromEventQueue (this->overFlowEvent); - } - if (this->pModifiedValue) { - this->pModifiedValue->unreference(); - this->pModifiedValue = NULL; + + // + // remove from the event system + // + if (this->ovf) { + client.removeFromEventQueue (this->overFlowEvent); } - this->ciu.deleteMonitor(*this); - this->mutex.osiUnlock(); + this->ciu.deleteMonitor(*this); + + this->mutex.osiUnlock(); } // @@ -151,69 +151,63 @@ void casMonitor::disable() // void casMonitor::push(gdd &newValue) { - casCoreClient &client = this->ciu.getClient(); - casMonEvent *pLog; - char full; - - this->mutex.osiLock(); - + casCoreClient &client = this->ciu.getClient(); + casMonEvent *pLog; + char full; + + this->mutex.osiLock(); + // // get a new block if we havent exceeded quotas // - full = (this->nPend>=individualEventEntries) + full = (this->nPend>=individualEventEntries) || client.casEventSys::full(); - if (!full) { - pLog = new casMonEvent(*this, newValue); - if (pLog) { - this->nPend++; - } - } + if (!full) { + pLog = new casMonEvent(*this, newValue); + if (pLog) { + this->nPend++; + } + } else { pLog = NULL; } - - if (this->ovf) { - if (pLog) { - int gddStatus; - // - // swap values - // (ugly - but avoids purify ukn sym type problem) - // (better to create a temp event object) - // - gdd *pValue = this->overFlowEvent.getValue(); - assert(pValue); - gddStatus = pValue->reference(); - assert(!gddStatus); - this->overFlowEvent = *pLog; - pLog->assign(*this, pValue); - gddStatus = pValue->unreference(); - assert(!gddStatus); - client.insertEventQueue(*pLog, this->overFlowEvent); - } - else { - // - // replace the value with the current one - // - this->overFlowEvent.assign(*this, &newValue); - } - client.removeFromEventQueue(this->overFlowEvent); - pLog = &this->overFlowEvent; - } - else if (!pLog) { - /* - * no log block - * - * => use the over flow block in the event structure - */ - this->ovf = TRUE; - this->overFlowEvent.assign(*this, &newValue); - this->nPend++; - pLog = &this->overFlowEvent; - } - - client.addToEventQueue(*pLog); - - this->mutex.osiUnlock(); + + if (this->ovf) { + if (pLog) { + // + // swap values + // (ugly - but avoids purify ukn sym type problem) + // (better to create a temp event object) + // + smartGDDPointer pValue = this->overFlowEvent.getValue(); + assert (pValue!=NULL); + this->overFlowEvent = *pLog; + pLog->assign(*this, pValue); + client.insertEventQueue(*pLog, this->overFlowEvent); + } + else { + // + // replace the value with the current one + // + this->overFlowEvent.assign(*this, &newValue); + } + client.removeFromEventQueue(this->overFlowEvent); + pLog = &this->overFlowEvent; + } + else if (!pLog) { + // + // no log block + // => use the over flow block in the event structure + // + this->ovf = TRUE; + this->overFlowEvent.assign(*this, &newValue); + this->nPend++; + pLog = &this->overFlowEvent; + } + + client.addToEventQueue(*pLog); + + this->mutex.osiUnlock(); } // @@ -221,12 +215,12 @@ void casMonitor::push(gdd &newValue) // caStatus casMonitor::executeEvent(casMonEvent *pEV) { - caStatus status; - gdd *pVal; - - pVal = pEV->getValue (); - assert (pVal); - + caStatus status; + smartGDDPointer pVal; + + pVal = pEV->getValue (); + assert (pVal!=NULL); + this->mutex.osiLock(); if (this->ciu.getClient().getEventsOff()==aitFalse) { status = this->callBack (*pVal); @@ -237,15 +231,11 @@ caStatus casMonitor::executeEvent(casMonEvent *pEV) // (and send it later when flow control goes to // no flow control) // - if (this->pModifiedValue) { - this->pModifiedValue->unreference (); - } - pVal->reference (); this->pModifiedValue = pVal; status = S_cas_success; } this->mutex.osiUnlock(); - + // // if the event isnt accepted we will try // again later (and the event returns to the queue) @@ -253,26 +243,26 @@ caStatus casMonitor::executeEvent(casMonEvent *pEV) if (status) { return status; } - - // - // decrement the count of the number of events pending - // - this->nPend--; - - // - // delete event object if it isnt a cache entry - // saved in the call back object - // - if (pEV == &this->overFlowEvent) { - assert (this->ovf==TRUE); - this->ovf = FALSE; - pEV->clear(); - } - else { - delete pEV; - } - - return S_cas_success; + + // + // decrement the count of the number of events pending + // + this->nPend--; + + // + // delete event object if it isnt a cache entry + // saved in the call back object + // + if (pEV == &this->overFlowEvent) { + assert (this->ovf==TRUE); + this->ovf = FALSE; + pEV->clear(); + } + else { + delete pEV; + } + + return S_cas_success; } // @@ -294,12 +284,11 @@ void casMonitor::show(unsigned level) const // void casMonitor::postIfModified() { - this->mutex.osiLock(); - if (this->pModifiedValue) { - this->callBack (*this->pModifiedValue); - this->pModifiedValue->unreference (); - this->pModifiedValue = NULL; - } - this->mutex.osiUnlock(); + this->mutex.osiLock(); + if (this->pModifiedValue!=NULL) { + this->callBack (*this->pModifiedValue); + this->pModifiedValue = NULL; + } + this->mutex.osiUnlock(); } diff --git a/src/cas/generic/casStrmClient.cc b/src/cas/generic/casStrmClient.cc index d7ed18bb7..2962f7353 100644 --- a/src/cas/generic/casStrmClient.cc +++ b/src/cas/generic/casStrmClient.cc @@ -29,6 +29,9 @@ * * History * $Log$ + * Revision 1.22 1998/05/05 16:32:17 jhill + * cleaned up file format + * * Revision 1.21 1998/04/15 00:04:05 jhill * cosmetic * @@ -270,10 +273,10 @@ void casStrmClient::show (unsigned level) const */ caStatus casStrmClient::readAction () { - const caHdr *mp = this->ctx.getMsg(); - caStatus status; - casChannelI *pChan; - gdd *pDesc; + const caHdr *mp = this->ctx.getMsg(); + caStatus status; + casChannelI *pChan; + smartGDDPointer pDesc; status = this->verifyRequest (pChan); if (status != S_cas_validRequest) { @@ -297,7 +300,6 @@ caStatus casStrmClient::readAction () return this->sendErr(mp, status, "read access denied"); } - pDesc = NULL; status = this->read(pDesc); if (status==S_casApp_success) { status = this->readResponse(pChan, *mp, pDesc, S_cas_success); @@ -312,13 +314,6 @@ caStatus casStrmClient::readAction () status = this->sendErrWithEpicsStatus(mp, status, ECA_GETFAIL); } - if (pDesc) { - int gddStatus; - - gddStatus = pDesc->unreference(); - assert(gddStatus==0); - } - return status; } @@ -404,14 +399,15 @@ caStatus casStrmClient::readResponse (casChannelI *pChan, const caHdr &msg, // caStatus casStrmClient::readNotifyAction () { - const caHdr *mp = this->ctx.getMsg(); - int status; - casChannelI *pChan; - gdd *pDesc; + const caHdr *mp = this->ctx.getMsg(); + int status; + casChannelI *pChan; + smartGDDPointer pDesc; status = this->verifyRequest (pChan); if (status != S_cas_validRequest) { - return status; + return casStrmClient::readNotifyResponse(NULL, *mp, NULL, + S_cas_badRequest); } // @@ -421,7 +417,6 @@ caStatus casStrmClient::readNotifyAction () return this->readNotifyResponse(pChan, *mp, NULL, S_cas_noRead); } - pDesc = NULL; status = this->read(pDesc); if (status == S_casApp_success) { status = this->readNotifyResponse(pChan, *mp, pDesc, status); @@ -436,12 +431,6 @@ caStatus casStrmClient::readNotifyAction () status = this->readNotifyResponse(pChan, *mp, pDesc, status); } - if (pDesc) { - int gddStatus; - gddStatus = pDesc->unreference(); - assert(gddStatus==0); - } - return status; } @@ -492,7 +481,7 @@ caStatus casStrmClient::readNotifyResponse (casChannelI *pChan, if (mapDBRStatus<0) { pDesc->dump(); errPrintf (S_cas_badBounds, __FILE__, __LINE__, "- get notify with PV=%s type=%u count=%u", - pChan->getPVI()->getName(), msg.m_type, msg.m_count); + pChan->getPVI()->getName(), msg.m_type, msg.m_count); reply->m_cid = ECA_GETFAIL; } else { @@ -557,7 +546,7 @@ caStatus casStrmClient::monitorResponse (casChannelI *pChan, const caHdr &msg, gdd *pDesc, const caStatus completionStatus) { caStatus completionStatusCopy = completionStatus; - gdd *pDBRDD = NULL; + smartGDDPointer pDBRDD; caHdr *pReply; unsigned size; caStatus status; @@ -670,10 +659,6 @@ caStatus casStrmClient::monitorResponse (casChannelI *pChan, this->commitMsg (); - if (pDBRDD) { - pDBRDD->unreference(); - } - return S_cas_success; } @@ -768,7 +753,8 @@ caStatus casStrmClient::writeNotifyAction() status = this->verifyRequest (pChan); if (status != S_cas_validRequest) { - return status; + return casStrmClient::writeNotifyResponse(NULL, *mp, + S_cas_badRequest); } // @@ -1034,6 +1020,14 @@ caStatus casStrmClient::createChanResponse(const caHdr &hdr, const pvCreateRetur return this->channelCreateFailed(&hdr, S_casApp_pvNotFound); } + // + // attach the PV to this server + // + status = pPV->attachToServer (this->getCAS()); + if (status) { + return this->channelCreateFailed (&hdr, status); + } + // // NOTE: // We are allocating enough space for both the claim @@ -1237,7 +1231,7 @@ caStatus casStrmClient::eventAddAction () this->ctx.getData(); casClientMon *pMonitor; casChannelI *pciu; - gdd *pDD; + smartGDDPointer pDD; caStatus status; casEventMask mask; unsigned short caProtoMask; @@ -1276,7 +1270,6 @@ caStatus casStrmClient::eventAddAction () // to postpone asynchronous IO we can safely restart this // request later. // - pDD = NULL; status = this->read(pDD); // // always send immediate monitor response at event add @@ -1306,12 +1299,6 @@ caStatus casStrmClient::eventAddAction () status = this->monitorResponse (pciu, *mp, pDD, status); } - if (pDD) { - int gddStatus; - gddStatus = pDD->unreference(); - assert(gddStatus==0); - } - if (status==S_cas_success) { pMonitor = new casClientMon(*pciu, mp->m_available, @@ -1347,9 +1334,11 @@ caStatus casStrmClient::clearChannelAction () * Verify the channel */ pciu = this->resIdToChannel (mp->m_cid); - if (!pciu) { - logBadId (mp, dp); - return S_cas_internal; + if (pciu==NULL) { + logBadId (mp, dp, ECA_BADCHID); + } + else { + pciu->clientDestroy (); } /* @@ -1362,8 +1351,6 @@ caStatus casStrmClient::clearChannelAction () *reply = *mp; this->commitMsg (); - pciu->clientDestroy (); - return S_cas_success; } @@ -1373,48 +1360,58 @@ caStatus casStrmClient::clearChannelAction () // // casStrmClient::eventCancelAction() // -caStatus casStrmClient::eventCancelAction() +caStatus casStrmClient::eventCancelAction () { - const caHdr *mp = this->ctx.getMsg(); - void *dp = this->ctx.getData(); - casChannelI *pciu; + const caHdr *mp = this->ctx.getMsg (); + void *dp = this->ctx.getData (); + casChannelI *pciu; caHdr *reply; casMonitor *pMon; - int status; - - /* - * Verify the channel - */ - pciu = this->resIdToChannel(mp->m_cid); + int status; + + /* + * 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); - return S_cas_internal; - } - pMon = pciu->findMonitor(mp->m_available); - if (!pMon) { - logBadId(mp, dp); - return S_cas_internal; + logBadId (mp, dp, ECA_BADCHID); + return S_cas_success; } + /* + * verify the event (monitor) + */ + pMon = pciu->findMonitor (mp->m_available); + if (!pMon) { + logBadId (mp, dp, ECA_BADMONID); + return S_cas_success; + } + /* * allocate delete confirmed message */ - status = allocMsg(0u, &reply); + status = allocMsg (0u, &reply); if (status) { return status; } - + reply->m_cmmd = CA_PROTO_EVENT_ADD; reply->m_postsize = 0u; - reply->m_type = pMon->getType(); - reply->m_count = (unsigned short) pMon->getCount(); - reply->m_cid = pciu->getCID(); - reply->m_available = pMon->getClientId(); - - this->commitMsg(); - + reply->m_type = pMon->getType (); + reply->m_count = (unsigned short) pMon->getCount (); + reply->m_cid = pciu->getCID (); + reply->m_available = pMon->getClientId (); + + this->commitMsg (); + delete pMon; - + return S_cas_success; } @@ -1637,7 +1634,7 @@ caStatus casStrmClient::write() // caStatus casStrmClient::writeScalarData() { - gdd *pDD; + smartGDDPointer pDD; const caHdr *pHdr = this->ctx.getMsg(); gddStatus gddStat; caStatus status; @@ -1649,10 +1646,17 @@ caStatus casStrmClient::writeScalarData() } pDD = new gddScalar (gddAppType_value, type); - if (!pDD) { + if (pDD==NULL) { return S_cas_noMemory; } + // + // reference count is managed by smart pointer class + // from here down + // + gddStat = pDD->unreference(); + assert (!gddStat); + if (type==aitEnumFixedString) { aitFixedString *pFStr = (aitFixedString *) this->ctx.getData(); @@ -1662,7 +1666,6 @@ caStatus casStrmClient::writeScalarData() gddStat = pDD->genCopy(type, this->ctx.getData()); } if (gddStat) { - pDD->unreference(); return S_cas_badType; } @@ -1680,12 +1683,6 @@ caStatus casStrmClient::writeScalarData() // status = (*this->ctx.getPV())->write(this->ctx, *pDD); - // - // tell the DD that this code is finished with it - // - gddStat = pDD->unreference(); - assert(gddStat==0); - return status; } @@ -1695,7 +1692,7 @@ caStatus casStrmClient::writeScalarData() // caStatus casStrmClient::writeArrayData() { - gdd *pDD; + smartGDDPointer pDD; const caHdr *pHdr = this->ctx.getMsg(); gddDestructor *pDestructor; gddStatus gddStat; @@ -1714,17 +1711,21 @@ caStatus casStrmClient::writeArrayData() return S_cas_noMemory; } + // + // GDD ref count is managed by smart pointer class from here down + // + gddStat = pDD->unreference(); + assert (!gddStat); + size = dbr_size_n (pHdr->m_type, pHdr->m_count); pData = new char [size]; if (!pData) { - pDD->unreference(); return S_cas_noMemory; } pDestructor = new gddDestructor; if (!pDestructor) { delete [] pData; - pDD->unreference(); return S_cas_noMemory; } @@ -1754,12 +1755,6 @@ caStatus casStrmClient::writeArrayData() // status = (*this->ctx.getPV())->write(this->ctx, *pDD); - // - // tell the DD that this code is finished with it - // - gddStat = pDD->unreference(); - assert(gddStat==0); - return status; } @@ -1767,7 +1762,7 @@ caStatus casStrmClient::writeArrayData() // // casStrmClient::read() // -caStatus casStrmClient::read(gdd *&pDescRet) +caStatus casStrmClient::read(smartGDDPointer &pDescRet) { const caHdr *pHdr = this->ctx.getMsg(); caStatus status; @@ -1778,7 +1773,7 @@ caStatus casStrmClient::read(gdd *&pDescRet) return status; } - if (!pDescRet) { + if (pDescRet==NULL) { return S_cas_noMemory; } @@ -1820,7 +1815,6 @@ caStatus casStrmClient::read(gdd *&pDescRet) } if (status) { - pDescRet->unreference(); pDescRet = NULL; } @@ -1832,12 +1826,12 @@ caStatus casStrmClient::read(gdd *&pDescRet) // // createDBRDD () // -caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet) +caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, smartGDDPointer &pDescRet) { - aitUint32 valIndex; - aitUint32 gddStatus; - aitUint16 appType; - gdd *pVal; + aitUint32 valIndex; + aitUint32 gddStatus; + aitUint16 appType; + gdd *pVal; appType = gddDbrToAit[dbrType].app; @@ -1848,9 +1842,20 @@ caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet) if (!pDescRet) { return S_cas_noMemory; } + + // + // smart pointer class maintains the ref count from here down + // + gddStatus = pDescRet->unreference(); + assert (!gddStatus); if (pDescRet->isContainer()) { - gddContainer *pCont = (gddContainer *) pDescRet; + gdd *pGdd = pDescRet; + // + // this cast is ugly and dangerous + // (Jim should have used virtual functions in gdd) + // + gddContainer *pCont = (gddContainer *) pGdd; // // All DBR types have a value member @@ -1859,13 +1864,11 @@ caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet) gddApplicationTypeTable::app_table.mapAppToIndex (appType, gddAppType_value, valIndex); if (gddStatus) { - pDescRet->unreference(); pDescRet = NULL; return S_cas_internal; } pVal = pCont->getDD(valIndex); if (!pVal) { - pDescRet->unreference(); pDescRet = NULL; return S_cas_internal; } @@ -1884,7 +1887,6 @@ caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet) // => out of luck (cant modify bounds) // if (pDescRet->isManaged()) { - pDescRet->unreference(); pDescRet = NULL; return S_cas_internal; } @@ -1916,7 +1918,6 @@ caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet) pVal->setBound(dim, 0u, bound); } else { - pDescRet->unreference(); pDescRet = NULL; return S_cas_internal; } @@ -1928,7 +1929,6 @@ caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet) // // the GDD is container or isnt any of the normal types // - pDescRet->unreference(); pDescRet = NULL; return S_cas_internal; }