From d35780888a3642561202835618b6d53d16432cd1 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 13 Nov 2014 11:58:35 -0500 Subject: [PATCH] iocInit: only teardown from iocBuildIsolated() iocShutdown() should only stop threads and cleanup if the IOC was started with iocBuildIsolated(). If iocBuild() is used then only close CA links as was done previously. This is needed as some device support calls epicsExit() (while holding a record lock). This make it impossible to run the full iocShutdown without deadlocking in scan/callback shutdown, or segfaulting in doFreeRecord() or dbLockCleanupRecords() --- src/ioc/misc/iocInit.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c index d6a94c794..0e553efd6 100644 --- a/src/ioc/misc/iocInit.c +++ b/src/ioc/misc/iocInit.c @@ -72,6 +72,9 @@ static enum { iocVirgin, iocBuilding, iocBuilt, iocRunning, iocPaused, iocStopped } iocState = iocVirgin; +static enum { + buildRSRV, buildIsolated +} iocBuildMode; /* define forward references*/ static int checkDatabase(dbBase *pdbbase); @@ -183,6 +186,7 @@ int iocBuild(void) rsrv_init(); status = iocBuild_3(); + if (!status) iocBuildMode = buildRSRV; return status; } @@ -199,6 +203,7 @@ int iocBuildIsolated(void) if (status) return status; status = iocBuild_3(); + if (!status) iocBuildMode = buildIsolated; return status; } @@ -672,13 +677,16 @@ int iocShutdown(void) { if (iocState == iocVirgin || iocState == iocStopped) return 0; iterateRecords(doCloseLinks, NULL); - scanShutdown(); - callbackShutdown(); - iterateRecords(doFreeRecord, NULL); - dbLockCleanupRecords(pdbbase); - asShutdown(); - iocshFree(); + if (iocBuildMode==buildIsolated) { + scanShutdown(); + callbackShutdown(); + iterateRecords(doFreeRecord, NULL); + dbLockCleanupRecords(pdbbase); + asShutdown(); + iocshFree(); + } iocState = iocStopped; + iocBuildMode = buildRSRV; return 0; }