diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index c11589fd9..207cd2d93 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -3,17 +3,66 @@ - EPICS Base R3.15.0.1 Release Notes + EPICS Base R3.15.1 Release Notes -

EPICS Base Release 3.15.0.2

+

EPICS Base Release 3.15.1

+ +

This version of EPICS Base has not been released yet.

+ +

Changes between 3.15.0.2 and 3.15.1

+ + +

Hooking into dbLoadRecords

+ +

A function pointer hook has been added to the dbLoadRecords() routine, to +allow external modules such as autosave to be notified when new records have +been loaded during IOC initialization. The hook is called dbLoadRecordsHook and +follows the model of the recGblAlarmHook pointer in that modules that wish to +use it must save the current value of the pointer before installing their own +function pointer, and must call the original function from their own +routine.

+ +

The hook is activiated from the dbLoadRecords() routine and gets called only +after a database instance file has been read in without error. Note that the +dbLoadTemplates() routine directly calls dbLoadRecords() so this hook also +provides information about instantiated database templates. It is still possible +to load record instances using dbLoadDatabase() though, and doing this will not +result in the hook routines being called.

+ +

Code to use this hook should look something like this:

+ +
+#include "dbAccessDefs.h"
+
+static DB_LOAD_RECORDS_HOOK_ROUTINE previousHook;
+
+static void myRoutine(const char* file, const char* subs) {
+    if (previousHook)
+        previousHook(file, subs);
+
+    /* Do whatever ... */
+}
+
+void myInit(void) {
+    static int done = 0;
+
+    if (!done) {
+        previousHook = dbLoadRecordsHook;
+        dbLoadRecordsHook = myRoutine;
+        done = 1;
+    }
+}
+
+ +

As with many other parts of the static database access library there is no +mutex to protect the function pointer. Initialization is expected to take place +in the context of the IOC's main thread, from either a static C++ constructor or +an EPICS registrar routine.

-

-EPICS Base 3.15.0.x releases are not intended for use in production systems.

Changes between 3.15.0.1 and 3.15.0.2

-

New iocshLoad command

diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c index 62a5247ad..93b00bf15 100644 --- a/src/ioc/db/dbAccess.c +++ b/src/ioc/db/dbAccess.c @@ -65,6 +65,10 @@ epicsShareDef struct dbBase *pdbbase = 0; epicsShareDef volatile int interruptAccept=FALSE; +/* Hook Routines */ + +epicsShareDef DB_LOAD_RECORDS_HOOK_ROUTINE dbLoadRecordsHook = NULL; + static short mapDBFToDBR[DBF_NTYPES] = { /* DBF_STRING => */ DBR_STRING, /* DBF_CHAR => */ DBR_CHAR, @@ -711,7 +715,11 @@ int dbLoadDatabase(const char *file, const char *path, const char *subs) int dbLoadRecords(const char* file, const char* subs) { - return dbReadDatabase(&pdbbase, file, 0, subs); + int status = dbReadDatabase(&pdbbase, file, 0, subs); + + if (!status && dbLoadRecordsHook) + dbLoadRecordsHook(file, subs); + return status; } diff --git a/src/ioc/db/dbAccessDefs.h b/src/ioc/db/dbAccessDefs.h index 31ffc18c2..e0e8f4484 100644 --- a/src/ioc/db/dbAccessDefs.h +++ b/src/ioc/db/dbAccessDefs.h @@ -233,9 +233,14 @@ epicsShareFunc long dbBufferSize( short dbrType,long options,long nRequest); epicsShareFunc long dbValueSize(short dbrType); +/* Hook Routine */ + +typedef void (*DB_LOAD_RECORDS_HOOK_ROUTINE)(const char* filename, + const char* substitutions); +epicsShareExtern DB_LOAD_RECORDS_HOOK_ROUTINE dbLoadRecordsHook; + epicsShareFunc int dbLoadDatabase( const char *filename, const char *path, const char *substitutions); - epicsShareFunc int dbLoadRecords( const char* filename, const char* substitutions); diff --git a/src/ioc/db/recGbl.c b/src/ioc/db/recGbl.c index d1b9fb358..0a8615506 100644 --- a/src/ioc/db/recGbl.c +++ b/src/ioc/db/recGbl.c @@ -45,7 +45,7 @@ /* Hook Routines */ -RECGBL_ALARM_HOOK_ROUTINE recGblAlarmHook = NULL; +epicsShareDef RECGBL_ALARM_HOOK_ROUTINE recGblAlarmHook = NULL; /* local routines */ static void getMaxRangeValues(short field_type, double *pupper_limit, diff --git a/src/ioc/db/recGbl.h b/src/ioc/db/recGbl.h index 04a0ee4d1..e81749a54 100644 --- a/src/ioc/db/recGbl.h +++ b/src/ioc/db/recGbl.h @@ -36,7 +36,7 @@ struct dbCommon; typedef void (*RECGBL_ALARM_HOOK_ROUTINE)(struct dbCommon *prec, epicsEnum16 prev_sevr, epicsEnum16 prev_stat); -extern RECGBL_ALARM_HOOK_ROUTINE recGblAlarmHook; +epicsShareExtern RECGBL_ALARM_HOOK_ROUTINE recGblAlarmHook; /* Global Record Support Routines */