Skip to content

Commit

Permalink
HPCC-18841 Embedded python may lock up at process termination
Browse files Browse the repository at this point in the history
This can cause issues for eclagent processes in particular

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
  • Loading branch information
richardkchapman committed Dec 5, 2017
1 parent 60512ee commit b33bca5
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 4 deletions.
7 changes: 6 additions & 1 deletion plugins/py3embed/py3embed.cpp
Expand Up @@ -252,6 +252,8 @@ static void releaseContext()

// Use a global object to ensure that the Python interpreter is initialized on main thread

static HINSTANCE keepLoadedHandle;

static class Python3xGlobalState
{
public:
Expand Down Expand Up @@ -289,6 +291,9 @@ static class Python3xGlobalState
}
~Python3xGlobalState()
{
if (keepLoadedHandle)
FreeSharedObject(keepLoadedHandle); // Must be process termination - ok to free now (and helps stop lockups at closedown in some Python libraries eg Tensorflow).

if (threadContext)
delete threadContext; // The one on the main thread won't get picked up by the thread hook mechanism
threadContext = NULL;
Expand Down Expand Up @@ -493,7 +498,7 @@ MODULE_INIT(INIT_PRIORITY_STANDARD)
if (tail)
{
tail[strlen(SharedObjectExtension)] = 0;
HINSTANCE h = LoadSharedObject(fullName, false, false);
keepLoadedHandle = LoadSharedObject(fullName, false, false);
break;
}
}
Expand Down
10 changes: 7 additions & 3 deletions plugins/pyembed/pyembed.cpp
Expand Up @@ -245,6 +245,8 @@ static void releaseContext()

// Use a global object to ensure that the Python interpreter is initialized on main thread

static HINSTANCE keepLoadedHandle;

static class Python27GlobalState
{
public:
Expand Down Expand Up @@ -282,6 +284,9 @@ static class Python27GlobalState
}
~Python27GlobalState()
{
if (keepLoadedHandle)
FreeSharedObject(keepLoadedHandle); // Must be process termination - ok to free now (and helps stop lockups at closedown in some Python libraries eg Tensorflow).

if (threadContext)
delete threadContext; // The one on the main thread won't get picked up by the thread hook mechanism
threadContext = NULL;
Expand Down Expand Up @@ -458,7 +463,7 @@ static class Python27GlobalState

MODULE_INIT(INIT_PRIORITY_STANDARD)
{
// Make sure we are never unloaded (as Python may crash if we are)
// Make sure we are never dynamically unloaded (as Python may crash if we are)
// we do this by doing a dynamic load of the pyembed library
// This also allows eclcc to be able to use the library for constant folding
#ifdef _WIN32
Expand All @@ -477,8 +482,7 @@ MODULE_INIT(INIT_PRIORITY_STANDARD)
StringBuffer modname;
if (findLoadedModule(modname, "libpy2embed"))
{
HINSTANCE h = LoadSharedObject(modname, false, false);
// Deliberately leak this handle
keepLoadedHandle = LoadSharedObject(modname, false, false);
}
#endif
return true;
Expand Down

0 comments on commit b33bca5

Please sign in to comment.