Skip to content

Commit

Permalink
loop safe wrapper for dbGet added
Browse files Browse the repository at this point in the history
  • Loading branch information
dirk-zimoch committed Dec 2, 2024
1 parent 1567da1 commit 75524e4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 30 deletions.
62 changes: 32 additions & 30 deletions modules/database/src/ioc/db/dbDbLink.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,19 +232,41 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
return status;
}

static long dbDbGetControlLimits(const struct link *plink, double *low,
double *high)
/* 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,
double *high)
{
struct buffer {
DBRctrlDouble
double value;
} buffer;
long options = DBR_CTRL_DOUBLE;
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
NULL);
long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_CTRL_DOUBLE);

if (status)
return status;
Expand All @@ -257,16 +279,11 @@ static long dbDbGetControlLimits(const struct link *plink, double *low,
static long dbDbGetGraphicLimits(const struct link *plink, double *low,
double *high)
{
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRgrDouble
double value;
} buffer;
long options = DBR_GR_DOUBLE;
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
NULL);
long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_GR_DOUBLE);

if (status)
return status;
Expand All @@ -279,16 +296,11 @@ static long dbDbGetGraphicLimits(const struct link *plink, double *low,
static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
double *low, double *high, double *hihi)
{
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRalDouble
double value;
} buffer;
long options = DBR_AL_DOUBLE;
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
0);
long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_AL_DOUBLE);

if (status)
return status;
Expand All @@ -302,16 +314,11 @@ static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,

static long dbDbGetPrecision(const struct link *plink, short *precision)
{
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRprecision
double value;
} buffer;
long options = DBR_PRECISION;
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
0);
long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_PRECISION);

if (status)
return status;
Expand All @@ -322,16 +329,11 @@ static long dbDbGetPrecision(const struct link *plink, short *precision)

static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
{
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRunits
double value;
} buffer;
long options = DBR_UNITS;
long number_elements = 0;
long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements,
0);
long status = dbDbGetOptionLoopSafe(plink, DBR_DOUBLE, &buffer, DBR_UNITS);

if (status)
return status;
Expand Down
1 change: 1 addition & 0 deletions modules/database/src/ioc/dbStatic/link.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ DBCORE_API extern const maplinkType pamaplinkType[LINK_NTYPES];
/* DBLINK Flag bits */
#define DBLINK_FLAG_INITIALIZED 1 /* dbInitLink() called */
#define DBLINK_FLAG_TSELisTIME 2 /* Use TSEL to get timeStamp */
#define DBLINK_FLAG_VISITED 4 /* Used in loop detection */

struct macro_link {
char *macroStr;
Expand Down

0 comments on commit 75524e4

Please sign in to comment.