use smart gdd ptr

This commit is contained in:
Jeff Hill
1998-06-16 02:32:30 +00:00
parent 78fc9f07f0
commit 233dc670a3
4 changed files with 233 additions and 273 deletions

View File

@@ -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();
}
//

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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;
}