updated for new server API and use smart GDD ptr

This commit is contained in:
Jeff Hill
1998-06-16 02:37:37 +00:00
parent a9b8a161f4
commit 6aa6cdd606
6 changed files with 151 additions and 122 deletions

View File

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

View File

@@ -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::

View File

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

View File

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

View File

@@ -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<exPV> {
// 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;
}
}

View File

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