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.
This commit is contained in:
Michael Davidsaver
2019-05-06 11:26:43 -07:00
parent ae755cd069
commit 9237bb4d95

View File

@ -26,6 +26,12 @@
static void cleanupPy(void *junk) 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(); PyThreadState *state = PyGILState_GetThisThreadState();
PyEval_RestoreThread(state); PyEval_RestoreThread(state);
@ -112,6 +118,15 @@ static void setupPyPath(void)
Py_XDECREF(path); 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) static void pySetupReg(void)
{ {
Py_InitializeEx(0); Py_InitializeEx(0);
@ -128,7 +143,10 @@ static void pySetupReg(void)
(void)PyEval_SaveThread(); (void)PyEval_SaveThread();
/* register first time to ensure cleanupPy is run at least once */
epicsAtExit(&cleanupPy, NULL); epicsAtExit(&cleanupPy, NULL);
initHookRegister(&cleanupPrep);
} }
#include <epicsExport.h> #include <epicsExport.h>