Added new initHook states for iocPause and iocRun commands.
Added a mutex to protect the initHook.c routines.
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* src/db/initHooks.c */
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Authors: Benjamin Franksen (BESY) and Marty Kraimer
|
||||
* Date: 06-01-91
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "ellLib.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsMutex.h"
|
||||
#define epicsExportSharedSymbols
|
||||
#include "initHooks.h"
|
||||
|
||||
@@ -29,6 +30,7 @@ typedef struct initHookLink {
|
||||
} initHookLink;
|
||||
|
||||
static ELLLIST functionList;
|
||||
static epicsMutexId listLock;
|
||||
|
||||
/*
|
||||
* Lazy initialization functions
|
||||
@@ -36,6 +38,7 @@ static ELLLIST functionList;
|
||||
static void initHookOnce(void *arg)
|
||||
{
|
||||
ellInit(&functionList);
|
||||
listLock = epicsMutexMustCreate();
|
||||
}
|
||||
|
||||
static void initHookInit(void)
|
||||
@@ -51,39 +54,53 @@ int initHookRegister(initHookFunction func)
|
||||
{
|
||||
initHookLink *newHook;
|
||||
|
||||
if (!func) return 0;
|
||||
|
||||
initHookInit();
|
||||
|
||||
newHook = (initHookLink *)malloc(sizeof(initHookLink));
|
||||
if (newHook == NULL) {
|
||||
if (!newHook) {
|
||||
printf("Cannot malloc a new initHookLink\n");
|
||||
return -1;
|
||||
}
|
||||
newHook->func = func;
|
||||
|
||||
epicsMutexMustLock(listLock);
|
||||
ellAdd(&functionList, &newHook->node);
|
||||
epicsMutexUnlock(listLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by iocInit at various points during initialization.
|
||||
* Do not call this function from any other function than iocInit.
|
||||
* This function must only be called by iocInit and relatives.
|
||||
*/
|
||||
void initHooks(initHookState state)
|
||||
void initHookAnnounce(initHookState state)
|
||||
{
|
||||
initHookLink *hook;
|
||||
|
||||
initHookInit();
|
||||
|
||||
epicsMutexMustLock(listLock);
|
||||
hook = (initHookLink *)ellFirst(&functionList);
|
||||
epicsMutexUnlock(listLock);
|
||||
|
||||
while (hook != NULL) {
|
||||
hook->func(state);
|
||||
|
||||
epicsMutexMustLock(listLock);
|
||||
hook = (initHookLink *)ellNext(&hook->node);
|
||||
epicsMutexUnlock(listLock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Call any time you want to print out a state name.
|
||||
*/
|
||||
const char *initHookName(initHookState state)
|
||||
const char *initHookName(int state)
|
||||
{
|
||||
const char *stateName[] = {
|
||||
"initHookAtIocBuild",
|
||||
"initHookAtBeginning",
|
||||
"initHookAfterCallbackInit",
|
||||
"initHookAfterCaLinkInit",
|
||||
@@ -94,10 +111,20 @@ const char *initHookName(initHookState state)
|
||||
"initHookAfterFinishDevSup",
|
||||
"initHookAfterScanInit",
|
||||
"initHookAfterInitialProcess",
|
||||
"initHookAfterCaServerInit",
|
||||
"initHookAfterIocBuilt",
|
||||
"initHookAtIocRun",
|
||||
"initHookAfterDatabaseRunning",
|
||||
"initHookAfterCaServerRunning",
|
||||
"initHookAfterIocRunning",
|
||||
"initHookAtIocPause",
|
||||
"initHookAfterCaServerPaused",
|
||||
"initHookAfterDatabasePaused",
|
||||
"initHookAfterIocPaused",
|
||||
"initHookAfterInterruptAccept",
|
||||
"initHookAtEnd"
|
||||
};
|
||||
if (state < initHookAtBeginning || state > initHookAtEnd) {
|
||||
if (state < 0 || state > NELEMENTS(stateName)) {
|
||||
return "Not an initHookState";
|
||||
}
|
||||
return stateName[state];
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* src/db/initHooks.h */
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Authors: Benjamin Franksen (BESY) and Marty Kraimer
|
||||
* Date: 06-01-91
|
||||
@@ -18,8 +18,13 @@
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This enum must agree with the array of names defined in initHookName() */
|
||||
typedef enum {
|
||||
initHookAtIocBuild = 0, /* Start of iocBuild/iocInit commands */
|
||||
initHookAtBeginning,
|
||||
initHookAfterCallbackInit,
|
||||
initHookAfterCaLinkInit,
|
||||
@@ -30,18 +35,32 @@ typedef enum {
|
||||
initHookAfterFinishDevSup,
|
||||
initHookAfterScanInit,
|
||||
initHookAfterInitialProcess,
|
||||
initHookAfterInterruptAccept,
|
||||
initHookAtEnd
|
||||
}initHookState;
|
||||
initHookAfterCaServerInit,
|
||||
initHookAfterIocBuilt, /* End of iocBuild command */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
initHookAtIocRun, /* Start of iocRun command */
|
||||
initHookAfterDatabaseRunning,
|
||||
initHookAfterCaServerRunning,
|
||||
initHookAfterIocRunning, /* End of iocRun/iocInit commands */
|
||||
|
||||
initHookAtIocPause, /* Start of iocPause command */
|
||||
initHookAfterCaServerPaused,
|
||||
initHookAfterDatabasePaused,
|
||||
initHookAfterIocPaused, /* End of iocPause command */
|
||||
|
||||
/* Deprecated states, provided for backwards compatibility.
|
||||
* These states are announced at the same point they were before,
|
||||
* but will not be repeated if the IOC gets paused and restarted.
|
||||
*/
|
||||
initHookAfterInterruptAccept, /* After initHookAfterDatabaseRunning */
|
||||
initHookAtEnd, /* Before initHookAfterIocRunning */
|
||||
} initHookState;
|
||||
|
||||
typedef void (*initHookFunction)(initHookState state);
|
||||
epicsShareFunc int initHookRegister(initHookFunction func);
|
||||
epicsShareFunc void initHooks(initHookState state);
|
||||
epicsShareFunc const char *initHookName(initHookState state);
|
||||
epicsShareFunc void initHookAnnounce(initHookState state);
|
||||
epicsShareFunc const char *initHookName(int state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* iocInit.c */
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
@@ -52,7 +51,7 @@
|
||||
#include "recSup.h"
|
||||
#include "envDefs.h"
|
||||
#include "rsrv.h"
|
||||
epicsShareFunc int epicsShareAPI asInit (void);
|
||||
#include "asDbLib.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "db_access_routines.h"
|
||||
#include "initHooks.h"
|
||||
@@ -91,6 +90,7 @@ int iocBuild(void)
|
||||
errlogPrintf("iocBuild: IOC can only be initialized once\n");
|
||||
return -1;
|
||||
}
|
||||
initHookAnnounce(initHookAtIocBuild);
|
||||
|
||||
if (!epicsThreadIsOkToBlock()) {
|
||||
epicsThreadSetOkToBlock(1);
|
||||
@@ -102,7 +102,7 @@ int iocBuild(void)
|
||||
return -1;
|
||||
}
|
||||
epicsSignalInstallSigHupIgnore();
|
||||
initHooks(initHookAtBeginning);
|
||||
initHookAnnounce(initHookAtBeginning);
|
||||
|
||||
coreRelease();
|
||||
/* After this point, further calls to iocInit() are disallowed. */
|
||||
@@ -110,27 +110,27 @@ int iocBuild(void)
|
||||
|
||||
taskwdInit();
|
||||
callbackInit();
|
||||
initHooks(initHookAfterCallbackInit);
|
||||
initHookAnnounce(initHookAfterCallbackInit);
|
||||
|
||||
dbCaLinkInit();
|
||||
initHooks(initHookAfterCaLinkInit);
|
||||
initHookAnnounce(initHookAfterCaLinkInit);
|
||||
|
||||
initDrvSup();
|
||||
initHooks(initHookAfterInitDrvSup);
|
||||
initHookAnnounce(initHookAfterInitDrvSup);
|
||||
|
||||
initRecSup();
|
||||
initHooks(initHookAfterInitRecSup);
|
||||
initHookAnnounce(initHookAfterInitRecSup);
|
||||
|
||||
initDevSup();
|
||||
initHooks(initHookAfterInitDevSup);
|
||||
initHookAnnounce(initHookAfterInitDevSup);
|
||||
|
||||
initDatabase();
|
||||
dbLockInitRecords(pdbbase);
|
||||
dbBkptInit();
|
||||
initHooks(initHookAfterInitDatabase);
|
||||
initHookAnnounce(initHookAfterInitDatabase);
|
||||
|
||||
finishDevSup();
|
||||
initHooks(initHookAfterFinishDevSup);
|
||||
initHookAnnounce(initHookAfterFinishDevSup);
|
||||
|
||||
scanInit();
|
||||
if (asInit()) {
|
||||
@@ -139,15 +139,17 @@ int iocBuild(void)
|
||||
}
|
||||
dbPutNotifyInit();
|
||||
epicsThreadSleep(.5);
|
||||
initHooks(initHookAfterScanInit);
|
||||
initHookAnnounce(initHookAfterScanInit);
|
||||
|
||||
initialProcess();
|
||||
initHooks(initHookAfterInitialProcess);
|
||||
initHookAnnounce(initHookAfterInitialProcess);
|
||||
|
||||
/* Start CA server threads */
|
||||
rsrv_init();
|
||||
initHookAnnounce(initHookAfterCaServerInit);
|
||||
|
||||
iocState = iocBuilt;
|
||||
initHookAnnounce(initHookAfterIocBuilt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -157,21 +159,25 @@ int iocRun(void)
|
||||
errlogPrintf("iocRun: IOC not paused\n");
|
||||
return -1;
|
||||
}
|
||||
initHookAnnounce(initHookAtIocRun);
|
||||
|
||||
/* Enable scan tasks and some driver support functions. */
|
||||
scanRun();
|
||||
dbCaRun();
|
||||
initHookAnnounce(initHookAfterDatabaseRunning);
|
||||
if (iocState == iocBuilt)
|
||||
initHooks(initHookAfterInterruptAccept);
|
||||
initHookAnnounce(initHookAfterInterruptAccept);
|
||||
|
||||
rsrv_run();
|
||||
initHookAnnounce(initHookAfterCaServerRunning);
|
||||
if (iocState == iocBuilt)
|
||||
initHooks(initHookAtEnd);
|
||||
initHookAnnounce(initHookAtEnd);
|
||||
|
||||
errlogPrintf("iocRun: %s\n", iocState == iocBuilt ?
|
||||
"All initialization complete" :
|
||||
"IOC restarted");
|
||||
iocState = iocRunning;
|
||||
initHookAnnounce(initHookAfterIocRunning);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -181,13 +187,18 @@ int iocPause(void)
|
||||
errlogPrintf("iocPause: IOC not running\n");
|
||||
return -1;
|
||||
}
|
||||
initHookAnnounce(initHookAtIocPause);
|
||||
|
||||
rsrv_pause();
|
||||
initHookAnnounce(initHookAfterCaServerPaused);
|
||||
|
||||
dbCaPause();
|
||||
scanPause();
|
||||
iocState = iocPaused;
|
||||
initHookAnnounce(initHookAfterDatabasePaused);
|
||||
|
||||
iocState = iocPaused;
|
||||
errlogPrintf("iocPause: IOC suspended\n");
|
||||
initHookAnnounce(initHookAfterIocPaused);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user