diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 680641904..477e57be3 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -15,6 +15,18 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
A server layer that sits on top of the IOC database may now register itself +as such by calling dbRegisterServer() and providing optional routines +that other components can use. The initial purpose of this API allows the Trace +Processing implementation in dbProcess() to identify a client that +causes a record to process when TPRO is set.
+ +To support the client idenfication, the server provides a routine that +returns that identity string when called by one of its own processing +threads.
+A series of database definition (dbd) files can now be concatenated during
diff --git a/src/ioc/db/Makefile b/src/ioc/db/Makefile
index 8788207fe..74b37ce60 100644
--- a/src/ioc/db/Makefile
+++ b/src/ioc/db/Makefile
@@ -26,6 +26,7 @@ INC += dbLink.h
INC += dbLock.h
INC += dbNotify.h
INC += dbScan.h
+INC += dbServer.h
INC += dbTest.h
INC += dbCaTest.h
INC += db_test.h
@@ -88,3 +89,5 @@ dbCore_SRCS += dbIocRegister.c
dbCore_SRCS += chfPlugin.c
dbCore_SRCS += dbState.c
dbCore_SRCS += dbUnitTest.c
+dbCore_SRCS += dbServer.c
+
diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c
index 3a0e98bdb..c8e1a8f9b 100644
--- a/src/ioc/db/dbAccess.c
+++ b/src/ioc/db/dbAccess.c
@@ -59,6 +59,7 @@
#include "dbNotify.h"
#include "dbAccessDefs.h"
#include "recGbl.h"
+#include "dbServer.h"
epicsShareDef struct dbBase *pdbbase = 0;
epicsShareDef volatile int interruptAccept=FALSE;
@@ -454,6 +455,7 @@ long dbProcess(dbCommon *precord)
struct rset *prset = precord->rset;
dbRecordType *pdbRecordType = precord->rdes;
unsigned char tpro = precord->tpro;
+ char context[40] = "";
long status = 0;
int *ptrace;
int set_trace = FALSE;
@@ -484,23 +486,33 @@ long dbProcess(dbCommon *precord)
/* check for trace processing*/
if (tpro) {
- if(*ptrace==0) {
+ if (!*ptrace) {
*ptrace = 1;
set_trace = TRUE;
}
}
+ if (*ptrace) {
+ /* Identify this thread's client from server layer */
+ if (dbServerClient(context, sizeof(context))) {
+ /* No client, use thread name */
+ strncpy(context, epicsThreadGetNameSelf(), sizeof(context));
+ context[sizeof(context) - 1] = 0;
+ }
+ }
+
/* If already active dont process */
if (precord->pact) {
- unsigned short monitor_mask;
+ unsigned short monitor_mask;
if (*ptrace)
- printf("%s: Active %s\n",
- epicsThreadGetNameSelf(), precord->name);
+ printf("%s: Active %s\n", context, precord->name);
+
/* raise scan alarm after MAX_LOCK times */
- if (precord->stat==SCAN_ALARM) goto all_done;
- if (precord->lcnt++ !=MAX_LOCK) goto all_done;
- if (precord->sevr>=INVALID_ALARM) goto all_done;
+ if ((precord->stat == SCAN_ALARM) ||
+ (precord->lcnt++ < MAX_LOCK) ||
+ (precord->sevr >= INVALID_ALARM)) goto all_done;
+
recGblSetSevr(precord, SCAN_ALARM, INVALID_ALARM);
monitor_mask = recGblResetAlarms(precord);
monitor_mask |= DBE_VALUE|DBE_LOG;
@@ -510,7 +522,8 @@ long dbProcess(dbCommon *precord)
monitor_mask);
goto all_done;
}
- else precord->lcnt = 0;
+ else
+ precord->lcnt = 0;
/*
* Check the record disable link. A record will not be
@@ -521,9 +534,8 @@ long dbProcess(dbCommon *precord)
/* if disabled check disable alarm severity and return success */
if (precord->disa == precord->disv) {
- if(*ptrace)
- printf("%s: Disabled %s\n",
- epicsThreadGetNameSelf(), precord->name);
+ if (*ptrace)
+ printf("%s: Disabled %s\n", context, precord->name);
/*take care of caching and notifyCompletion*/
precord->rpro = FALSE;
@@ -531,7 +543,9 @@ long dbProcess(dbCommon *precord)
callNotifyCompletion = TRUE;
/* raise disable alarm */
- if (precord->stat==DISABLE_ALARM) goto all_done;
+ if (precord->stat == DISABLE_ALARM)
+ goto all_done;
+
precord->sevr = precord->diss;
precord->stat = DISABLE_ALARM;
precord->nsev = 0;
@@ -547,29 +561,34 @@ long dbProcess(dbCommon *precord)
/* locate record processing routine */
/* FIXME: put this in iocInit() !!! */
- if (!(prset=precord->rset) || !(prset->process)) {
+ if (!prset || !prset->process) {
callNotifyCompletion = TRUE;
- precord->pact=1;/*set pact TRUE so error is issued only once*/
+ precord->pact = 1;/*set pact so error is issued only once*/
recGblRecordError(S_db_noRSET, (void *)precord, "dbProcess");
status = S_db_noRSET;
if (*ptrace)
- printf("%s: No RSET for %s\n",
- epicsThreadGetNameSelf(), precord->name);
+ printf("%s: No RSET for %s\n", context, precord->name);
goto all_done;
}
- if(*ptrace)
- printf("%s: Process %s\n",
- epicsThreadGetNameSelf(), precord->name);
+
+ if (*ptrace)
+ printf("%s: Process %s\n", context, precord->name);
+
/* process record */
- status = (*prset->process)(precord);
+ status = prset->process(precord);
+
/* Print record's fields if PRINT_MASK set in breakpoint field */
if (lset_stack_count != 0) {
dbPrint(precord);
}
+
all_done:
- if (set_trace) *ptrace = 0;
- if(callNotifyCompletion && precord->ppn) dbNotifyCompletion(precord);
- return(status);
+ if (set_trace)
+ *ptrace = 0;
+ if (callNotifyCompletion && precord->ppn)
+ dbNotifyCompletion(precord);
+
+ return status;
}
/*
diff --git a/src/ioc/db/dbIocRegister.c b/src/ioc/db/dbIocRegister.c
index 0de2d7172..c07dcc730 100644
--- a/src/ioc/db/dbIocRegister.c
+++ b/src/ioc/db/dbIocRegister.c
@@ -18,6 +18,7 @@
#include "db_test.h"
#include "dbLock.h"
#include "dbScan.h"
+#include "dbServer.h"
#include "dbNotify.h"
#include "callback.h"
#include "dbIocRegister.h"
@@ -90,6 +91,12 @@ static const iocshArg * const dbapArgs[1] = {&dbapArg0};
static const iocshFuncDef dbapFuncDef = {"dbap",1,dbapArgs};
static void dbapCallFunc(const iocshArgBuf *args) { dbap(args[0].sval);}
+/* dbsr */
+static const iocshArg dbsrArg0 = { "interest level",iocshArgInt};
+static const iocshArg * const dbsrArgs[1] = {&dbsrArg0};
+static const iocshFuncDef dbsrFuncDef = {"dbsr",1,dbsrArgs};
+static void dbsrCallFunc(const iocshArgBuf *args) { dbsr(args[0].ival);}
+
/* dbcar */
static const iocshArg dbcarArg0 = { "record name",iocshArgString};
static const iocshArg dbcarArg1 = { "level",iocshArgInt};
@@ -360,6 +367,7 @@ void dbIocRegister(void)
iocshRegister(&dbpFuncDef,dbpCallFunc);
iocshRegister(&dbapFuncDef,dbapCallFunc);
+ iocshRegister(&dbsrFuncDef,dbsrCallFunc);
iocshRegister(&dbcarFuncDef,dbcarCallFunc);
iocshRegister(&dbelFuncDef,dbelCallFunc);
diff --git a/src/ioc/db/dbServer.c b/src/ioc/db/dbServer.c
new file mode 100644
index 000000000..bc1094ce7
--- /dev/null
+++ b/src/ioc/db/dbServer.c
@@ -0,0 +1,58 @@
+/*************************************************************************\
+* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/*
+ * Author: Andrew Johnson