瀏覽代碼

HPCC-9088 Python errors prevent start of ESP in 4.0.0rc2

Python library calls exit() if stdin is referring to a directory.

FOr some reason, this seems to sometimes happen if the R library is also
loaded. While we should also address the problem in the R embedding plugin, it
is never a good idea for the Python plugin to cause the caller to exit.
Therefore, we check for the situation that causes it to exit, and disable
the python support if it is present.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 12 年之前
父節點
當前提交
c2a9bcaddb
共有 1 個文件被更改,包括 24 次插入3 次删除
  1. 24 3
      plugins/pyembed/pyembed.cpp

+ 24 - 3
plugins/pyembed/pyembed.cpp

@@ -210,22 +210,41 @@ static class Python27GlobalState
 public:
     Python27GlobalState()
     {
+#ifndef _WIN32
+        // If Py_Initialize is called when stdin is set to a directory, it calls exit()
+        // We don't want that to happen - just disable Python support in such situations
+        struct stat sb;
+        if (fstat(fileno(stdin), &sb) == 0 && S_ISDIR(sb.st_mode))
+        {
+            initialized = false;
+            return;
+        }
+#endif
         // Initialize the Python Interpreter
         Py_Initialize();
         PyEval_InitThreads();
         tstate = PyEval_SaveThread();
+        initialized = true;
     }
     ~Python27GlobalState()
     {
         if (threadContext)
             delete threadContext;   // The one on the main thread won't get picked up by the thread hook mechanism
         threadContext = NULL;
-        PyEval_RestoreThread(tstate);
-        // Finish the Python Interpreter
-        Py_Finalize();
+        if (initialized)
+        {
+            PyEval_RestoreThread(tstate);
+            // Finish the Python Interpreter
+            Py_Finalize();
+        }
+    }
+    bool isInitialized()
+    {
+        return initialized;
     }
 protected:
     PyThreadState *tstate;
+    bool initialized;
 } globalState;
 
 // Each call to a Python function will use a new Python27EmbedFunctionContext object
@@ -704,6 +723,8 @@ public:
     {
         if (!threadContext)
         {
+            if (!globalState.isInitialized())
+                rtlFail(0, "Python not initialized");
             threadContext = new PythonThreadContext;
             threadHookChain = addThreadTermFunc(releaseContext);
         }