From 564a527489993c20f7fc4ecc245f616f23016a57 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 23 Jun 2014 16:28:20 -0400 Subject: [PATCH] misc/iocInit: add iocBuildNoCA() and iocShutdown() to API, split up iocBuild in three phases --- src/ioc/misc/iocInit.c | 77 +++++++++++++++++++++++++++++++++++++----- src/ioc/misc/iocInit.h | 2 ++ 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c index a98bfea7f..e7c9a26ab 100644 --- a/src/ioc/misc/iocInit.c +++ b/src/ioc/misc/iocInit.c @@ -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. \*************************************************************************/ @@ -31,6 +33,7 @@ #include "errMdef.h" #include "taskwd.h" #include "caeventmask.h" +#include "iocsh.h" #define epicsExportSharedSymbols #include "alarm.h" @@ -88,10 +91,10 @@ int iocInit(void) 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; } errlogInit(0); @@ -110,14 +113,17 @@ int iocBuild(void) 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(); @@ -148,9 +154,11 @@ int iocBuild(void) initialProcess(); initHookAnnounce(initHookAfterInitialProcess); + return 0; +} - /* Start CA server threads */ - rsrv_init(); +static int iocBuild_3(void) +{ initHookAnnounce(initHookAfterCaServerInit); iocState = iocBuilt; @@ -158,6 +166,39 @@ int iocBuild(void) 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) { @@ -600,8 +641,26 @@ static void doCloseLinks(dbRecordType *pdbRecordType, dbCommon *precord, } } +static void doFreeRecord(dbRecordType *pdbRecordType, dbCommon *precord, + void *user) +{ + struct rset *prset = pdbRecordType->prset; + + if (!prset) return; /* unlikely */ + + epicsMutexDestroy(precord->mlok); +} + +int iocShutdown(void) +{ + if (iocState == iocVirgin || iocState == iocStopped) return 0; + iterateRecords(doCloseLinks, NULL); + iterateRecords(doFreeRecord, NULL); + iocState = iocStopped; + return 0; +} + static void exitDatabase(void *dummy) { - iterateRecords(doCloseLinks, NULL); - iocState = iocStopped; + iocShutdown(); } diff --git a/src/ioc/misc/iocInit.h b/src/ioc/misc/iocInit.h index 6a2f5682c..a5709f68e 100644 --- a/src/ioc/misc/iocInit.h +++ b/src/ioc/misc/iocInit.h @@ -19,8 +19,10 @@ extern "C" { 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 }