From 3fb10b6d59f3434b86858bbc9d829aaf1fbfbfb7 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Sat, 29 Dec 2018 19:29:39 -0800
Subject: [PATCH 01/30] dbNotify set PUTF
---
modules/database/src/ioc/db/dbNotify.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/modules/database/src/ioc/db/dbNotify.c b/modules/database/src/ioc/db/dbNotify.c
index c2420affc..794672a55 100644
--- a/modules/database/src/ioc/db/dbNotify.c
+++ b/modules/database/src/ioc/db/dbNotify.c
@@ -86,12 +86,6 @@ typedef struct notifyGlobal {
static notifyGlobal *pnotifyGlobal = 0;
-/*Local routines*/
-static void notifyInit(processNotify *ppn);
-static void notifyCleanup(processNotify *ppn);
-static void restartCheck(processNotifyRecord *ppnr);
-static void callDone(dbCommon *precord,processNotify *ppn);
-static void processNotifyCommon(processNotify *ppn,dbCommon *precord);
static void notifyCallback(CALLBACK *pcallback);
#define ellSafeAdd(list,listnode) \
@@ -210,7 +204,7 @@ static void callDone(dbCommon *precord, processNotify *ppn)
return;
}
-static void processNotifyCommon(processNotify *ppn,dbCommon *precord)
+static void processNotifyCommon(processNotify *ppn, dbCommon *precord, int first)
{
notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
int didPut = 0;
@@ -256,6 +250,9 @@ static void processNotifyCommon(processNotify *ppn,dbCommon *precord)
doProcess = 1;
if (doProcess) {
+ if (first) {
+ precord->putf = TRUE;
+ }
ppn->wasProcessed = 1;
precord->ppn = ppn;
ellSafeAdd(&pnotifyPvt->waitList, &precord->ppnr->waitNode);
@@ -298,7 +295,7 @@ static void notifyCallback(CALLBACK *pcallback)
return;
}
if(pnotifyPvt->state == notifyRestartCallbackRequested) {
- processNotifyCommon(ppn, precord);
+ processNotifyCommon(ppn, precord, 0);
return;
}
/* All done. Clean up and call userCallback */
@@ -382,7 +379,7 @@ void dbProcessNotify(processNotify *ppn)
precord->ppnr->precord = precord;
ellInit(&precord->ppnr->restartList);
}
- processNotifyCommon(ppn, precord);
+ processNotifyCommon(ppn, precord, 1);
}
void dbNotifyCancel(processNotify *ppn)
@@ -582,7 +579,7 @@ static void tpnThread(void *pvt)
processNotify *ppn = (processNotify *) ptpnInfo->ppn;
dbProcessNotify(ppn);
- epicsEventWait(ptpnInfo->callbackDone);
+ epicsEventMustWait(ptpnInfo->callbackDone);
dbNotifyCancel(ppn);
epicsEventDestroy(ptpnInfo->callbackDone);
dbChannelDelete(ppn->chan);
From bc7ee94e2c7903dc83fec7b18e9f64439b68216e Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Thu, 3 Jan 2019 20:33:34 -0800
Subject: [PATCH 02/30] Remove Warning: 'blah.PUTF' found true with PACT false
---
modules/database/src/ioc/db/dbDbLink.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/modules/database/src/ioc/db/dbDbLink.c b/modules/database/src/ioc/db/dbDbLink.c
index ce0110a64..c4e2b1987 100644
--- a/modules/database/src/ioc/db/dbDbLink.c
+++ b/modules/database/src/ioc/db/dbDbLink.c
@@ -406,10 +406,6 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
printf("%s: '%s' -> '%s' with PUTF=%u\n",
context, psrc->name, pdst->name, psrc->putf);
- if (pdst->putf)
- errlogPrintf("Warning: '%s.PUTF' found true with PACT false\n",
- pdst->name);
-
pdst->putf = psrc->putf;
}
else if (psrc->putf) {
From 5e1bad2b34fb2b3920d7dedb2d6abe239cc17f80 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Thu, 10 Jan 2019 14:45:18 -0600
Subject: [PATCH 03/30] dbStatic parser: Reject empty object names
---
src/ioc/dbStatic/dbLexRoutines.c | 64 +++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 6 deletions(-)
diff --git a/src/ioc/dbStatic/dbLexRoutines.c b/src/ioc/dbStatic/dbLexRoutines.c
index b11f4a3fa..3df3c7f3a 100644
--- a/src/ioc/dbStatic/dbLexRoutines.c
+++ b/src/ioc/dbStatic/dbLexRoutines.c
@@ -428,6 +428,10 @@ static void dbMenuHead(char *name)
dbMenu *pdbMenu;
GPHENTRY *pgphentry;
+ if (!*name) {
+ yyerrorAbort("dbMenuHead: Menu name can't be empty");
+ return;
+ }
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->menuList);
if(pgphentry) {
duplicate = TRUE;
@@ -441,6 +445,10 @@ static void dbMenuHead(char *name)
static void dbMenuChoice(char *name,char *value)
{
+ if (!*name) {
+ yyerror("dbMenuChoice: Menu choice name can't be empty");
+ return;
+ }
if(duplicate) return;
allocTemp(epicsStrDup(name));
allocTemp(epicsStrDup(value));
@@ -488,6 +496,10 @@ static void dbRecordtypeHead(char *name)
dbRecordType *pdbRecordType;
GPHENTRY *pgphentry;
+ if (!*name) {
+ yyerrorAbort("dbRecordtypeHead: Recordtype name can't be empty");
+ return;
+ }
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->recordTypeList);
if(pgphentry) {
duplicate = TRUE;
@@ -505,7 +517,11 @@ static void dbRecordtypeFieldHead(char *name,char *type)
{
dbFldDes *pdbFldDes;
int i;
-
+
+ if (!*name) {
+ yyerrorAbort("dbRecordtypeFieldHead: Field name can't be empty");
+ return;
+ }
if(duplicate) return;
pdbFldDes = dbCalloc(1,sizeof(dbFldDes));
allocTemp(pdbFldDes);
@@ -572,7 +588,7 @@ static void dbRecordtypeFieldItem(char *name,char *value)
if(sscanf(value,"%hd",&pdbFldDes->special)==1) {
return;
}
- yyerror("Illegal special value.");
+ yyerror("Illegal 'special' value.");
return;
}
if(strcmp(name,"pp")==0) {
@@ -581,13 +597,13 @@ static void dbRecordtypeFieldItem(char *name,char *value)
} else if((strcmp(value,"NO")==0) || (strcmp(value,"FALSE")==0)) {
pdbFldDes->process_passive = FALSE;
} else {
- yyerror("Illegal value. Must be NO or YES");
+ yyerror("Illegal 'pp' value, must be YES/NO/TRUE/FALSE");
}
return;
}
if(strcmp(name,"interest")==0) {
if(sscanf(value,"%hd",&pdbFldDes->interest)!=1)
- yyerror("Illegal value. Must be integer");
+ yyerror("Illegal 'interest' value, must be integer");
return;
}
if(strcmp(name,"base")==0) {
@@ -596,13 +612,13 @@ static void dbRecordtypeFieldItem(char *name,char *value)
} else if(strcmp(value,"HEX")==0) {
pdbFldDes->base = CT_HEX;
} else {
- yyerror("Illegal value. Must be CT_DECIMAL or CT_HEX");
+ yyerror("Illegal 'base' value, must be DECIMAL/HEX");
}
return;
}
if(strcmp(name,"size")==0) {
if(sscanf(value,"%hd",&pdbFldDes->size)!=1)
- yyerror("Illegal value. Must be integer");
+ yyerror("Illegal 'size' value, must be integer");
return;
}
if(strcmp(name,"extra")==0) {
@@ -794,6 +810,10 @@ static void dbDriver(char *name)
drvSup *pdrvSup;
GPHENTRY *pgphentry;
+ if (!*name) {
+ yyerrorAbort("dbDriver: Driver name can't be empty");
+ return;
+ }
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->drvList);
if(pgphentry) {
return;
@@ -813,6 +833,10 @@ static void dbRegistrar(char *name)
dbText *ptext;
GPHENTRY *pgphentry;
+ if (!*name) {
+ yyerrorAbort("dbRegistrar: Registrar name can't be empty");
+ return;
+ }
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->registrarList);
if(pgphentry) {
return;
@@ -832,6 +856,10 @@ static void dbFunction(char *name)
dbText *ptext;
GPHENTRY *pgphentry;
+ if (!*name) {
+ yyerrorAbort("dbFunction: Function name can't be empty");
+ return;
+ }
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->functionList);
if(pgphentry) {
return;
@@ -851,6 +879,10 @@ static void dbVariable(char *name, char *type)
dbVariableDef *pvar;
GPHENTRY *pgphentry;
+ if (!*name) {
+ yyerrorAbort("dbVariable: Variable name can't be empty");
+ return;
+ }
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->variableList);
if(pgphentry) {
return;
@@ -871,6 +903,10 @@ static void dbBreakHead(char *name)
brkTable *pbrkTable;
GPHENTRY *pgphentry;
+ if (!*name) {
+ yyerrorAbort("dbBreakHead: Breaktable name can't be empty");
+ return;
+ }
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->bptList);
if(pgphentry) {
duplicate = TRUE;
@@ -973,6 +1009,10 @@ static void dbRecordHead(char *recordType, char *name, int visible)
DBENTRY *pdbentry;
long status;
+ if (!*name) {
+ yyerrorAbort("dbRecordHead: Record name can't be empty");
+ return;
+ }
badch = strpbrk(name, " \"'.$");
if (badch) {
epicsPrintf("Bad character '%c' in record name \"%s\"\n",
@@ -1072,6 +1112,10 @@ static void dbRecordInfo(char *name, char *value)
tempListNode *ptempListNode;
long status;
+ if (!*name) {
+ yyerrorAbort("dbRecordInfo: Info item name can't be empty");
+ return;
+ }
if (duplicate) return;
ptempListNode = (tempListNode *)ellFirst(&tempList);
pdbentry = ptempListNode->item;
@@ -1091,6 +1135,10 @@ static void dbRecordAlias(char *name)
tempListNode *ptempListNode;
long status;
+ if (!*name) {
+ yyerrorAbort("dbRecordAlias: Alias name can't be empty");
+ return;
+ }
if (duplicate) return;
ptempListNode = (tempListNode *)ellFirst(&tempList);
pdbentry = ptempListNode->item;
@@ -1108,6 +1156,10 @@ static void dbAlias(char *name, char *alias)
DBENTRY dbEntry;
DBENTRY *pdbEntry = &dbEntry;
+ if (!*alias) {
+ yyerrorAbort("dbAlias: Alias name can't be empty");
+ return;
+ }
dbInitEntry(pdbbase, pdbEntry);
if (dbFindRecord(pdbEntry, name)) {
epicsPrintf("Alias \"%s\" refers to unknown record \"%s\"\n",
From 5eb7da45957640b20b07347dc4a7008c25e1b63f Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Sun, 27 Jan 2019 18:17:53 -0800
Subject: [PATCH 04/30] dbRec2Pvt()
---
modules/database/src/ioc/db/dbAccess.c | 4 ++--
modules/database/src/ioc/db/dbCommonPvt.h | 8 ++++++++
modules/database/src/ioc/dbStatic/dbStaticRun.c | 2 +-
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/modules/database/src/ioc/db/dbAccess.c b/modules/database/src/ioc/db/dbAccess.c
index dfe3e0455..323131767 100644
--- a/modules/database/src/ioc/db/dbAccess.c
+++ b/modules/database/src/ioc/db/dbAccess.c
@@ -679,7 +679,7 @@ finish:
void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry)
{
struct dbCommon *prec = paddr->precord;
- dbCommonPvt *ppvt = CONTAINER(prec, dbCommonPvt, common);
+ dbCommonPvt *ppvt = dbRec2Pvt(prec);
memset((char *)pdbentry,'\0',sizeof(DBENTRY));
@@ -693,7 +693,7 @@ void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry)
void dbInitEntryFromRecord(struct dbCommon *prec, DBENTRY *pdbentry)
{
- dbCommonPvt *ppvt = CONTAINER(prec, dbCommonPvt, common);
+ dbCommonPvt *ppvt = dbRec2Pvt(prec);
memset((char *)pdbentry,'\0',sizeof(DBENTRY));
diff --git a/modules/database/src/ioc/db/dbCommonPvt.h b/modules/database/src/ioc/db/dbCommonPvt.h
index 3dfce8b27..e91de6f65 100644
--- a/modules/database/src/ioc/db/dbCommonPvt.h
+++ b/modules/database/src/ioc/db/dbCommonPvt.h
@@ -1,6 +1,8 @@
#ifndef DBCOMMONPVT_H
#define DBCOMMONPVT_H
+#include
+#include
#include "dbCommon.h"
/** Base internal additional information for every record
@@ -11,4 +13,10 @@ typedef struct dbCommonPvt {
struct dbCommon common;
} dbCommonPvt;
+static EPICS_ALWAYS_INLINE
+dbCommonPvt* dbRec2Pvt(struct dbCommon *prec)
+{
+ return CONTAINER(prec, dbCommonPvt, common);
+}
+
#endif // DBCOMMONPVT_H
diff --git a/modules/database/src/ioc/dbStatic/dbStaticRun.c b/modules/database/src/ioc/dbStatic/dbStaticRun.c
index d3817ffc5..46cbf982a 100644
--- a/modules/database/src/ioc/dbStatic/dbStaticRun.c
+++ b/modules/database/src/ioc/dbStatic/dbStaticRun.c
@@ -179,7 +179,7 @@ long dbFreeRecord(DBENTRY *pdbentry)
if(!pdbRecordType) return(S_dbLib_recordTypeNotFound);
if(!precnode) return(S_dbLib_recNotFound);
if(!precnode->precord) return(S_dbLib_recNotFound);
- free(CONTAINER(precnode->precord, dbCommonPvt, common));
+ free(dbRec2Pvt(precnode->precord));
precnode->precord = NULL;
return(0);
}
From e9189947044a7f836f1af5eb774aac2ac32dbaa8 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Sun, 27 Jan 2019 18:33:17 -0800
Subject: [PATCH 05/30] test for RPRO/PUTF regression
---
modules/database/test/std/rec/asyncproctest.c | 30 ++++++++++++++++++-
.../database/test/std/rec/asyncproctest.db | 27 +++++++++++++++++
2 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/modules/database/test/std/rec/asyncproctest.c b/modules/database/test/std/rec/asyncproctest.c
index a8b09a928..ac788c755 100644
--- a/modules/database/test/std/rec/asyncproctest.c
+++ b/modules/database/test/std/rec/asyncproctest.c
@@ -9,6 +9,7 @@
#include
#include
+#include
#include
#include
#include
@@ -16,6 +17,7 @@
#include
#include "registryFunction.h"
#include
+#include
epicsEventId done;
static int waitFor;
@@ -28,11 +30,17 @@ long doneSubr(subRecord *prec)
return 0;
}
+static
+void dummydone(void *usr, struct dbCommon* prec)
+{
+ epicsEventMustTrigger(done);
+}
+
void asyncproctest_registerRecordDeviceDriver(struct dbBase *);
MAIN(asyncproctest)
{
- testPlan(21);
+ testPlan(25);
done = epicsEventMustCreate(epicsEventEmpty);
@@ -99,6 +107,26 @@ MAIN(asyncproctest)
testdbGetFieldEqual("chain3", DBF_LONG, 7);
testdbGetFieldEqual("chain3.A", DBF_LONG, 2);
+ testDiag("===== Chain 4 ======");
+
+ {
+ dbCommon *dummy=testdbRecordPtr("chain4_dummy");
+
+ testdbPutFieldOk("chain4_pos.PROC", DBF_LONG, 0);
+
+ /* sync once queue to wait for any queued RPRO */
+ scanOnceCallback(dummy, dummydone, NULL);
+
+ if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK)
+ testAbort("Processing timed out");
+
+ testTodoBegin("Bug");
+ testdbGetFieldEqual("chain4_pos", DBF_SHORT, 1);
+ testdbGetFieldEqual("chain4_rel", DBF_SHORT, 1);
+ testdbGetFieldEqual("chain4_lim", DBF_SHORT, 1);
+ testTodoEnd();
+ }
+
testIocShutdownOk();
testdbCleanup();
diff --git a/modules/database/test/std/rec/asyncproctest.db b/modules/database/test/std/rec/asyncproctest.db
index 352b6ca56..4f8a97522 100644
--- a/modules/database/test/std/rec/asyncproctest.db
+++ b/modules/database/test/std/rec/asyncproctest.db
@@ -53,3 +53,30 @@ record(sub, "done3") {
field(FLNK, "chain3")
field(TPRO, "$(TPRO=)")
}
+
+
+# loop breaking regression
+# should _not_ RPRO
+record(calcout,"chain4_pos") {
+ field(CALC, "E:=E+1;E")
+ field(OUT,"chain4_rel.A PP")
+ field(TPRO, "$(TPRO=)")
+}
+
+record(calc,"chain4_rel") {
+ field(CALC, "E:=E+1;E")
+ field(FLNK,"chain4_lim")
+ field(TPRO, "$(TPRO=)")
+}
+
+record(calc,"chain4_lim") {
+ field(CALC, "E:=E+1;E")
+ field(INPA,"chain4_pos PP")
+ field(INPB,"chain4_pos.HIGH PP")
+ field(INPC,"chain4_pos.LOW PP")
+ field(TPRO, "$(TPRO=)")
+}
+
+record(bo, "chain4_dummy") {
+field(TPRO, "$(TPRO=)")
+}
From e860617389c14eb297742e1fad6e4f0dcf659194 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Sun, 27 Jan 2019 19:10:00 -0800
Subject: [PATCH 06/30] fix RPRO/PUTF regression
---
modules/database/src/ioc/db/dbCommonPvt.h | 5 +++
modules/database/src/ioc/db/dbDbLink.c | 34 ++++++++++++++++---
modules/database/test/std/rec/asyncproctest.c | 2 --
3 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/modules/database/src/ioc/db/dbCommonPvt.h b/modules/database/src/ioc/db/dbCommonPvt.h
index e91de6f65..eda8b18a7 100644
--- a/modules/database/src/ioc/db/dbCommonPvt.h
+++ b/modules/database/src/ioc/db/dbCommonPvt.h
@@ -5,11 +5,16 @@
#include
#include "dbCommon.h"
+struct epicsThreadOSD;
+
/** Base internal additional information for every record
*/
typedef struct dbCommonPvt {
struct dbRecordNode *recnode;
+ /* Thread which is currently processing this record */
+ struct epicsThreadOSD* procThread;
+
struct dbCommon common;
} dbCommonPvt;
diff --git a/modules/database/src/ioc/db/dbDbLink.c b/modules/database/src/ioc/db/dbDbLink.c
index c4e2b1987..d53e1568c 100644
--- a/modules/database/src/ioc/db/dbDbLink.c
+++ b/modules/database/src/ioc/db/dbDbLink.c
@@ -56,7 +56,7 @@
#include "dbAddr.h"
#include "dbBase.h"
#include "dbBkpt.h"
-#include "dbCommon.h"
+#include "dbCommonPvt.h"
#include "dbConvertFast.h"
#include "dbConvert.h"
#include "db_field_log.h"
@@ -386,8 +386,11 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
{
char context[40] = "";
int trace = dbAccessDebugPUTF && *dbLockSetAddrTrace(psrc);
+ int srcset = dbRec2Pvt(psrc)->procThread==NULL;
+ int dstset = dbRec2Pvt(pdst)->procThread==NULL;
long status;
epicsUInt8 pact = psrc->pact;
+ epicsThreadId self = epicsThreadGetIdSelf();
psrc->pact = TRUE;
@@ -408,8 +411,9 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
pdst->putf = psrc->putf;
}
- else if (psrc->putf) {
- /* The dst record is busy (awaiting async reprocessing) and
+ else if (psrc->putf && dbRec2Pvt(pdst)->procThread!=self) {
+ /* The dst record is busy (awaiting async reprocessing),
+ * not being processed recursively by us, and
* we were originally triggered by a call to dbPutField(),
* so we mark the dst record for reprocessing once the async
* completion is over.
@@ -422,17 +426,37 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
pdst->rpro = TRUE;
}
else {
- /* The dst record is busy, but we weren't triggered by a call
- * to dbPutField(). Do nothing.
+ /* The dst record is busy, but either is being processed recursively,
+ * or wasn't triggered by a call to dbPutField(). Do nothing.
*/
if (trace)
printf("%s: '%s' -> Active '%s', done\n",
context, psrc->name, pdst->name);
}
+ if(srcset) {
+ dbRec2Pvt(psrc)->procThread = self;
+ } else {
+ assert(dbRec2Pvt(psrc)->procThread==self);
+ }
+ if(dstset) {
+ dbRec2Pvt(pdst)->procThread = self;
+ } else {
+ assert(dbRec2Pvt(psrc)->procThread==self);
+ }
+
status = dbProcess(pdst);
psrc->pact = pact;
+ assert(dbRec2Pvt(psrc)->procThread==self);
+ assert(dbRec2Pvt(pdst)->procThread==self);
+ if(srcset) {
+ dbRec2Pvt(psrc)->procThread = NULL;
+ }
+ if(dstset) {
+ dbRec2Pvt(pdst)->procThread = NULL;
+ }
+
return status;
}
diff --git a/modules/database/test/std/rec/asyncproctest.c b/modules/database/test/std/rec/asyncproctest.c
index ac788c755..b10bcac68 100644
--- a/modules/database/test/std/rec/asyncproctest.c
+++ b/modules/database/test/std/rec/asyncproctest.c
@@ -120,11 +120,9 @@ MAIN(asyncproctest)
if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK)
testAbort("Processing timed out");
- testTodoBegin("Bug");
testdbGetFieldEqual("chain4_pos", DBF_SHORT, 1);
testdbGetFieldEqual("chain4_rel", DBF_SHORT, 1);
testdbGetFieldEqual("chain4_lim", DBF_SHORT, 1);
- testTodoEnd();
}
testIocShutdownOk();
From 9ef3b773486128f157bae6ff2931bf5ffcd44537 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Fri, 1 Feb 2019 16:14:45 -0600
Subject: [PATCH 07/30] Fix ca/client/perl/Makefile for macOS Mojave
... in which Apple moved the Perl headers into XCode.
This should also make the build a little more forgiving on other
architectures that have incomplete Perl installations; it gives up
trying to build the Perl bindings with a warning if perl.h is missing.
---
src/ca/client/perl/Makefile | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/src/ca/client/perl/Makefile b/src/ca/client/perl/Makefile
index 9b61b3b32..98352b2e7 100644
--- a/src/ca/client/perl/Makefile
+++ b/src/ca/client/perl/Makefile
@@ -8,6 +8,18 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
+ifdef T_A
+ PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version)
+ PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname)
+ PERL_ARCHPATH := $(PERL_VERSION)/$(PERL_ARCHNAME)
+
+ PERL_ARCHLIB := $(shell $(PERL) ../perlConfig.pl archlib)
+ PERL_h = $(PERL_ARCHLIB)/CORE/perl.h
+
+ EXTUTILS := $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils
+ PERLBIN := $(shell $(PERL) ../perlConfig.pl bin)
+ XSUBPP := $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp))
+
# Special settings for Darwin:
ifeq ($(OS_CLASS),Darwin)
# Use hdepends command (not GNU compiler flags)
@@ -18,22 +30,23 @@ ifeq ($(OS_CLASS),Darwin)
# Perl loadable libraries on Darwin have funny names
LOADABLE_SHRLIB_PREFIX =
LOADABLE_SHRLIB_SUFFIX = .$(shell $(PERL) ../perlConfig.pl dlext)
+
+ifeq ($(wildcard $(PERL_h)),)
+ # Perl's headers moved in Mojave
+ SDK_PATH := $(shell xcodebuild -version -sdk macosx Path)
+ PERL_ARCHLIB := $(SDK_PATH)/$(PERL_ARCHLIB)
+endif
endif
-ifdef T_A
- PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version)
- PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname)
- PERL_ARCHPATH := $(PERL_VERSION)/$(PERL_ARCHNAME)
-
- EXTUTILS := $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils
- PERLBIN := $(shell $(PERL) ../perlConfig.pl bin)
- XSUBPP := $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp))
-
+ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!)
ifeq ($(strip $(XSUBPP)),)
$(warning Perl's xsubpp program was not found.)
$(warning The Perl CA module will not be built.)
else
-ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!)
+ifeq ($(wildcard $(PERL_h)),)
+ $(warning Perl's C header files were not found.)
+ $(warning The Perl CA module will not be built.)
+else
ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),) # Doesn't build on WIN32
LOADABLE_LIBRARY_HOST = Cap5
@@ -52,10 +65,11 @@ endif
endif
endif
endif
+endif
Cap5_SRCS = Cap5.xs
Cap5_LIBS = ca Com
-Cap5_INCLUDES = -I$(shell $(PERL) ../perlConfig.pl archlib)/CORE
+Cap5_INCLUDES = -I$(PERL_ARCHLIB)/CORE
Cap5_CFLAGS = $(shell $(PERL) ../perlConfig.pl ccflags)
CLEANS += Cap5.c
From 736075daf6507c847c7ea90b2cf21342fecc832e Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Fri, 1 Feb 2019 16:49:11 -0600
Subject: [PATCH 08/30] Document macOS Mojave fix
---
documentation/RELEASE_NOTES.html | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 4e317c84d..c47dc2d5b 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -16,6 +16,15 @@
+Perl CA bindings fixed for macOS Mojave
+
+Apple removed some Perl header files from macOS Mojave that were available
+in their SDK, requiring a change to the include paths used when compiling the
+CA bindings. The new version should build on new and older macOS versions, and
+these changes may also help other targets that have an incomplete installation
+of Perl (the build will continue after printing a warning that the Perl CA
+bindings could not be built).
+
Routine epicsTempName() removed from libCom
This routine was a simple wrapper around the C89 function tmpnam()
From 62c11c22c98e4883307cea741a693a13a527d203 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Sat, 2 Feb 2019 15:34:19 -0800
Subject: [PATCH 09/30] RPRO/PUTF also handle self link case
---
modules/database/src/ioc/db/dbDbLink.c | 4 ++--
modules/database/test/std/rec/asyncproctest.c | 18 +++++++++++++++++-
modules/database/test/std/rec/asyncproctest.db | 8 ++++++++
3 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/modules/database/src/ioc/db/dbDbLink.c b/modules/database/src/ioc/db/dbDbLink.c
index d53e1568c..74f522fbd 100644
--- a/modules/database/src/ioc/db/dbDbLink.c
+++ b/modules/database/src/ioc/db/dbDbLink.c
@@ -387,7 +387,7 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
char context[40] = "";
int trace = dbAccessDebugPUTF && *dbLockSetAddrTrace(psrc);
int srcset = dbRec2Pvt(psrc)->procThread==NULL;
- int dstset = dbRec2Pvt(pdst)->procThread==NULL;
+ int dstset = psrc!=pdst && dbRec2Pvt(pdst)->procThread==NULL;
long status;
epicsUInt8 pact = psrc->pact;
epicsThreadId self = epicsThreadGetIdSelf();
@@ -411,7 +411,7 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
pdst->putf = psrc->putf;
}
- else if (psrc->putf && dbRec2Pvt(pdst)->procThread!=self) {
+ else if (psrc->putf && dstset) {
/* The dst record is busy (awaiting async reprocessing),
* not being processed recursively by us, and
* we were originally triggered by a call to dbPutField(),
diff --git a/modules/database/test/std/rec/asyncproctest.c b/modules/database/test/std/rec/asyncproctest.c
index b10bcac68..7b8fca782 100644
--- a/modules/database/test/std/rec/asyncproctest.c
+++ b/modules/database/test/std/rec/asyncproctest.c
@@ -40,7 +40,7 @@ void asyncproctest_registerRecordDeviceDriver(struct dbBase *);
MAIN(asyncproctest)
{
- testPlan(25);
+ testPlan(27);
done = epicsEventMustCreate(epicsEventEmpty);
@@ -125,6 +125,22 @@ MAIN(asyncproctest)
testdbGetFieldEqual("chain4_lim", DBF_SHORT, 1);
}
+ testDiag("===== Chain 5 ======");
+
+ {
+ dbCommon *dummy=testdbRecordPtr("chain4_dummy");
+
+ testdbPutFieldOk("chain5_cnt.PROC", DBF_LONG, 0);
+
+ /* sync once queue to wait for any queued RPRO */
+ scanOnceCallback(dummy, dummydone, NULL);
+
+ if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK)
+ testAbort("Processing timed out");
+
+ testdbGetFieldEqual("chain5_cnt", DBF_SHORT, 1);
+ }
+
testIocShutdownOk();
testdbCleanup();
diff --git a/modules/database/test/std/rec/asyncproctest.db b/modules/database/test/std/rec/asyncproctest.db
index 4f8a97522..021506512 100644
--- a/modules/database/test/std/rec/asyncproctest.db
+++ b/modules/database/test/std/rec/asyncproctest.db
@@ -80,3 +80,11 @@ record(calc,"chain4_lim") {
record(bo, "chain4_dummy") {
field(TPRO, "$(TPRO=)")
}
+
+# loop breaking regression part 2
+# selft link should _not_ RPRO
+record(calcout,"chain5_cnt") {
+ field(CALC, "E:=E+1;E")
+ field(OUT,"chain5_cnt.A PP")
+ field(TPRO, "$(TPRO=)")
+}
From d3feb1e2f910b127285a90d49d503fa869c23f94 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Mon, 4 Feb 2019 16:35:44 -0800
Subject: [PATCH 10/30] RPRO/PUTF rename
---
modules/database/src/ioc/db/dbDbLink.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/modules/database/src/ioc/db/dbDbLink.c b/modules/database/src/ioc/db/dbDbLink.c
index 74f522fbd..e5a686984 100644
--- a/modules/database/src/ioc/db/dbDbLink.c
+++ b/modules/database/src/ioc/db/dbDbLink.c
@@ -386,8 +386,8 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
{
char context[40] = "";
int trace = dbAccessDebugPUTF && *dbLockSetAddrTrace(psrc);
- int srcset = dbRec2Pvt(psrc)->procThread==NULL;
- int dstset = psrc!=pdst && dbRec2Pvt(pdst)->procThread==NULL;
+ int claim_src = dbRec2Pvt(psrc)->procThread==NULL;
+ int claim_dst = psrc!=pdst && dbRec2Pvt(pdst)->procThread==NULL;
long status;
epicsUInt8 pact = psrc->pact;
epicsThreadId self = epicsThreadGetIdSelf();
@@ -411,7 +411,7 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
pdst->putf = psrc->putf;
}
- else if (psrc->putf && dstset) {
+ else if (psrc->putf && claim_dst) {
/* The dst record is busy (awaiting async reprocessing),
* not being processed recursively by us, and
* we were originally triggered by a call to dbPutField(),
@@ -434,12 +434,12 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
context, psrc->name, pdst->name);
}
- if(srcset) {
+ if(claim_src) {
dbRec2Pvt(psrc)->procThread = self;
} else {
assert(dbRec2Pvt(psrc)->procThread==self);
}
- if(dstset) {
+ if(claim_dst) {
dbRec2Pvt(pdst)->procThread = self;
} else {
assert(dbRec2Pvt(psrc)->procThread==self);
@@ -451,10 +451,10 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
assert(dbRec2Pvt(psrc)->procThread==self);
assert(dbRec2Pvt(pdst)->procThread==self);
- if(srcset) {
+ if(claim_src) {
dbRec2Pvt(psrc)->procThread = NULL;
}
- if(dstset) {
+ if(claim_dst) {
dbRec2Pvt(pdst)->procThread = NULL;
}
From 688f32cff03979e7002d7dacddfb006ae75c8005 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Mon, 4 Feb 2019 16:42:15 -0800
Subject: [PATCH 11/30] RPRO/PUTF test all three link types
Shouldn't be any difference, but check IN_LINK
and FWD_LINK to be sure.
---
modules/database/test/std/rec/asyncproctest.db | 3 +++
1 file changed, 3 insertions(+)
diff --git a/modules/database/test/std/rec/asyncproctest.db b/modules/database/test/std/rec/asyncproctest.db
index 021506512..87fe5d63d 100644
--- a/modules/database/test/std/rec/asyncproctest.db
+++ b/modules/database/test/std/rec/asyncproctest.db
@@ -74,6 +74,7 @@ record(calc,"chain4_lim") {
field(INPA,"chain4_pos PP")
field(INPB,"chain4_pos.HIGH PP")
field(INPC,"chain4_pos.LOW PP")
+ field(FLNK,"chain4_pos")
field(TPRO, "$(TPRO=)")
}
@@ -85,6 +86,8 @@ field(TPRO, "$(TPRO=)")
# selft link should _not_ RPRO
record(calcout,"chain5_cnt") {
field(CALC, "E:=E+1;E")
+ field(INPA,"chain5_cnt.A PP")
field(OUT,"chain5_cnt.A PP")
+ field(FLNK,"chain5_cnt")
field(TPRO, "$(TPRO=)")
}
From 8c3c5a9731887c6d8b1918394090564af38461b5 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Mon, 11 Mar 2019 16:00:54 -0500
Subject: [PATCH 12/30] Restore the -flat_namespace linker flag on macOS
Latest versions of Apple XCode require it.
---
configure/os/CONFIG.darwinCommon.darwinCommon | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure/os/CONFIG.darwinCommon.darwinCommon b/configure/os/CONFIG.darwinCommon.darwinCommon
index 4a8f3ef8e..bfd61830d 100644
--- a/configure/os/CONFIG.darwinCommon.darwinCommon
+++ b/configure/os/CONFIG.darwinCommon.darwinCommon
@@ -65,7 +65,7 @@ GNU = NO
#
# Darwin shared libraries
#
-SHRLIB_LDFLAGS = -dynamiclib -undefined dynamic_lookup \
+SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined dynamic_lookup \
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
$(addprefix -compatibility_version , $(SHRLIB_VERSION)) \
$(addprefix -current_version , $(SHRLIB_VERSION))
From d1149a0ba90096b3aa2890029ed9a430216d96ec Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Mon, 11 Mar 2019 16:50:40 -0700
Subject: [PATCH 13/30] iocsh epicsMutexShowAll accepts 2 arguments
---
modules/libcom/src/iocsh/libComRegister.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/libcom/src/iocsh/libComRegister.c b/modules/libcom/src/iocsh/libComRegister.c
index 737d7e9c2..b105ea12f 100644
--- a/modules/libcom/src/iocsh/libComRegister.c
+++ b/modules/libcom/src/iocsh/libComRegister.c
@@ -319,7 +319,7 @@ static const iocshArg epicsMutexShowAllArg1 = { "level",iocshArgInt};
static const iocshArg * const epicsMutexShowAllArgs[2] =
{&epicsMutexShowAllArg0,&epicsMutexShowAllArg1};
static const iocshFuncDef epicsMutexShowAllFuncDef =
- {"epicsMutexShowAll",1,epicsMutexShowAllArgs};
+ {"epicsMutexShowAll",2,epicsMutexShowAllArgs};
static void epicsMutexShowAllCallFunc(const iocshArgBuf *args)
{
epicsMutexShowAll(args[0].ival,args[1].ival);
From c93ec231a2b2f13b74f950f39307df9413d0a990 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Mon, 11 Mar 2019 19:45:37 -0700
Subject: [PATCH 14/30] update PVD and PVA
---
modules/pvAccess | 2 +-
modules/pvData | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/pvAccess b/modules/pvAccess
index 5e7934221..663146f2e 160000
--- a/modules/pvAccess
+++ b/modules/pvAccess
@@ -1 +1 @@
-Subproject commit 5e793422198d4223a03164787cacbfb6cf9575fc
+Subproject commit 663146f2e76c26a7b8a3b419e790692295ea02a0
diff --git a/modules/pvData b/modules/pvData
index d776f6eaf..643f289c2 160000
--- a/modules/pvData
+++ b/modules/pvData
@@ -1 +1 @@
-Subproject commit d776f6eaf03c058597c05b3308636d95223b6c6e
+Subproject commit 643f289c23729016f420748fea4180c3153c0b7c
From 0f75e0aa7fc8d5219c95855c0cd52a24be1d2c35 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Wed, 13 Mar 2019 17:57:41 -0700
Subject: [PATCH 15/30] RPRO/PUTF log instead of assert()
---
modules/database/src/ioc/db/dbDbLink.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/modules/database/src/ioc/db/dbDbLink.c b/modules/database/src/ioc/db/dbDbLink.c
index e5a686984..0da927139 100644
--- a/modules/database/src/ioc/db/dbDbLink.c
+++ b/modules/database/src/ioc/db/dbDbLink.c
@@ -436,21 +436,27 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
if(claim_src) {
dbRec2Pvt(psrc)->procThread = self;
- } else {
- assert(dbRec2Pvt(psrc)->procThread==self);
}
if(claim_dst) {
dbRec2Pvt(pdst)->procThread = self;
- } else {
- assert(dbRec2Pvt(psrc)->procThread==self);
+ }
+
+ if(dbRec2Pvt(psrc)->procThread!=self ||
+ dbRec2Pvt(pdst)->procThread!=self) {
+ errlogPrintf("Logic Error: processTarget 1 from %p, %s(%p) -> %s(%p)\n",
+ self, psrc->name, dbRec2Pvt(psrc), pdst->name, dbRec2Pvt(pdst));
}
status = dbProcess(pdst);
psrc->pact = pact;
- assert(dbRec2Pvt(psrc)->procThread==self);
- assert(dbRec2Pvt(pdst)->procThread==self);
+ if(dbRec2Pvt(psrc)->procThread!=self ||
+ dbRec2Pvt(pdst)->procThread!=self) {
+ errlogPrintf("Logic Error: processTarget 2 from %p, %s(%p) -> %s(%p)\n",
+ self, psrc->name, dbRec2Pvt(psrc), pdst->name, dbRec2Pvt(pdst));
+ }
+
if(claim_src) {
dbRec2Pvt(psrc)->procThread = NULL;
}
From 394c39da51c7cea144a110d7d92264685d089c9d Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Wed, 13 Mar 2019 18:17:57 -0700
Subject: [PATCH 16/30] update release notes
---
documentation/RELEASE_NOTES.html | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index f056d3b16..765b6ba53 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -21,7 +21,7 @@ which should also be read to understand what has changed since an earlier
release.
-EPICS Release 7.0.3
+EPICS Release 7.0.2.1
+Fix DB_LINK loop breaking
+
+A regression was introduced in 7.0.2 which caused record chains with
+loops to be incorrectly broken. Processing should be skipped when a
+DB_LINK with Process Passive (PP) closes a loop to a synchronous record.
+
+Instead in 7.0.2 the targeted record would be processed if processing began with
+a remote action (or other caller of dbPutField() ). The would result in the loop
+running a second time. The loop would be broken on the second iteration.
+
+See lp #1809570
+
Old dbStaticLib APIs removed
Support for some obsolete dbStaticLib Database Configuration Tool (DCT) APIs
From 511a541f31f2efd9a7b56a359ef522f6ff637dd5 Mon Sep 17 00:00:00 2001
From: till straumann
Date: Thu, 14 Mar 2019 10:36:55 -0700
Subject: [PATCH 17/30] stripped-down fix for 1816841 only
---
modules/libcom/src/osi/os/posix/osdThread.c | 13 ++-
modules/libcom/test/Makefile | 11 ++
.../test/nonEpicsThreadPriorityTest.cpp | 100 ++++++++++++++++++
3 files changed, 117 insertions(+), 7 deletions(-)
create mode 100644 modules/libcom/test/nonEpicsThreadPriorityTest.cpp
diff --git a/modules/libcom/src/osi/os/posix/osdThread.c b/modules/libcom/src/osi/os/posix/osdThread.c
index c08dea40e..854441898 100644
--- a/modules/libcom/src/osi/os/posix/osdThread.c
+++ b/modules/libcom/src/osi/os/posix/osdThread.c
@@ -567,14 +567,13 @@ static epicsThreadOSD *createImplicit(void)
pthreadInfo->osiPriority = 0;
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0
- {
- struct sched_param param;
- int policy;
- if(pthread_getschedparam(tid,&policy,¶m) == 0)
- pthreadInfo->osiPriority =
- (param.sched_priority - pcommonAttr->minPriority) * 100.0 /
+ if(pthread_getschedparam(tid,&pthreadInfo->schedPolicy,&pthreadInfo->schedParam) == 0) {
+ if ( pcommonAttr->usePolicy && pthreadInfo->schedPolicy == pcommonAttr->schedPolicy ) {
+ pthreadInfo->osiPriority =
+ (pthreadInfo->schedParam.sched_priority - pcommonAttr->minPriority) * 100.0 /
(pcommonAttr->maxPriority - pcommonAttr->minPriority + 1);
- }
+ }
+ }
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);
diff --git a/modules/libcom/test/Makefile b/modules/libcom/test/Makefile
index 1c26c44b7..e3d1820f6 100755
--- a/modules/libcom/test/Makefile
+++ b/modules/libcom/test/Makefile
@@ -288,4 +288,15 @@ TESTPROD_HOST += cvtFastPerform
cvtFastPerform_SRCS += cvtFastPerform.cpp
testHarness_SRCS += cvtFastPerform.cpp
+ifeq ($(POSIX),YES)
+ifeq ($(USE_POSIX_THREAD_PRIORITY_SCHEDULING),YES)
+TESTPROD_HOST += nonEpicsThreadPriorityTest
+nonEpicsThreadPriorityTest_SRCS += nonEpicsThreadPriorityTest.cpp
+nonEpicsThreadPriorityTest_SYS_LIBS += pthread rt
+testHarness_SRCS += nonEpicsThreadPriorityTest.cpp
+epicsRunLibComTests_CFLAGS += -DHAVE_PTHREAD_PRIORITY_SCHEDULING
+TESTS += nonEpicsThreadPriorityTest
+endif
+endif
+
include $(TOP)/configure/RULES
diff --git a/modules/libcom/test/nonEpicsThreadPriorityTest.cpp b/modules/libcom/test/nonEpicsThreadPriorityTest.cpp
new file mode 100644
index 000000000..088f0fca7
--- /dev/null
+++ b/modules/libcom/test/nonEpicsThreadPriorityTest.cpp
@@ -0,0 +1,100 @@
+#include
+#include "epicsUnitTest.h"
+#include "testMain.h"
+#include
+#include
+
+#ifdef __rtems__
+
+/* RTEMS is posix but currently does not use the pthread API */
+MAIN(nonEpicsThreadPriorityTest)
+{
+ testPlan(1);
+ testSkip(1, "Platform does not use pthread API");
+ return testDone();
+}
+
+#else
+
+static void *nonEpicsTestFunc(void *arg)
+{
+ unsigned int pri;
+ // epicsThreadGetIdSelf() creates an EPICS context
+ // verify that the priority computed by epics context
+ // is OK
+ pri = epicsThreadGetPriority( epicsThreadGetIdSelf() );
+ if ( ! testOk( 0 == pri, "'createImplicit' assigned correct priority (%d) to non-EPICS thread", pri) ) {
+ return 0;
+ }
+
+ return (void*)1;
+}
+
+
+static void testFunc(void *arg)
+{
+ epicsEventId ev = (epicsEventId)arg;
+ int policy;
+ struct sched_param param;
+ int status;
+ pthread_t tid;
+ void *rval;
+ pthread_attr_t attr;
+
+ status = pthread_getschedparam(pthread_self(), &policy,¶m);
+ if ( status ) {
+ testSkip(1, "pthread_getschedparam failed");
+ goto done;
+ }
+
+ if ( SCHED_FIFO != policy ) {
+ testSkip(1, "nonEpicsThreadPriorityTest must be executed with privileges to use SCHED_FIFO");
+ goto done;
+ }
+
+ if ( pthread_attr_init( &attr ) ) {
+ testSkip(1, "pthread_attr_init failed");
+ goto done;
+ }
+ if ( pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ) ) {
+ testSkip(1, "pthread_attr_setinheritsched failed");
+ goto done;
+ }
+ if ( pthread_attr_setschedpolicy ( &attr, SCHED_OTHER ) ) {
+ testSkip(1, "pthread_attr_setschedpolicy failed");
+ goto done;
+ }
+ param.sched_priority = 0;
+ if ( pthread_attr_setschedparam ( &attr, ¶m ) ) {
+ testSkip(1, "pthread_attr_setschedparam failed");
+ goto done;
+ }
+
+ if ( pthread_create( &tid, &attr, nonEpicsTestFunc, 0 ) ) {
+ testSkip(1, "pthread_create failed");
+ goto done;
+ }
+
+ if ( pthread_join( tid, &rval ) ) {
+ testSkip(1, "pthread_join failed");
+ goto done;
+ }
+
+done:
+
+ epicsEventSignal( ev );
+}
+
+MAIN(nonEpicsThreadPriorityTest)
+{
+ testPlan(2);
+ epicsEventId testComplete = epicsEventMustCreate(epicsEventEmpty);
+ epicsThreadMustCreate("nonEpicsThreadPriorityTest", epicsThreadPriorityLow,
+ epicsThreadGetStackSize(epicsThreadStackMedium),
+ testFunc, testComplete);
+ epicsEventWaitStatus status = epicsEventWait(testComplete);
+ testOk(status == epicsEventWaitOK,
+ "epicsEventWait returned %d", status);
+ return testDone();
+}
+#endif
From 7f55bb0386bc04d89381f48cd8fb834558b8dee2 Mon Sep 17 00:00:00 2001
From: till straumann
Date: Thu, 14 Mar 2019 11:47:52 -0700
Subject: [PATCH 18/30] Another hack to deal with RTEMS which is POSIX but
still different
---
modules/libcom/test/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/libcom/test/Makefile b/modules/libcom/test/Makefile
index e3d1820f6..130c23512 100755
--- a/modules/libcom/test/Makefile
+++ b/modules/libcom/test/Makefile
@@ -292,7 +292,7 @@ ifeq ($(POSIX),YES)
ifeq ($(USE_POSIX_THREAD_PRIORITY_SCHEDULING),YES)
TESTPROD_HOST += nonEpicsThreadPriorityTest
nonEpicsThreadPriorityTest_SRCS += nonEpicsThreadPriorityTest.cpp
-nonEpicsThreadPriorityTest_SYS_LIBS += pthread rt
+nonEpicsThreadPriorityTest_SYS_LIBS += $(POSIX_LDLIBS:-l%=%)
testHarness_SRCS += nonEpicsThreadPriorityTest.cpp
epicsRunLibComTests_CFLAGS += -DHAVE_PTHREAD_PRIORITY_SCHEDULING
TESTS += nonEpicsThreadPriorityTest
From 1d2637a04efffcaf2ad12d3b517d71c3bfd5e308 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Mon, 18 Mar 2019 11:58:02 -0700
Subject: [PATCH 19/30] update submodules
---
modules/normativeTypes | 2 +-
modules/pvAccess | 2 +-
modules/pvData | 2 +-
modules/pvDatabase | 2 +-
modules/pva2pva | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/modules/normativeTypes b/modules/normativeTypes
index 41d56fdf8..54c07f705 160000
--- a/modules/normativeTypes
+++ b/modules/normativeTypes
@@ -1 +1 @@
-Subproject commit 41d56fdf89a09617f2d5fe726fa0ecb579ca551f
+Subproject commit 54c07f705ff7332e94d75208f1895af370eb7d9d
diff --git a/modules/pvAccess b/modules/pvAccess
index 663146f2e..78410499f 160000
--- a/modules/pvAccess
+++ b/modules/pvAccess
@@ -1 +1 @@
-Subproject commit 663146f2e76c26a7b8a3b419e790692295ea02a0
+Subproject commit 78410499f0236f5830a0937567bbb794de7b2347
diff --git a/modules/pvData b/modules/pvData
index 643f289c2..8c275cbc1 160000
--- a/modules/pvData
+++ b/modules/pvData
@@ -1 +1 @@
-Subproject commit 643f289c23729016f420748fea4180c3153c0b7c
+Subproject commit 8c275cbc1caca1f6175b75b6f0ffc2d4abc234db
diff --git a/modules/pvDatabase b/modules/pvDatabase
index 07a951c3a..68cc5e3b2 160000
--- a/modules/pvDatabase
+++ b/modules/pvDatabase
@@ -1 +1 @@
-Subproject commit 07a951c3a2bd3e95b1de24e3224e310225e3e45a
+Subproject commit 68cc5e3b28664688f3ba197cb367dcd1703f53d8
diff --git a/modules/pva2pva b/modules/pva2pva
index a245adb5c..521154fd5 160000
--- a/modules/pva2pva
+++ b/modules/pva2pva
@@ -1 +1 @@
-Subproject commit a245adb5cfc9b4a0b0d04b630032963ecc3410d0
+Subproject commit 521154fd52d149ea578a73cabc1f7e4c784cf14f
From 89da4130fc4b2dbf2ae9a37a7091f230c18196ec Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Mon, 18 Mar 2019 13:49:25 -0700
Subject: [PATCH 20/30] make-tar.sh allow HEAD for testing
---
.tools/make-tar.sh | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/.tools/make-tar.sh b/.tools/make-tar.sh
index ff78a23cd..4c9c33a7b 100755
--- a/.tools/make-tar.sh
+++ b/.tools/make-tar.sh
@@ -36,7 +36,10 @@ case "$PREFIX" in
esac
# Check for both and R
-if ! [ `git tag -l $TOPREV` ]
+if [ "$TOPREV" = "HEAD" ]
+then
+ true
+elif ! [ `git tag -l $TOPREV` ]
then
if [ `git tag -l R$TOPREV` ]
then
From cde682f7baf67fe6eebe02100461cc5d1f05e1ab Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Mon, 18 Mar 2019 16:08:20 -0700
Subject: [PATCH 21/30] nonEpicsThreadPriorityTest is Linux only
---
modules/libcom/test/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/libcom/test/Makefile b/modules/libcom/test/Makefile
index 130c23512..f2e495a90 100755
--- a/modules/libcom/test/Makefile
+++ b/modules/libcom/test/Makefile
@@ -288,7 +288,7 @@ TESTPROD_HOST += cvtFastPerform
cvtFastPerform_SRCS += cvtFastPerform.cpp
testHarness_SRCS += cvtFastPerform.cpp
-ifeq ($(POSIX),YES)
+ifeq ($(OS_CLASS),Linux)
ifeq ($(USE_POSIX_THREAD_PRIORITY_SCHEDULING),YES)
TESTPROD_HOST += nonEpicsThreadPriorityTest
nonEpicsThreadPriorityTest_SRCS += nonEpicsThreadPriorityTest.cpp
From 638391249ddddb120001dfa3d52251176a9e9093 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 20 Mar 2019 13:44:02 -0500
Subject: [PATCH 22/30] Update EPICS_TIMEZONE settings in CONFIG_SITE_ENV
Deleted 2018, added 2023.
---
configure/CONFIG_SITE_ENV | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/configure/CONFIG_SITE_ENV b/configure/CONFIG_SITE_ENV
index 3bdb94b15..5bf4960f7 100644
--- a/configure/CONFIG_SITE_ENV
+++ b/configure/CONFIG_SITE_ENV
@@ -34,14 +34,9 @@
# The future dates below assume the rules don't get changed;
# see http://www.timeanddate.com/time/dst/2018.html to check.
#
-# DST for 2018 US: Mar 11 - Nov 04
-# EU: Mar 25 - Oct 28
-EPICS_TIMEZONE = CUS::360:031102:110402
-#EPICS_TIMEZONE = MET::-60:032502:102803
-#
# DST for 2019 US: Mar 10 - Nov 03
# EU: Mar 31 - Oct 27
-#EPICS_TIMEZONE = CUS::360:031002:110302
+EPICS_TIMEZONE = CUS::360:031002:110302
#EPICS_TIMEZONE = MET::-60:033102:102703
#
# DST for 2020 US: Mar 08 - Nov 01
@@ -58,6 +53,11 @@ EPICS_TIMEZONE = CUS::360:031102:110402
# EU: Mar 27 - Oct 30
#EPICS_TIMEZONE = CUS::360:031302:110602
#EPICS_TIMEZONE = MET::-60:032702:103003
+#
+# DST for 2023 US: Mar 13 - Nov 06
+# EU: Mar 27 - Oct 30
+#EPICS_TIMEZONE = CUS::360:031202:110502
+#EPICS_TIMEZONE = MET::-60:032602:102903
# EPICS_TS_NTP_INET
# NTP time server ip address for VxWorks and RTEMS.
From 592b935146edddc568832bde41567d13fb2630b3 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 20 Mar 2019 13:46:47 -0500
Subject: [PATCH 23/30] Document the macOS -flat_namespace flag change
---
documentation/RELEASE_NOTES.html | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 765b6ba53..ab6914ccc 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -23,25 +23,25 @@ release.
EPICS Release 7.0.2.1
-
+The linker flag -flat_namespace has been restored for creating
+shared libraries, although not for loadable libraries (bundles). This was
+required for building using the latest versions of Apple XCode.
Fix DB_LINK loop breaking
-A regression was introduced in 7.0.2 which caused record chains with
-loops to be incorrectly broken. Processing should be skipped when a
-DB_LINK with Process Passive (PP) closes a loop to a synchronous record.
+A regression was introduced in 7.0.2 which caused record chains with loops to
+be incorrectly broken. Processing should be skipped when a DB_LINK with Process
+Passive (PP) closes a loop to a synchronous record.
-Instead in 7.0.2 the targeted record would be processed if processing began with
-a remote action (or other caller of dbPutField() ). The would result in the loop
-running a second time. The loop would be broken on the second iteration.
+Instead in 7.0.2 the targeted record would be processed if processing began
+with a remote action (or some other caller of dbPutField()). This would
+result in the loop running a second time. The loop would be broken on the second
+iteration.
-See lp #1809570
+See lp:
+#1809570
Old dbStaticLib APIs removed
From 9a062cd6a134396f34eed32e7947a21f86f1c675 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 20 Mar 2019 15:16:55 -0500
Subject: [PATCH 24/30] Update submodules
---
modules/normativeTypes | 2 +-
modules/pvDatabase | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/normativeTypes b/modules/normativeTypes
index 54c07f705..e803240fb 160000
--- a/modules/normativeTypes
+++ b/modules/normativeTypes
@@ -1 +1 @@
-Subproject commit 54c07f705ff7332e94d75208f1895af370eb7d9d
+Subproject commit e803240fbfbb06d96d94fc70e91b4cf832811b15
diff --git a/modules/pvDatabase b/modules/pvDatabase
index 68cc5e3b2..b3f96f730 160000
--- a/modules/pvDatabase
+++ b/modules/pvDatabase
@@ -1 +1 @@
-Subproject commit 68cc5e3b28664688f3ba197cb367dcd1703f53d8
+Subproject commit b3f96f730fcf1b07a24125fd06b8c413a1e93b5d
From a5b3157ec1057292bdc229673bd28d7603e8122e Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 20 Mar 2019 15:18:05 -0500
Subject: [PATCH 25/30] Update version numbers for libcom and database
---
modules/database/configure/CONFIG_DATABASE_VERSION | 2 +-
modules/libcom/configure/CONFIG_LIBCOM_VERSION | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/database/configure/CONFIG_DATABASE_VERSION b/modules/database/configure/CONFIG_DATABASE_VERSION
index 63ad9cd4c..4b6ef8a6b 100644
--- a/modules/database/configure/CONFIG_DATABASE_VERSION
+++ b/modules/database/configure/CONFIG_DATABASE_VERSION
@@ -1,4 +1,4 @@
EPICS_DATABASE_MAJOR_VERSION = 3
EPICS_DATABASE_MINOR_VERSION = 17
-EPICS_DATABASE_MAINTENANCE_VERSION = 2
+EPICS_DATABASE_MAINTENANCE_VERSION = 3
EPICS_DATABASE_DEVELOPMENT_FLAG = 0
diff --git a/modules/libcom/configure/CONFIG_LIBCOM_VERSION b/modules/libcom/configure/CONFIG_LIBCOM_VERSION
index 668c4fe1b..5a21198ff 100644
--- a/modules/libcom/configure/CONFIG_LIBCOM_VERSION
+++ b/modules/libcom/configure/CONFIG_LIBCOM_VERSION
@@ -1,4 +1,4 @@
EPICS_LIBCOM_MAJOR_VERSION = 3
EPICS_LIBCOM_MINOR_VERSION = 17
-EPICS_LIBCOM_MAINTENANCE_VERSION = 2
+EPICS_LIBCOM_MAINTENANCE_VERSION = 3
EPICS_LIBCOM_DEVELOPMENT_FLAG = 0
From 72be690fec6cfab4dc02460f6cc1627e1a83e6cd Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 20 Mar 2019 15:24:51 -0500
Subject: [PATCH 26/30] Set Base version to 7.0.2.1 (final)
---
configure/CONFIG_BASE_VERSION | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION
index 715fc168c..dc0466d36 100644
--- a/configure/CONFIG_BASE_VERSION
+++ b/configure/CONFIG_BASE_VERSION
@@ -52,10 +52,10 @@ EPICS_MODIFICATION = 2
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
# Not included if zero
-EPICS_PATCH_LEVEL = 0
+EPICS_PATCH_LEVEL = 1
# This will end in -DEV between official releases
-EPICS_DEV_SNAPSHOT=-DEV
+#EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-pre1-DEV
#EPICS_DEV_SNAPSHOT=-pre2
@@ -64,7 +64,7 @@ EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-rc1-DEV
#EPICS_DEV_SNAPSHOT=-rc2
#EPICS_DEV_SNAPSHOT=-rc2-DEV
-#EPICS_DEV_SNAPSHOT=
+EPICS_DEV_SNAPSHOT=
# No changes should be needed below here
From 7fe8373c32b3aecfc278fd42a4510296ab8c5e8d Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 20 Mar 2019 15:28:37 -0500
Subject: [PATCH 27/30] Changes after creating the 7.0.2.1 tag
---
configure/CONFIG_BASE_VERSION | 4 ++--
documentation/RELEASE_NOTES.html | 12 +++++++++++-
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION
index dc0466d36..050721029 100644
--- a/configure/CONFIG_BASE_VERSION
+++ b/configure/CONFIG_BASE_VERSION
@@ -55,7 +55,7 @@ EPICS_MODIFICATION = 2
EPICS_PATCH_LEVEL = 1
# This will end in -DEV between official releases
-#EPICS_DEV_SNAPSHOT=-DEV
+EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-pre1-DEV
#EPICS_DEV_SNAPSHOT=-pre2
@@ -64,7 +64,7 @@ EPICS_PATCH_LEVEL = 1
#EPICS_DEV_SNAPSHOT=-rc1-DEV
#EPICS_DEV_SNAPSHOT=-rc2
#EPICS_DEV_SNAPSHOT=-rc2-DEV
-EPICS_DEV_SNAPSHOT=
+#EPICS_DEV_SNAPSHOT=
# No changes should be needed below here
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index ab6914ccc..27670a17e 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -20,12 +20,22 @@ release.
which should also be read to understand what has changed since an earlier
release.
+EPICS Release 7.0.2.2
+
+
+
EPICS Release 7.0.2.1
Linking shared libraries on macOS
-The linker flag -flat_namespace has been restored for creating
+
The linker flag -flat_namespace has been restored for creating
shared libraries, although not for loadable libraries (bundles). This was
required for building using the latest versions of Apple XCode.
From bad8b25e4ed6ee8135d03cdcf663b34b7c541497 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 20 Mar 2019 11:57:54 -0500
Subject: [PATCH 28/30] Prevent submodules from cleaning the
EPICS_BASE/configure directory
---
configure/RULES_TOP | 2 ++
1 file changed, 2 insertions(+)
diff --git a/configure/RULES_TOP b/configure/RULES_TOP
index b18fbf026..bd844e76f 100644
--- a/configure/RULES_TOP
+++ b/configure/RULES_TOP
@@ -26,8 +26,10 @@ realuninstall: uninstallDirs
UNINSTALL_DIRS += $(INSTALL_DBD) $(INSTALL_INCLUDE) $(INSTALL_DOC) \
$(INSTALL_HTML) $(INSTALL_TEMPLATES) $(INSTALL_DB) $(DIRECTORY_TARGETS)
ifneq ($(INSTALL_LOCATION),$(TOP))
+ifneq ($(INSTALL_LOCATION),$(EPICS_BASE))
UNINSTALL_DIRS += $(INSTALL_CONFIG)
endif
+endif
uninstallDirs:
$(RMDIR) $(UNINSTALL_DIRS)
From 597393a8eeb0d41dd07fd0170672c2a95156cf12 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Mon, 25 Mar 2019 14:07:58 -0700
Subject: [PATCH 29/30] libCom: drop CLOCK_MONOTONIC_RAW
Turns out this is ~10x slower to query than CLOCK_MONOTONIC
---
modules/libcom/src/osi/os/posix/osdMonotonic.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/modules/libcom/src/osi/os/posix/osdMonotonic.c b/modules/libcom/src/osi/os/posix/osdMonotonic.c
index 00c9c2871..65585797c 100644
--- a/modules/libcom/src/osi/os/posix/osdMonotonic.c
+++ b/modules/libcom/src/osi/os/posix/osdMonotonic.c
@@ -18,9 +18,6 @@ void osdMonotonicInit(void)
{
unsigned i;
clockid_t ids[] = {
-#ifdef CLOCK_MONOTONIC_RAW
- CLOCK_MONOTONIC_RAW, /* Linux specific */
-#endif
#ifdef CLOCK_HIGHRES
CLOCK_HIGHRES, /* solaris specific */
#endif
From 2a14647eec059adf9440a91e731bf7fe4df796a3 Mon Sep 17 00:00:00 2001
From: Ralph Lange
Date: Thu, 28 Mar 2019 16:43:50 -0700
Subject: [PATCH 30/30] Change -DEV to be based on next patch release number
---
configure/CONFIG_BASE_VERSION | 7 ++++---
documentation/ReleaseChecklist.html | 23 +++++++++++++++++++++++
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION
index 050721029..e55ee5d33 100644
--- a/configure/CONFIG_BASE_VERSION
+++ b/configure/CONFIG_BASE_VERSION
@@ -52,9 +52,11 @@ EPICS_MODIFICATION = 2
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
# Not included if zero
-EPICS_PATCH_LEVEL = 1
+EPICS_PATCH_LEVEL = 2
-# This will end in -DEV between official releases
+# Between official releases, the EPICS_PATCH_LEVEL gets incremented
+# and a -DEV suffix is added (similar to the Maven -SNAPSHOT versions)
+#EPICS_DEV_SNAPSHOT=
EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-pre1-DEV
@@ -64,7 +66,6 @@ EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-rc1-DEV
#EPICS_DEV_SNAPSHOT=-rc2
#EPICS_DEV_SNAPSHOT=-rc2-DEV
-#EPICS_DEV_SNAPSHOT=
# No changes should be needed below here
diff --git a/documentation/ReleaseChecklist.html b/documentation/ReleaseChecklist.html
index 18533f59d..cb95f7f60 100644
--- a/documentation/ReleaseChecklist.html
+++ b/documentation/ReleaseChecklist.html
@@ -37,6 +37,8 @@ that should be performed when creating production releases of EPICS Base.
The Release Process
+Full Process
+
The version released on the Feature Freeze date is designated the first
pre-release, -pre1. The first release candidate -rc1 is the
first version that has undergone testing by the developers and has shown no
@@ -49,6 +51,12 @@ release candidate has been available for 2 weeks without any new problems being
reported or major changes having to be committed, the final release can be
made.
+Short Process for Patch Releases
+
+The Patch Release date and its scope are agreed upon about four weeks
+ahead of time. If no blocking issues are raised, the release is made by the
+release manager.
+
Roles
The following roles are used below:
@@ -322,6 +330,21 @@ made.
+
+ | |
+ Release Manager |
+ Edit and commit changes to the EPICS Base version number file and
+ the embedded module version files:
+
+ - configure/CONFIG_BASE_VERSION
+ - modules/libcom/configure/CONFIG_LIBCOM_VERSION
+ - modules/ca/configure/CONFIG_CA_VERSION
+ - modules/database/configure/CONFIG_DATABASE_VERSION
+
+ Version numbers should be set to the next expected patch release,
+ with a "-DEV" tag added (where applicable).
+ |
+
| |
Release Manager |