From 9237bb4d955152f3eb62162ccf1f9390b30168d2 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 6 May 2019 11:26:43 -0700 Subject: [PATCH] try to ensure cleanupPy() is run early on shutdown. Add in registrar happens early in startup, and will be run near the end of shutdown. Even if iocInit() isn't run. Also use an initHook to add cleanupPy(), which happens late in startup, and will be run early on shutdown. Though only if iocInit() is run. --- pyIocApp/setup.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pyIocApp/setup.c b/pyIocApp/setup.c index 8a579cd..a15fcb5 100644 --- a/pyIocApp/setup.c +++ b/pyIocApp/setup.c @@ -26,6 +26,12 @@ static void cleanupPy(void *junk) { + /* safe because exit hooks are only run once, from a single thread */ + static int done; + + if(done) return; + done = 1; + PyThreadState *state = PyGILState_GetThisThreadState(); PyEval_RestoreThread(state); @@ -112,6 +118,15 @@ static void setupPyPath(void) Py_XDECREF(path); } +static void cleanupPrep(initHookState state) +{ + /* register a second time to better our chances of running + * first on exit. eg. before cacExitHandler() + */ + if(state==initHookAfterIocRunning) + epicsAtExit(&cleanupPy, NULL); +} + static void pySetupReg(void) { Py_InitializeEx(0); @@ -128,7 +143,10 @@ static void pySetupReg(void) (void)PyEval_SaveThread(); + /* register first time to ensure cleanupPy is run at least once */ epicsAtExit(&cleanupPy, NULL); + + initHookRegister(&cleanupPrep); } #include