dbStatic: Added hook routine for dbLoadRecords()
Requested by Tim Mooney for use by Autosave. See the Release Notes for documentation. This commit also corrects the decorations for recGblAlarmHook.
This commit is contained in:
@@ -3,17 +3,66 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
|
||||
<title>EPICS Base R3.15.0.1 Release Notes</title>
|
||||
<title>EPICS Base R3.15.1 Release Notes</title>
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
<h1 align="center">EPICS Base Release 3.15.0.2</h1>
|
||||
<h1 align="center">EPICS Base Release 3.15.1</h1>
|
||||
|
||||
<p style="color:red">This version of EPICS Base has not been released yet.</p>
|
||||
|
||||
<h2 align="center">Changes between 3.15.0.2 and 3.15.1</h2>
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>Hooking into dbLoadRecords</h3>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>Code to use this hook should look something like this:</p>
|
||||
|
||||
<blockquote><pre>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>
|
||||
EPICS Base 3.15.0.x releases are not intended for use in production systems.</p>
|
||||
|
||||
<h2 align="center">Changes between 3.15.0.1 and 3.15.0.2</h2>
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>New iocshLoad command</h3>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user