updated for new server API and use smart GDD ptr
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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::
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user