Experimental Physics and Industrial Control System
Subject: |
[Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 |
From: |
Andrew Johnson via Core-talk <[email protected]> |
To: |
[email protected] |
Date: |
Thu, 18 Apr 2019 04:33:22 -0000 |
Andrew Johnson has proposed merging ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0.
Commit message:
Fix for bug lp: #1824277 and related issues.
This could go into 7.0.2.2 if nobody objects. The bug has existed since 3.16.1.
Requested reviews:
EPICS Core Developers (epics-core)
Related bugs:
Bug #1824277 in EPICS Base: "Regression in calcout setting constant links at runtime"
https://bugs.launchpad.net/epics-base/+bug/1824277
For more details, see:
https://code.launchpad.net/~anj/epics-base/+git/base-7.0/+merge/366247
--
Your team EPICS Core Developers is requested to review the proposed merge of ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0.
diff --git a/modules/database/src/ioc/db/dbAccess.c b/modules/database/src/ioc/db/dbAccess.c
index be81d22..35f19e2 100644
--- a/modules/database/src/ioc/db/dbAccess.c
+++ b/modules/database/src/ioc/db/dbAccess.c
@@ -1140,8 +1140,6 @@ static long dbPutFieldLink(DBADDR *paddr,
if (!status) status = dbSetLink(plink, &link_info, new_devsup);
- if (!status && special) status = dbPutSpecial(paddr, 1);
-
if (status) {
if (isDevLink) {
precord->dset = NULL;
@@ -1150,28 +1148,57 @@ static long dbPutFieldLink(DBADDR *paddr,
goto postScanEvent;
}
- if (isDevLink) {
+ /* We need to initialize any links with a link support layer, i.e.
+ * any CONSTANT, JSON_LINK, or PV_LINK types. However for a PV_LINK
+ * when isDevLink is set (i.e. this is the record's INP or OUT link)
+ * we must wait until after calling dsxt->add_record(). This allows
+ * the Async Soft Channel input supports to change it to a PN_LINK.
+ * For other cases we initialize the link before the second call to
+ * dbPutSpecial() because some record types such as calcout need to
+ * be able to call link support methods from prset->special().
+ */
+
+ switch (plink->type) { /* New type */
+ case PV_LINK:
+ if (isDevLink)
+ break;
+ /* else fall through */
+ case CONSTANT:
+ case JSON_LINK:
+ dbAddLink(&locker, plink, pfldDes->field_type, pdbaddr);
+ }
+
+ if (special) status = dbPutSpecial(paddr, 1);
+
+ if (!status && isDevLink) {
precord->dpvt = NULL;
precord->dset = new_dset;
precord->pact = FALSE;
status = new_dsxt->add_record(precord);
- if (status) {
+ }
+
+ if (status) {
+ if (isDevLink) {
precord->dset = NULL;
precord->pact = TRUE;
- goto postScanEvent;
}
+ goto postScanEvent;
}
switch (plink->type) { /* New link type */
- case PV_LINK:
case CONSTANT:
+ case CA_LINK:
+ case DB_LINK:
+ case PN_LINK:
case JSON_LINK:
- dbAddLink(&locker, plink, pfldDes->field_type, pdbaddr);
break;
- case DB_LINK:
- case CA_LINK:
+ case PV_LINK:
+ if (isDevLink)
+ dbAddLink(&locker, plink, pfldDes->field_type, pdbaddr);
+ break;
+
case MACRO_LINK:
break; /* should never get here */
@@ -1180,7 +1207,6 @@ static long dbPutFieldLink(DBADDR *paddr,
status = S_db_badHWaddr;
goto postScanEvent;
}
- break;
}
db_post_events(precord, plink, DBE_VALUE | DBE_LOG);
diff --git a/modules/database/src/std/dev/devAiSoftCallback.c b/modules/database/src/std/dev/devAiSoftCallback.c
index cf38c87..872684c 100644
--- a/modules/database/src/std/dev/devAiSoftCallback.c
+++ b/modules/database/src/std/dev/devAiSoftCallback.c
@@ -80,7 +80,7 @@ static long add_record(dbCommon *pcommon)
devPvt *pdevPvt;
processNotify *ppn;
- if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink))
+ if (plink->type == CONSTANT)
return 0;
if (plink->type != PV_LINK) {
diff --git a/modules/database/src/std/dev/devBiSoftCallback.c b/modules/database/src/std/dev/devBiSoftCallback.c
index 3144600..88b96f8 100644
--- a/modules/database/src/std/dev/devBiSoftCallback.c
+++ b/modules/database/src/std/dev/devBiSoftCallback.c
@@ -78,7 +78,7 @@ static long add_record(dbCommon *pcommon)
devPvt *pdevPvt;
processNotify *ppn;
- if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink))
+ if (plink->type == CONSTANT)
return 0;
if (plink->type != PV_LINK) {
diff --git a/modules/database/src/std/dev/devI64inSoftCallback.c b/modules/database/src/std/dev/devI64inSoftCallback.c
index 9eb5656..43c48f6 100644
--- a/modules/database/src/std/dev/devI64inSoftCallback.c
+++ b/modules/database/src/std/dev/devI64inSoftCallback.c
@@ -78,7 +78,7 @@ static long add_record(dbCommon *pcommon)
devPvt *pdevPvt;
processNotify *ppn;
- if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink))
+ if (plink->type == CONSTANT)
return 0;
if (plink->type != PV_LINK) {
diff --git a/modules/database/src/std/dev/devLiSoftCallback.c b/modules/database/src/std/dev/devLiSoftCallback.c
index caab523..a95f989 100644
--- a/modules/database/src/std/dev/devLiSoftCallback.c
+++ b/modules/database/src/std/dev/devLiSoftCallback.c
@@ -78,7 +78,7 @@ static long add_record(dbCommon *pcommon)
devPvt *pdevPvt;
processNotify *ppn;
- if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink))
+ if (plink->type == CONSTANT)
return 0;
if (plink->type != PV_LINK) {
diff --git a/modules/database/src/std/dev/devMbbiDirectSoftCallback.c b/modules/database/src/std/dev/devMbbiDirectSoftCallback.c
index d785f73..947b9c0 100644
--- a/modules/database/src/std/dev/devMbbiDirectSoftCallback.c
+++ b/modules/database/src/std/dev/devMbbiDirectSoftCallback.c
@@ -78,7 +78,7 @@ static long add_record(dbCommon *pcommon)
devPvt *pdevPvt;
processNotify *ppn;
- if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink))
+ if (plink->type == CONSTANT)
return 0;
if (plink->type != PV_LINK) {
diff --git a/modules/database/src/std/dev/devMbbiSoftCallback.c b/modules/database/src/std/dev/devMbbiSoftCallback.c
index 3796bce..5b3370f 100644
--- a/modules/database/src/std/dev/devMbbiSoftCallback.c
+++ b/modules/database/src/std/dev/devMbbiSoftCallback.c
@@ -78,7 +78,7 @@ static long add_record(dbCommon *pcommon)
devPvt *pdevPvt;
processNotify *ppn;
- if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink))
+ if (plink->type == CONSTANT)
return 0;
if (plink->type != PV_LINK) {
diff --git a/modules/database/src/std/dev/devSiSoftCallback.c b/modules/database/src/std/dev/devSiSoftCallback.c
index 8f67988..2b0922c 100644
--- a/modules/database/src/std/dev/devSiSoftCallback.c
+++ b/modules/database/src/std/dev/devSiSoftCallback.c
@@ -80,7 +80,7 @@ static long add_record(dbCommon *pcommon)
devPvt *pdevPvt;
processNotify *ppn;
- if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink))
+ if (plink->type == CONSTANT)
return 0;
if (plink->type != PV_LINK) {
diff --git a/modules/database/test/std/rec/Makefile b/modules/database/test/std/rec/Makefile
index 185c2c0..cd7316a 100644
--- a/modules/database/test/std/rec/Makefile
+++ b/modules/database/test/std/rec/Makefile
@@ -113,8 +113,8 @@ regressTest_DBD += base.dbd
TESTPROD_HOST += regressTest
regressTest_SRCS += regressTest.c
regressTest_SRCS += regressTest_registerRecordDeviceDriver.cpp
-TESTFILES += $(COMMON_DIR)/regressTest.dbd ../regressArray1.db ../regressHex.db ../regressLinkMS.db
-TESTFILES += ../badCaLink.db
+TESTFILES += $(COMMON_DIR)/regressTest.dbd ../regressArray1.db ../regressHex.db
+TESTFILES += ../regressLinkMS.db ../badCaLink.db ../regressCalcout.db
TESTS += regressTest
TARGETS += $(COMMON_DIR)/simmTest.dbd
diff --git a/modules/database/test/std/rec/regressCalcout.db b/modules/database/test/std/rec/regressCalcout.db
new file mode 100644
index 0000000..8896131
--- /dev/null
+++ b/modules/database/test/std/rec/regressCalcout.db
@@ -0,0 +1,27 @@
+record(calcout, "cout") {
+ field(INPA, "99")
+ field(INPB, "99")
+ field(INPC, "99")
+ field(INPD, "99")
+}
+record(ai, "ain") {
+ field(DTYP, "Async Soft Channel")
+}
+record(bi, "bin") {
+ field(DTYP, "Async Soft Channel")
+}
+record(int64in, "iin") {
+ field(DTYP, "Async Soft Channel")
+}
+record(longin, "lin") {
+ field(DTYP, "Async Soft Channel")
+}
+record(mbbi, "min") {
+ field(DTYP, "Async Soft Channel")
+}
+record(mbbiDirect, "din") {
+ field(DTYP, "Async Soft Channel")
+}
+record(stringin, "sin") {
+ field(DTYP, "Async Soft Channel")
+}
diff --git a/modules/database/test/std/rec/regressTest.c b/modules/database/test/std/rec/regressTest.c
index 6614639..37bcc31 100644
--- a/modules/database/test/std/rec/regressTest.c
+++ b/modules/database/test/std/rec/regressTest.c
@@ -135,15 +135,61 @@ void testCADisconn(void)
testdbPutFieldOk("ai:disconn.PROC", DBF_LONG, 1);
testdbGetFieldEqual("ai:disconn.SEVR", DBF_LONG, INVALID_ALARM);
testdbGetFieldEqual("ai:disconn.STAT", DBF_LONG, LINK_ALARM);
+
+ testIocShutdownOk();
+ testdbCleanup();
+}
+
+/* lp:1824277 Regression in calcout, setting links at runtime */
+static void
+testSpecialLinks(void)
+{
+ testDiag("In testSpecialLinks()");
+
+ startRegressTestIoc("regressCalcout.db");
+
+ testdbPutFieldOk("cout.INPA", DBF_STRING, "10");
+ testdbGetFieldEqual("cout.A", DBF_LONG, 10);
+ testdbGetFieldEqual("cout.INAV", DBF_LONG, calcoutINAV_CON);
+ testdbPutFieldOk("cout.INPB", DBF_STRING, "{\"const\":20}");
+ testdbGetFieldEqual("cout.B", DBF_LONG, 20);
+ testdbGetFieldEqual("cout.INBV", DBF_LONG, calcoutINAV_CON);
+ testdbPutFieldOk("cout.INPC", DBF_STRING, "cout.A");
+ testdbGetFieldEqual("cout.C", DBF_LONG, 99);
+ testdbGetFieldEqual("cout.INCV", DBF_LONG, calcoutINAV_LOC);
+ testdbPutFieldOk("cout.INPD", DBF_STRING, "no-such-pv");
+ testdbGetFieldEqual("cout.D", DBF_LONG, 99);
+ testdbGetFieldEqual("cout.INDV", DBF_LONG, calcoutINAV_EXT_NC);
+
+ eltc(0);
+ testdbPutFieldOk("ain.INP", DBF_STRING, "cout");
+ testdbPutFieldFail(S_db_badField, "ain.INP", DBF_STRING, "{\"const\":1}");
+ testdbPutFieldOk("bin.INP", DBF_STRING, "cout");
+ testdbPutFieldFail(S_db_badField, "bin.INP", DBF_STRING, "{\"const\":1}");
+ testdbPutFieldOk("iin.INP", DBF_STRING, "cout");
+ testdbPutFieldFail(S_db_badField, "iin.INP", DBF_STRING, "{\"const\":1}");
+ testdbPutFieldOk("lin.INP", DBF_STRING, "cout");
+ testdbPutFieldFail(S_db_badField, "lin.INP", DBF_STRING, "{\"const\":1}");
+ testdbPutFieldOk("min.INP", DBF_STRING, "cout");
+ testdbPutFieldFail(S_db_badField, "min.INP", DBF_STRING, "{\"const\":1}");
+ testdbPutFieldOk("din.INP", DBF_STRING, "cout");
+ testdbPutFieldFail(S_db_badField, "din.INP", DBF_STRING, "{\"const\":1}");
+ testdbPutFieldOk("sin.INP", DBF_STRING, "cout");
+ testdbPutFieldFail(S_db_badField, "sin.INP", DBF_STRING, "{\"const\":1}");
+ eltc(1);
+
+ testIocShutdownOk();
+ testdbCleanup();
}
MAIN(regressTest)
{
- testPlan(34);
+ testPlan(60);
testArrayLength1();
testHexConstantLinks();
testLinkMS();
testCADisconn();
+ testSpecialLinks();
return testDone();
}
- Replies:
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 Andrew Johnson via Core-talk
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 mdavidsaver via Core-talk
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 Andrew Johnson via Core-talk
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 Keenan Lang via Core-talk
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 Keenan Lang via Core-talk
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 Keenan Lang via Core-talk
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 mdavidsaver via Core-talk
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 mdavidsaver via Core-talk
- Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 Andrew Johnson via Core-talk
- Navigate by Date:
- Prev:
Build failed in Jenkins: epics-base-7.0-win64s-test #23 APS Jenkins via Core-talk
- Next:
Re: Support for Google Test in EPICS base / modules? Ralph Lange via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
<2019>
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Jenkins build is back to normal : epics-base-7.0-win64-test #22 APS Jenkins via Core-talk
- Next:
Re: [Merge] ~anj/epics-base/+git/base-7.0:fix-1824277 into epics-base:7.0 Andrew Johnson via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
<2019>
2020
2021
2022
2023
2024