Subject: |
[Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base |
From: |
Ralph Lange <[email protected]> |
To: |
[email protected] |
Date: |
Fri, 11 Oct 2013 00:45:37 -0000 |
Ralph Lange has proposed merging lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base.
Requested reviews:
EPICS Core Developers (epics-core)
For more details, see:
https://code.launchpad.net/~epics-core/epics-base/ioc-shutdown/+merge/190512
Add iocBuildNoCA() and iocShutdown() to iocInit API to allow running an IOC from withing a test program that is part of a test harness.
Doc changes in https://code.launchpad.net/~epics-documenters/epics-appdev/ioc-shutdown
--
https://code.launchpad.net/~epics-core/epics-base/ioc-shutdown/+merge/190512
Your team EPICS Core Developers is requested to review the proposed merge of lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base.
=== modified file 'src/ioc/db/callback.c'
--- src/ioc/db/callback.c 2012-05-04 22:34:48 +0000
+++ src/ioc/db/callback.c 2013-10-11 00:44:30 +0000
@@ -53,6 +53,8 @@
static epicsTimerQueueId timerQueue;
/* Shutdown handling */
+enum ctl {ctlInit, ctlRun, ctlPause, ctlExit};
+static volatile enum ctl cbCtl;
static epicsEventId startStopEvent;
static void *exitCallback;
@@ -101,10 +103,13 @@
epicsEventSignal(startStopEvent);
}
-static void callbackShutdown(void *arg)
+void callbackShutdown(void)
{
int i;
+ if (cbCtl == ctlExit) return;
+ cbCtl = ctlExit;
+
for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) {
int lockKey = epicsInterruptLock();
int ok = epicsRingPointerPush(callbackQ[i], &exitCallback);
@@ -112,6 +117,12 @@
epicsEventSignal(callbackSem[i]);
if (ok) epicsEventWait(startStopEvent);
}
+ epicsTimerQueueRelease(timerQueue);
+}
+
+static void callbackExit(void *arg)
+{
+ callbackShutdown();
}
static void callbackInitOnce(void *arg)
@@ -119,6 +130,7 @@
int i;
startStopEvent = epicsEventMustCreate(epicsEventEmpty);
+ cbCtl = ctlRun;
timerQueue = epicsTimerQueueAllocate(0,epicsThreadPriorityScanHigh);
for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) {
epicsThreadId tid;
@@ -137,7 +149,7 @@
else
epicsEventWait(startStopEvent);
}
- epicsAtExit(callbackShutdown, NULL);
+ epicsAtExit(callbackExit, NULL);
}
void callbackInit(void)
=== modified file 'src/ioc/db/callback.h'
--- src/ioc/db/callback.h 2010-10-05 19:27:37 +0000
+++ src/ioc/db/callback.h 2013-10-11 00:44:30 +0000
@@ -57,6 +57,7 @@
epicsShareFunc void callbackInit(void);
epicsShareFunc void callbackRequest(CALLBACK *pCallback);
+epicsShareFunc void callbackShutdown(void);
epicsShareFunc void callbackSetProcess(
CALLBACK *pcallback, int Priority, void *pRec);
epicsShareFunc void callbackRequestProcessCallback(
=== modified file 'src/ioc/db/dbCa.c'
--- src/ioc/db/dbCa.c 2012-06-22 23:16:26 +0000
+++ src/ioc/db/dbCa.c 2013-10-11 00:44:30 +0000
@@ -173,15 +173,22 @@
dbScanUnlock(pdbCommon);
}
-static void dbCaShutdown(void *arg)
+void dbCaShutdown(void)
{
- if (dbCaCtl == ctlRun) {
+ if (dbCaCtl == ctlRun || dbCaCtl == ctlPause) {
dbCaCtl = ctlExit;
epicsEventSignal(workListEvent);
epicsEventMustWait(startStopEvent);
+ epicsEventDestroy(startStopEvent);
+ epicsEventDestroy(workListEvent);
}
}
+static void dbCaExit(void *arg)
+{
+ dbCaShutdown();
+}
+
void dbCaLinkInit(void)
{
dbServiceIOInit();
@@ -194,19 +201,23 @@
epicsThreadGetStackSize(epicsThreadStackBig),
dbCaTask, NULL);
epicsEventMustWait(startStopEvent);
- epicsAtExit(dbCaShutdown, NULL);
+ epicsAtExit(dbCaExit, NULL);
}
void dbCaRun(void)
{
- dbCaCtl = ctlRun;
- epicsEventSignal(workListEvent);
+ if (dbCaCtl == ctlPause) {
+ dbCaCtl = ctlRun;
+ epicsEventSignal(workListEvent);
+ }
}
void dbCaPause(void)
{
- dbCaCtl = ctlPause;
- epicsEventSignal(workListEvent);
+ if (dbCaCtl == ctlRun) {
+ dbCaCtl = ctlPause;
+ epicsEventSignal(workListEvent);
+ }
}
void dbCaAddLinkCallback(struct link *plink,
=== modified file 'src/ioc/db/dbCa.h'
--- src/ioc/db/dbCa.h 2012-04-27 17:21:47 +0000
+++ src/ioc/db/dbCa.h 2013-10-11 00:44:30 +0000
@@ -26,6 +26,7 @@
epicsShareFunc void dbCaLinkInit(void);
epicsShareFunc void dbCaRun(void);
epicsShareFunc void dbCaPause(void);
+epicsShareFunc void dbCaShutdown(void);
epicsShareFunc void dbCaAddLinkCallback(struct link *plink,
dbCaCallback connect, dbCaCallback monitor, void *userPvt);
=== modified file 'src/ioc/db/dbScan.c'
--- src/ioc/db/dbScan.c 2013-04-23 15:38:57 +0000
+++ src/ioc/db/dbScan.c 2013-10-11 00:44:30 +0000
@@ -3,6 +3,8 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
+* Copyright (c) 2013 Helmholtz-Zentrum Berlin
+* für Materialien und Energie GmbH.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
@@ -129,6 +131,7 @@
static void initOnce(void);
static void periodicTask(void *arg);
static void initPeriodic(void);
+static void deletePeriodic(void);
static void spawnPeriodic(int ind);
static void initEvent(void);
static void eventCallback(CALLBACK *pcallback);
@@ -139,10 +142,13 @@
static void addToList(struct dbCommon *precord, scan_list *psl);
static void deleteFromList(struct dbCommon *precord, scan_list *psl);
-static void scanShutdown(void *arg)
+void scanShutdown(void)
{
int i;
+ if (scanCtl == ctlExit) return;
+ scanCtl = ctlExit;
+
interruptAccept = FALSE;
for (i = 0; i < nPeriodic; i++) {
@@ -153,6 +159,15 @@
scanOnce((dbCommon *)&exitOnce);
epicsEventWait(startStopEvent);
+
+ deletePeriodic();
+
+ epicsEventDestroy(startStopEvent);
+}
+
+static void scanExit(void *arg)
+{
+ scanShutdown();
}
long scanInit(void)
@@ -169,7 +184,7 @@
for (i = 0; i < nPeriodic; i++)
spawnPeriodic(i);
- epicsAtExit(scanShutdown, NULL);
+ epicsAtExit(scanExit, NULL);
return 0;
}
@@ -672,6 +687,28 @@
}
}
+static void deletePeriodic(void)
+{
+ int i;
+ scan_element *pse;
+
+ for (i = 0; i < nPeriodic; i++) {
+ periodic_scan_list *ppsl = papPeriodic[i];
+
+ for (pse = (scan_element *)ellFirst(&ppsl->scan_list.list);
+ pse;
+ pse = (scan_element *)ellNext(&pse->node)) {
+ ellDelete(&ppsl->scan_list.list, (ELLNODE *)pse);
+ free(pse);
+ }
+ epicsEventDestroy(ppsl->loopEvent);
+ epicsMutexDestroy(ppsl->scan_list.lock);
+ free(ppsl);
+ }
+
+ free(papPeriodic);
+}
+
static void spawnPeriodic(int ind)
{
periodic_scan_list *ppsl;
@@ -778,23 +815,25 @@
{
dbRecordType *pdbRecordType;
- /*Look for first record*/
for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList);
pdbRecordType;
pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) {
dbRecordNode *pdbRecordNode;
+
for (pdbRecordNode = (dbRecordNode *)ellFirst(&pdbRecordType->recList);
pdbRecordNode;
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
dbCommon *precord = pdbRecordNode->precord;
+
if (!precord->name[0] ||
pdbRecordNode->flags & DBRN_FLAGS_ISALIAS)
continue;
+
scanAdd(precord);
}
}
}
-
+
static void addToList(struct dbCommon *precord, scan_list *psl)
{
scan_element *pse, *ptemp;
=== modified file 'src/ioc/db/dbScan.h'
--- src/ioc/db/dbScan.h 2012-04-10 22:10:50 +0000
+++ src/ioc/db/dbScan.h 2013-10-11 00:44:30 +0000
@@ -44,6 +44,7 @@
epicsShareFunc long scanInit(void);
epicsShareFunc void scanRun(void);
epicsShareFunc void scanPause(void);
+epicsShareFunc void scanShutdown(void);
epicsShareFunc EVENTPVT eventNameToHandle(const char* event);
epicsShareFunc void postEvent(EVENTPVT epvt);
=== modified file 'src/ioc/misc/iocInit.c'
--- src/ioc/misc/iocInit.c 2013-05-30 20:00:37 +0000
+++ src/ioc/misc/iocInit.c 2013-10-11 00:44:30 +0000
@@ -3,6 +3,8 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
+* Copyright (c) 2013 Helmholtz-Zentrum Berlin
+* für Materialien und Energie GmbH.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
@@ -88,10 +90,10 @@
return iocBuild() || iocRun();
}
-int iocBuild(void)
+static int iocBuild_1(void)
{
- if (iocState != iocVirgin) {
- errlogPrintf("iocBuild: IOC can only be initialized once\n");
+ if (iocState != iocVirgin && iocState != iocStopped) {
+ errlogPrintf("iocBuild: IOC can only be initialized from uninitialized or stopped state\n");
return -1;
}
initHookAnnounce(initHookAtIocBuild);
@@ -109,14 +111,17 @@
initHookAnnounce(initHookAtBeginning);
coreRelease();
- /* After this point, further calls to iocInit() are disallowed. */
iocState = iocBuilding;
taskwdInit();
callbackInit();
initHookAnnounce(initHookAfterCallbackInit);
- dbCaLinkInit();
+ return 0;
+}
+
+static int iocBuild_2(void)
+{
initHookAnnounce(initHookAfterCaLinkInit);
initDrvSup();
@@ -147,9 +152,11 @@
initialProcess();
initHookAnnounce(initHookAfterInitialProcess);
+ return 0;
+}
- /* Start CA server threads */
- rsrv_init();
+static int iocBuild_3(void)
+{
initHookAnnounce(initHookAfterCaServerInit);
iocState = iocBuilt;
@@ -157,6 +164,39 @@
return 0;
}
+int iocBuild(void)
+{
+ int status;
+
+ status = iocBuild_1();
+ if (status) return status;
+
+ dbCaLinkInit();
+
+ status = iocBuild_2();
+ if (status) return status;
+
+ /* Start CA server threads */
+ rsrv_init();
+
+ status = iocBuild_3();
+ return status;
+}
+
+int iocBuildNoCA(void)
+{
+ int status;
+
+ status = iocBuild_1();
+ if (status) return status;
+
+ status = iocBuild_2();
+ if (status) return status;
+
+ status = iocBuild_3();
+ return status;
+}
+
int iocRun(void)
{
if (iocState != iocPaused && iocState != iocBuilt) {
@@ -599,8 +639,19 @@
}
}
-static void exitDatabase(void *dummy)
+int iocShutdown(void)
{
+ if (iocState == iocVirgin || iocState == iocStopped) return 0;
iterateRecords(doCloseLinks, NULL);
+ scanShutdown();
+ callbackShutdown();
+ taskwdShutdown();
+ errlogShutdown();
iocState = iocStopped;
+ return 0;
+}
+
+static void exitDatabase(void *dummy)
+{
+ iocShutdown();
}
=== modified file 'src/ioc/misc/iocInit.h'
--- src/ioc/misc/iocInit.h 2009-06-10 20:19:32 +0000
+++ src/ioc/misc/iocInit.h 2013-10-11 00:44:30 +0000
@@ -19,8 +19,10 @@
epicsShareFunc int iocInit(void);
epicsShareFunc int iocBuild(void);
+epicsShareFunc int iocBuildNoCA(void);
epicsShareFunc int iocRun(void);
epicsShareFunc int iocPause(void);
+epicsShareFunc int iocShutdown(void);
#ifdef __cplusplus
}
=== modified file 'src/libCom/error/errlog.c'
--- src/libCom/error/errlog.c 2013-06-28 17:35:43 +0000
+++ src/libCom/error/errlog.c 2013-10-11 00:44:30 +0000
@@ -447,8 +447,9 @@
}
-static void exitHandler(void *pvt)
+void errlogShutdown(void)
{
+ if (pvtData.atExit) return;
pvtData.atExit = 1;
epicsEventSignal(pvtData.waitForWork);
epicsEventMustWait(pvtData.waitForExit);
@@ -463,6 +464,11 @@
epicsEventDestroy(pvtData.waitForExit);
}
+static void exitHandler(void *pvt)
+{
+ errlogShutdown();
+}
+
struct initArgs {
int bufsize;
int maxMsgSize;
=== modified file 'src/libCom/error/errlog.h'
--- src/libCom/error/errlog.h 2013-06-28 17:35:43 +0000
+++ src/libCom/error/errlog.h 2013-10-11 00:44:30 +0000
@@ -64,6 +64,7 @@
epicsShareFunc int errlogSetConsole(FILE *stream);
epicsShareFunc int epicsShareAPI errlogInit(int bufsize);
+epicsShareFunc void epicsShareAPI errlogShutdown(void);
epicsShareFunc int epicsShareAPI errlogInit2(int bufsize, int maxMsgSize);
epicsShareFunc void epicsShareAPI errlogFlush(void);
=== modified file 'src/libCom/taskwd/taskwd.c'
--- src/libCom/taskwd/taskwd.c 2012-05-04 18:38:59 +0000
+++ src/libCom/taskwd/taskwd.c 2013-10-11 00:44:30 +0000
@@ -70,7 +70,7 @@
/* Watchdog task control */
static volatile enum {
- twdctlInit, twdctlRun, twdctlDisable, twdctlExit
+ ctlInit, ctlRun, ctlDisable, ctlExit
} twdCtl;
static epicsEventId loopEvent;
static epicsEventId exitEvent;
@@ -90,8 +90,8 @@
struct tNode *pt;
struct mNode *pm;
- while (twdCtl != twdctlExit) {
- if (twdCtl == twdctlRun) {
+ while (twdCtl != ctlExit) {
+ if (twdCtl == ctlRun) {
epicsMutexMustLock(tLock);
pt = (struct tNode *)ellFirst(&tList);
while (pt) {
@@ -127,14 +127,20 @@
epicsEventSignal(exitEvent);
}
-
-static void twdShutdown(void *arg)
+void taskwdShutdown(void)
{
- twdCtl = twdctlExit;
+ if (twdCtl == ctlExit) return;
+ twdCtl = ctlExit;
+
epicsEventSignal(loopEvent);
epicsEventWait(exitEvent);
}
+static void twdExit(void *arg)
+{
+ taskwdShutdown();
+}
+
static void twdInitOnce(void *arg)
{
epicsThreadId tid;
@@ -143,7 +149,7 @@
mLock = epicsMutexMustCreate();
fLock = epicsMutexMustCreate();
- twdCtl = twdctlRun;
+ twdCtl = ctlRun;
loopEvent = epicsEventMustCreate(epicsEventEmpty);
exitEvent = epicsEventMustCreate(epicsEventEmpty);
@@ -153,7 +159,7 @@
if (tid == 0)
cantProceed("Failed to spawn task watchdog thread\n");
- epicsAtExit(twdShutdown, NULL);
+ epicsAtExit(twdExit, NULL);
}
void taskwdInit(void)
=== modified file 'src/libCom/taskwd/taskwd.h'
--- src/libCom/taskwd/taskwd.h 2010-10-05 19:27:37 +0000
+++ src/libCom/taskwd/taskwd.h 2013-10-11 00:44:30 +0000
@@ -28,6 +28,7 @@
/* Initialization, optional */
epicsShareFunc void taskwdInit(void);
+epicsShareFunc void taskwdShutdown(void);
/* For tasks to be monitored */
- Replies:
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base mdavidsaver
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base mdavidsaver
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base mdavidsaver
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base mdavidsaver
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base Ralph Lange
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base Ralph Lange
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base Andrew Johnson
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base Andrew Johnson
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base Andrew Johnson
- Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base mdavidsaver
- Navigate by Date:
- Prev:
Re: Enumerated string comparisons Benjamin Franksen
- Next:
Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base mdavidsaver
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
<2013>
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: Enumerated string comparisons Eric Norum
- Next:
Re: [Merge] lp:~epics-core/epics-base/ioc-shutdown into lp:epics-base mdavidsaver
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
<2013>
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|