loop safe wrapper for dbGet added

This commit is contained in:
2024-11-29 13:07:30 +01:00
committed by Andrew Johnson
parent 4ee766b6b1
commit dac620a708
2 changed files with 33 additions and 30 deletions

View File

@ -232,19 +232,41 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
return status; return status;
} }
/* Some records get options (precsision, units, ...) for some fields
* from an input link. We need to catch the case that this link
* points back to the same field or we will end in an infinite recursion.
*/
static long dbDbGetOptionLoopSafe(const struct link *plink, short dbrType,
void *pbuffer, long option)
{
/* We need to cast away const to set the flags.
That's ok because we know that plink is never actually readonly.
And we reset everything to its original state.
*/
struct link *mutable_plink = (struct link *)plink;
long status = S_dbLib_badLink;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
long number_elements = 0;
dbScanLock(paddr->precord);
if (!(mutable_plink->flags & DBLINK_FLAG_VISITED)) {
mutable_plink->flags |= DBLINK_FLAG_VISITED;
status = dbGet(paddr, dbrType, pbuffer, &option, &number_elements, NULL);
mutable_plink->flags &= ~DBLINK_FLAG_VISITED;
}
dbScanUnlock(paddr->precord);
return status;
}
static long dbDbGetControlLimits(const struct link *plink, double *low, static long dbDbGetControlLimits(const struct link *plink, double *low,
double *high) double *high)
{ {
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer { struct buffer {
DBRctrlDouble DBRctrlDouble
double value; double value;
} buffer; } buffer;
long options = DBR_CTRL_DOUBLE; long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_CTRL_DOUBLE);
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
NULL);
if (status) if (status)
return status; return status;
@ -257,16 +279,11 @@ static long dbDbGetControlLimits(const struct link *plink, double *low,
static long dbDbGetGraphicLimits(const struct link *plink, double *low, static long dbDbGetGraphicLimits(const struct link *plink, double *low,
double *high) double *high)
{ {
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer { struct buffer {
DBRgrDouble DBRgrDouble
double value; double value;
} buffer; } buffer;
long options = DBR_GR_DOUBLE; long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_GR_DOUBLE);
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
NULL);
if (status) if (status)
return status; return status;
@ -279,16 +296,11 @@ static long dbDbGetGraphicLimits(const struct link *plink, double *low,
static long dbDbGetAlarmLimits(const struct link *plink, double *lolo, static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
double *low, double *high, double *hihi) double *low, double *high, double *hihi)
{ {
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer { struct buffer {
DBRalDouble DBRalDouble
double value; double value;
} buffer; } buffer;
long options = DBR_AL_DOUBLE; long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_AL_DOUBLE);
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
0);
if (status) if (status)
return status; return status;
@ -302,16 +314,11 @@ static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
static long dbDbGetPrecision(const struct link *plink, short *precision) static long dbDbGetPrecision(const struct link *plink, short *precision)
{ {
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer { struct buffer {
DBRprecision DBRprecision
double value; double value;
} buffer; } buffer;
long options = DBR_PRECISION; long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_PRECISION);
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
0);
if (status) if (status)
return status; return status;
@ -322,16 +329,11 @@ static long dbDbGetPrecision(const struct link *plink, short *precision)
static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize) static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
{ {
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer { struct buffer {
DBRunits DBRunits
double value; double value;
} buffer; } buffer;
long options = DBR_UNITS; long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_UNITS);
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
0);
if (status) if (status)
return status; return status;

View File

@ -72,6 +72,7 @@ DBCORE_API extern const maplinkType pamaplinkType[LINK_NTYPES];
/* DBLINK Flag bits */ /* DBLINK Flag bits */
#define DBLINK_FLAG_INITIALIZED 1 /* dbInitLink() called */ #define DBLINK_FLAG_INITIALIZED 1 /* dbInitLink() called */
#define DBLINK_FLAG_TSELisTIME 2 /* Use TSEL to get timeStamp */ #define DBLINK_FLAG_TSELisTIME 2 /* Use TSEL to get timeStamp */
#define DBLINK_FLAG_VISITED 4 /* Used in loop detection */
struct macro_link { struct macro_link {
char *macroStr; char *macroStr;