From 6aa6cdd6066421ccc65cd0d6328e388482a86aad Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Tue, 16 Jun 1998 02:37:37 +0000 Subject: [PATCH] updated for new server API and use smart GDD ptr --- src/cas/example/simple/Makefile.Host | 5 -- src/cas/example/simple/exPV.cc | 41 +++++-------- src/cas/example/simple/exScalarPV.cc | 87 ++++++++++++++-------------- src/cas/example/simple/exServer.cc | 16 ++++- src/cas/example/simple/exServer.h | 86 ++++++++++++++++++--------- src/cas/example/simple/exVectorPV.cc | 38 ++++++------ 6 files changed, 151 insertions(+), 122 deletions(-) diff --git a/src/cas/example/simple/Makefile.Host b/src/cas/example/simple/Makefile.Host index 317dc5645..8ceacb2aa 100644 --- a/src/cas/example/simple/Makefile.Host +++ b/src/cas/example/simple/Makefile.Host @@ -24,13 +24,8 @@ PROD := excas include $(TOP)/config/RULES.Host -pexcas: $(PROD_OBJS) $(PRODDEPLIBS) - $(PURIFY) $(PROD_LINKER) $(PROD_OBJS) $(LDLIBS) - clean:: @$(RM) excas - @$(RM) fexcas - @$(RM) pexcas @$(RM) -rf Templates.DB @$(RM) core diff --git a/src/cas/example/simple/exPV.cc b/src/cas/example/simple/exPV.cc index f77172b40..d0f5cdc0e 100644 --- a/src/cas/example/simple/exPV.cc +++ b/src/cas/example/simple/exPV.cc @@ -15,13 +15,11 @@ osiTime exPV::currentTime; // // exPV::exPV() // -exPV::exPV (caServer &casIn, pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) : - casPV(casIn), - pValue(NULL), - info(setup), - interest(aitFalse), - preCreate(preCreateFlag), - scanOn(scanOnIn) +exPV::exPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) : + info (setup), + interest (aitFalse), + preCreate (preCreateFlag), + scanOn (scanOnIn) { // // no dataless PV allowed @@ -48,15 +46,12 @@ exPV::~exPV() delete this->pScanTimer; this->pScanTimer = NULL; } - if (this->pValue) { - this->pValue->unreference(); - this->pValue = NULL; - } - this->info.destroyPV(); + this->info.unlinkPV(); } // // exPV::destroy() +// // this is replaced by a noop since we are // pre-creating most of the PVs during init in this simple server // @@ -81,17 +76,13 @@ caStatus exPV::update(gdd &valueIn) struct timespec t; caStatus cas; - if (!pCAS) { - return S_casApp_noSupport; - } - # if DEBUG printf("Setting %s too:\n", this->info.getName().string()); valueIn.dump(); # endif cas = this->updateValue (valueIn); - if (cas || !this->pValue) { + if (cas || this->pValue==NULL) { return cas; } @@ -107,9 +98,9 @@ caStatus exPV::update(gdd &valueIn) // // post a value change event // - if (this->interest==aitTrue) { - casEventMask select(pCAS->valueEventMask|pCAS->logEventMask); - this->postEvent (select, *this->pValue); + if (this->interest==aitTrue && pCAS!=NULL) { + casEventMask select(pCAS->valueEventMask|pCAS->logEventMask); + this->postEvent (select, *this->pValue); } return S_casApp_success; @@ -218,7 +209,7 @@ void exPV::interestDelete() void exPV::show(unsigned level) const { if (level>1u) { - if (this->pValue) { + if (this->pValue!=NULL) { printf("exPV: cond=%d\n", this->pValue->getStat()); printf("exPV: sevr=%d\n", this->pValue->getSevr()); printf("exPV: value=%f\n", (double) *this->pValue); @@ -262,7 +253,7 @@ void exPV::initFT() // caStatus exPV::getStatus(gdd &value) { - if (this->pValue) { + if (this->pValue!=NULL) { value.put(this->pValue->getStat()); } else { @@ -276,7 +267,7 @@ caStatus exPV::getStatus(gdd &value) // caStatus exPV::getSeverity(gdd &value) { - if (this->pValue) { + if (this->pValue!=NULL) { value.put(this->pValue->getSevr()); } else { @@ -291,7 +282,7 @@ caStatus exPV::getSeverity(gdd &value) inline aitTimeStamp exPV::getTS() { aitTimeStamp ts; - if (this->pValue) { + if (this->pValue!=NULL) { this->pValue->getTimeStamp(&ts); } else { @@ -401,7 +392,7 @@ caStatus exPV::getValue(gdd &value) { caStatus status; - if (this->pValue) { + if (this->pValue!=NULL) { gddStatus gdds; gdds = gddApplicationTypeTable:: diff --git a/src/cas/example/simple/exScalarPV.cc b/src/cas/example/simple/exScalarPV.cc index 962f393d7..c33f0569a 100644 --- a/src/cas/example/simple/exScalarPV.cc +++ b/src/cas/example/simple/exScalarPV.cc @@ -27,44 +27,49 @@ // void exScalarPV::scan() { - caStatus status; - double radians; - gdd *pDD; - float newValue; - float limit; + caStatus status; + double radians; + smartGDDPointer pDD; + float newValue; + float limit; + int gddStatus; - // - // update current time (so we are not required to do - // this every time that we write the PV which impacts - // throughput under sunos4 because gettimeofday() is - // slow) - // - this->currentTime = osiTime::getCurrent(); - - pDD = new gddScalar (gddAppType_value, aitEnumFloat32); - if (!pDD) { - return; - } - - radians = (rand () * 2.0 * myPI)/RAND_MAX; - if (this->pValue) { - this->pValue->getConvert(newValue); - } - else { - newValue = 0.0f; - } - newValue += (float) (sin (radians) / 10.0); - limit = (float) this->info.getHopr(); - newValue = tsMin (newValue, limit); - limit = (float) this->info.getLopr(); - newValue = tsMax (newValue, limit); - *pDD = newValue; - status = this->update (*pDD); - if (status) { - errMessage (status, "scan update failed\n"); - } - - pDD->unreference(); + // + // update current time (so we are not required to do + // this every time that we write the PV which impacts + // throughput under sunos4 because gettimeofday() is + // slow) + // + this->currentTime = osiTime::getCurrent(); + + pDD = new gddScalar (gddAppType_value, aitEnumFloat32); + if (pDD==NULL) { + return; + } + + // + // smart pointer class manages reference count after this point + // + gddStatus = pDD->unreference(); + assert (!gddStatus); + + radians = (rand () * 2.0 * myPI)/RAND_MAX; + if (this->pValue!=NULL) { + this->pValue->getConvert(newValue); + } + else { + newValue = 0.0f; + } + newValue += (float) (sin (radians) / 10.0); + limit = (float) this->info.getHopr(); + newValue = tsMin (newValue, limit); + limit = (float) this->info.getLopr(); + newValue = tsMax (newValue, limit); + *pDD = newValue; + status = this->update (*pDD); + if (status!=S_casApp_success) { + errMessage (status, "scalar scan update failed\n"); + } } // @@ -89,14 +94,6 @@ caStatus exScalarPV::updateValue (gdd &valueIn) return S_casApp_outOfBounds; } - // - // release old value and replace it - // with the new one - // - if (this->pValue) { - this->pValue->unreference(); - } - valueIn.reference(); this->pValue = &valueIn; return S_casApp_success; diff --git a/src/cas/example/simple/exServer.cc b/src/cas/example/simple/exServer.cc index abe7ed544..2a7ea257a 100644 --- a/src/cas/example/simple/exServer.cc +++ b/src/cas/example/simple/exServer.cc @@ -115,6 +115,16 @@ exServer::exServer(const char * const pvPrefix, unsigned aliasCount, aitBool sca // exServer::~exServer() { + pvInfo *pPVI; + pvInfo *pPVAfter = + &exServer::pvList[NELEMENTS(exServer::pvList)]; + + // + // delete all pre-created PVs (eliminate bounds-checker warnings) + // + for (pPVI = exServer::pvList; pPVI < pPVAfter; pPVI++) { + pPVI->deletePV (); + } } // @@ -258,10 +268,10 @@ exPV *pvInfo::createPV (exServer &exCAS, aitBool preCreateFlag, aitBool scanOn) if (this->elementCount==1u) { switch (this->ioType){ case excasIoSync: - pNewPV = new exScalarPV (exCAS, *this, preCreateFlag, scanOn); + pNewPV = new exScalarPV (*this, preCreateFlag, scanOn); break; case excasIoAsync: - pNewPV = new exAsyncPV (exCAS, *this, preCreateFlag, scanOn); + pNewPV = new exAsyncPV (*this, preCreateFlag, scanOn); break; default: pNewPV = NULL; @@ -270,7 +280,7 @@ exPV *pvInfo::createPV (exServer &exCAS, aitBool preCreateFlag, aitBool scanOn) } else { if (this->ioType==excasIoSync) { - pNewPV = new exVectorPV (exCAS, *this, preCreateFlag, scanOn); + pNewPV = new exVectorPV (*this, preCreateFlag, scanOn); } else { pNewPV = NULL; diff --git a/src/cas/example/simple/exServer.h b/src/cas/example/simple/exServer.h index 766d9658e..e5b6cc6d7 100644 --- a/src/cas/example/simple/exServer.h +++ b/src/cas/example/simple/exServer.h @@ -8,9 +8,9 @@ // // casPV // | -// exPV------------- -// | | -// exScalarPV exVectorPV +// exPV----------- +// | | +// exScalarPV exVectorPV // | // exAsyncPV // @@ -61,6 +61,8 @@ public: { } + ~pvInfo (); + // // for use when MSVC++ will not build a default copy constructor // for this class @@ -80,8 +82,11 @@ public: const excasIoType getIOType () const { return this->ioType; } const unsigned getElementCount() const { return this->elementCount; } - void destroyPV() { this->pPV=NULL; } + void unlinkPV() { this->pPV=NULL; } + exPV *createPV (exServer &exCAS, aitBool preCreateFlag, aitBool scanOn); + void deletePV (); + private: const double scanPeriod; const char *pName; @@ -138,6 +143,8 @@ private: exPV &pv; }; + + // // exPV // @@ -145,7 +152,7 @@ class exPV : public casPV, public tsSLNode { // allow the exScanTimer destructor to set dangling pScanTimer pointer to NULL friend exScanTimer::~exScanTimer(); public: - exPV (caServer &cas, pvInfo &setup, aitBool preCreateFlag, aitBool scanOn); + exPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOn); virtual ~exPV(); void show(unsigned level) const; @@ -230,7 +237,7 @@ public: static void initFT(); protected: - gdd *pValue; + smartGDDPointer pValue; exScanTimer *pScanTimer; pvInfo & info; aitBool interest; @@ -267,9 +274,8 @@ private: // class exScalarPV : public exPV { public: - exScalarPV (caServer &cas, - pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) : - exPV (cas, setup, preCreateFlag, scanOnIn) {} + exScalarPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) : + exPV (setup, preCreateFlag, scanOnIn) {} void scan(); private: caStatus updateValue (gdd &value); @@ -280,9 +286,8 @@ private: // class exVectorPV : public exPV { public: - exVectorPV (caServer &cas, pvInfo &setup, - aitBool preCreateFlag, aitBool scanOnIn) : - exPV (cas, setup, preCreateFlag, scanOnIn) {} + exVectorPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) : + exPV (setup, preCreateFlag, scanOnIn) {} void scan(); unsigned maxDimension() const; @@ -299,9 +304,10 @@ class exServer : public caServer { public: exServer(const char * const pvPrefix, unsigned aliasCount, aitBool scanOn); ~exServer(); - void show (unsigned level) const; - pvExistReturn pvExistTest (const casCtx&, const char *pPVName); - pvCreateReturn createPV (const casCtx &ctx, const char *pPVName); + + void show (unsigned level) const; + pvExistReturn pvExistTest (const casCtx&, const char *pPVName); + pvCreateReturn createPV (const casCtx &ctx, const char *pPVName); void installAliasName(pvInfo &info, const char *pAliasName); inline void removeAliasName(pvEntry &entry); @@ -344,9 +350,8 @@ public: // // exAsyncPV() // - exAsyncPV (caServer &cas, pvInfo &setup, - aitBool preCreateFlag, aitBool scanOnIn) : - exScalarPV (cas, setup, preCreateFlag, scanOnIn), + exAsyncPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) : + exScalarPV (setup, preCreateFlag, scanOnIn), simultAsychIOCount(0u) {} // @@ -417,7 +422,7 @@ private: // class exOSITimer : public osiTimer { public: - exOSITimer(double delay) : osiTimer(osiTime(delay)) {} + exOSITimer (double delay) : osiTimer(osiTime(delay)) {} // // this is a noop that postpones the timer expiration @@ -436,16 +441,20 @@ public: // // exAsyncWriteIO() // - exAsyncWriteIO(const casCtx &ctxIn, exAsyncPV &pvIn, gdd &valueIn) : + exAsyncWriteIO (const casCtx &ctxIn, exAsyncPV &pvIn, gdd &valueIn) : casAsyncWriteIO(ctxIn), exOSITimer(0.1), pv(pvIn), value(valueIn) { - this->value.reference(); + int gddStatus; + gddStatus = this->value.reference(); + assert (!gddStatus); } ~exAsyncWriteIO() { + int gddStatus; this->pv.removeIO(); - this->value.unreference(); + gddStatus = this->value.unreference(); + assert (!gddStatus); } // @@ -473,13 +482,17 @@ public: exAsyncReadIO(const casCtx &ctxIn, exAsyncPV &pvIn, gdd &protoIn) : casAsyncReadIO(ctxIn), exOSITimer(0.1), pv(pvIn), proto(protoIn) { - this->proto.reference(); + int gddStatus; + gddStatus = this->proto.reference(); + assert (!gddStatus); } ~exAsyncReadIO() { + int gddStatus; this->pv.removeIO(); - this->proto.unreference(); + gddStatus = this->proto.unreference(); + assert (!gddStatus); } // @@ -576,7 +589,7 @@ inline void exServer::removeAliasName(pvEntry &entry) // inline pvEntry::~pvEntry() { - this->cas.removeAliasName(*this); + this->cas.removeAliasName(*this); } // @@ -585,8 +598,27 @@ inline pvEntry::~pvEntry() inline void pvEntry::destroy () { // - // always created with new + // always created with new (in this example) // delete this; } - + +inline pvInfo::~pvInfo () +{ + // + // dont leak pre created PVs when we exit + // + if (this->pPV!=NULL) { + // + // always created with new (in this example) + // + delete this->pPV; + } +} + +inline void pvInfo::deletePV () +{ + if (this->pPV!=NULL) { + delete this->pPV; + } +} diff --git a/src/cas/example/simple/exVectorPV.cc b/src/cas/example/simple/exVectorPV.cc index 6123e2317..b50bb6f4a 100644 --- a/src/cas/example/simple/exVectorPV.cc +++ b/src/cas/example/simple/exVectorPV.cc @@ -50,11 +50,12 @@ void exVectorPV::scan() { caStatus status; double radians; - gdd *pDD; + smartGDDPointer pDD; aitFloat32 *pF, *pFE, *pCF; float newValue; float limit; exVecDestructor *pDest; + int gddStatus; // // update current time (so we are not required to do @@ -70,19 +71,23 @@ void exVectorPV::scan() return; } + // + // smart pointer class manages reference count after this point + // + gddStatus = pDD->unreference(); + assert (!gddStatus); + // // allocate array buffer // pF = new aitFloat32 [this->info.getElementCount()]; if (!pF) { - pDD->unreference(); return; } pDest = new exVecDestructor; if (!pDest) { delete [] pF; - pDD->unreference(); return; } @@ -97,7 +102,7 @@ void exVectorPV::scan() // current value // pCF=NULL; - if (this->pValue) { + if (this->pValue!=NULL) { if (this->pValue->dimension()==1u) { const gddBounds *pB = this->pValue->getBounds(); if (pB[0u].size()==this->info.getElementCount()) { @@ -124,11 +129,9 @@ void exVectorPV::scan() } status = this->update (*pDD); - if (status) { - errMessage (status, "scan update failed\n"); + if (status!=S_casApp_success) { + errMessage (status, "vector scan update failed\n"); } - - pDD->unreference(); } // @@ -153,7 +156,7 @@ caStatus exVectorPV::updateValue(gdd &valueIn) // enum {replace, dontReplace} replFlag = dontReplace; gddStatus gdds; - gdd *pNewValue; + smartGDDPointer pNewValue; // // Check bounds of incoming request @@ -189,11 +192,11 @@ caStatus exVectorPV::updateValue(gdd &valueIn) // // replacing all elements is efficient // - valueIn.reference(); pNewValue = &valueIn; } else { aitFloat32 *pF, *pFE; + int gddStatus; // // Create a new array data descriptor @@ -206,14 +209,20 @@ caStatus exVectorPV::updateValue(gdd &valueIn) return S_casApp_noMemory; } + // + // smart pointer class takes care of the reference count + // from here down + // + gddStatus = pNewValue->unreference(); + assert (!gddStatus); + // // copy over the old values if they exist // (or initialize all elements to zero) // - if (this->pValue) { + if (this->pValue!=NULL) { gdds = pNewValue->copy(this->pValue); if (gdds) { - pNewValue->unreference(); return S_cas_noConvert; } } @@ -223,7 +232,6 @@ caStatus exVectorPV::updateValue(gdd &valueIn) // pF = new aitFloat32 [this->info.getElementCount()]; if (!pF) { - pNewValue->unreference(); return S_casApp_noMemory; } @@ -243,14 +251,10 @@ caStatus exVectorPV::updateValue(gdd &valueIn) // gdds = pNewValue->put(&valueIn); if (gdds) { - pNewValue->unreference(); return S_cas_noConvert; } } - if (this->pValue) { - this->pValue->unreference(); - } this->pValue = pNewValue; return S_casApp_success;