From 542353aedbf521e822f06d04d737f94dffc80088 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 23 May 2017 23:51:26 -0400 Subject: [PATCH] Fix aai constant initialization The aai record is "special" and does things its own way. These changes let it support {const:[...]} initialization without breaking regular input link types which could be initialized twice without the new DBLINK_FLAG_INITIALIZED guard in dbInitLink(). Also adds tests for this, and for similar links for waveform. --- src/ioc/db/dbLink.c | 6 ++++++ src/ioc/dbStatic/link.h | 2 ++ src/std/dev/devAaiSoft.c | 14 ++++++++------ src/std/rec/test/linkInitTest.c | 8 +++++++- src/std/rec/test/linkInitTest.db | 12 +++++++++++- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/ioc/db/dbLink.c b/src/ioc/db/dbLink.c index 6fb936ae4..9279b91fb 100644 --- a/src/ioc/db/dbLink.c +++ b/src/ioc/db/dbLink.c @@ -73,6 +73,12 @@ void dbInitLink(struct link *plink, short dbfType) { struct dbCommon *precord = plink->precord; + /* Only initialize link once */ + if (plink->flags & DBLINK_FLAG_INITIALIZED) + return; + else + plink->flags |= DBLINK_FLAG_INITIALIZED; + if (plink->type == CONSTANT) { dbConstInitLink(plink); return; diff --git a/src/ioc/dbStatic/link.h b/src/ioc/dbStatic/link.h index 9055c7588..f2b426308 100644 --- a/src/ioc/dbStatic/link.h +++ b/src/ioc/dbStatic/link.h @@ -69,6 +69,8 @@ epicsShareExtern maplinkType pamaplinkType[]; #define pvlOptOutString 0x400 /*Output as string*/ #define pvlOptTSELisTime 0x800 /*Field TSEL is getting timeStamp*/ +/* DBLINK Flag bits */ +#define DBLINK_FLAG_INITIALIZED 1 /* dbInitLink() called */ struct macro_link { char *macroStr; diff --git a/src/std/dev/devAaiSoft.c b/src/std/dev/devAaiSoft.c index e2e014efb..d2a9875ee 100644 --- a/src/std/dev/devAaiSoft.c +++ b/src/std/dev/devAaiSoft.c @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ /* @@ -53,7 +53,12 @@ epicsExportAddress(dset,devAaiSoft); static long init_record(aaiRecord *prec) { - if (prec->inp.type == CONSTANT) { + DBLINK *plink = &prec->inp; + + /* This is pass 0, link hasn't been initialized yet */ + dbInitLink(plink, DBF_INLINK); + + if (dbLinkIsConstant(plink)) { long nRequest = prec->nelm; long status; @@ -63,10 +68,7 @@ static long init_record(aaiRecord *prec) "devAaiSoft: buffer calloc failed"); } - /* This is pass 0 so link hasn't been initialized either */ - dbConstInitLink(&prec->inp); - - status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &nRequest); + status = dbLoadLinkArray(plink, prec->ftvl, prec->bptr, &nRequest); if (!status && nRequest > 0) { prec->nord = nRequest; prec->udf = FALSE; diff --git a/src/std/rec/test/linkInitTest.c b/src/std/rec/test/linkInitTest.c index cc17c07c5..301987ea2 100644 --- a/src/std/rec/test/linkInitTest.c +++ b/src/std/rec/test/linkInitTest.c @@ -138,17 +138,23 @@ static void testArrayInputs() testdbGetFieldEqual("aai1.NORD", DBR_LONG, 10); testdbGetFieldEqual("aai1.UDF", DBR_UCHAR, 0); + testdbGetFieldEqual("aai2.NORD", DBR_LONG, 10); + testdbGetFieldEqual("aai2.UDF", DBR_UCHAR, 0); testdbGetFieldEqual("sa1.NORD", DBR_LONG, 10); testdbGetFieldEqual("sa1.UDF", DBR_UCHAR, 0); testdbGetFieldEqual("sa2.NORD", DBR_LONG, 0); testdbGetFieldEqual("sa2.UDF", DBR_UCHAR, 1); testdbGetFieldEqual("wf1.NORD", DBR_LONG, 10); testdbGetFieldEqual("wf1.UDF", DBR_UCHAR, 0); + testdbGetFieldEqual("wf2.NORD", DBR_LONG, 10); + testdbGetFieldEqual("wf2.UDF", DBR_UCHAR, 0); testdbGetArrFieldEqual("aai1.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]); + testdbGetArrFieldEqual("aai2.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]); testdbGetArrFieldEqual("sa1.VAL", DBF_LONG, 12, 10, &oneToTwelve[2]); testdbGetArrFieldEqual("sa2.VAL", DBF_LONG, 10, 0, NULL); testdbGetArrFieldEqual("wf1.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]); + testdbGetArrFieldEqual("wf2.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]); testdbPutFieldOk("sa1.INDX", DBF_LONG, 3); testdbGetArrFieldEqual("sa1.VAL", DBF_LONG, 12, 9, &oneToTwelve[3]); @@ -200,7 +206,7 @@ static void testEventRecord() MAIN(linkInitTest) { - testPlan(62); + testPlan(68); testLongStringInit(); testCalcInit(); diff --git a/src/std/rec/test/linkInitTest.db b/src/std/rec/test/linkInitTest.db index 6887b56ba..907dc9288 100644 --- a/src/std/rec/test/linkInitTest.db +++ b/src/std/rec/test/linkInitTest.db @@ -31,11 +31,16 @@ record(printf, "printf2") { field(INP0, ["Longer test string, more that 40 characters long"]) } -record(waveform, "aai1") { +record(aai, "aai1") { field(NELM, 10) field(FTVL, "LONG") field(INP, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) } +record(aai, "aai2") { + field(NELM, 10) + field(FTVL, "LONG") + field(INP, {const:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}) +} record(subArray, "sa1") { field(FTVL, "LONG") field(MALM, 12) @@ -53,6 +58,11 @@ record(waveform, "wf1") { field(FTVL, "LONG") field(INP, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) } +record(waveform, "wf2") { + field(NELM, 10) + field(FTVL, "LONG") + field(INP, {const:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}) +} record(longin, "count1" ) { field(INP, {calc: {expr:"VAL+1"}})