Salome HOME
[EDF30399] : Steer directory hosting replay files
[modules/kernel.git] / src / Container / SALOME_CPythonHelper.cxx
index c1032a298229d1149091142a2b3d8ce84028e042..8fae563f3a251b60c975a7c64ed90f0ec566db8c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2019-2024  CEA, EDF, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // Author : Anthony GEAY (EDF R&D)
 
 #include "SALOME_CPythonHelper.hxx"
+#include "PythonCppUtils.hxx"
+
+SALOME_CPythonHelper *SALOME_CPythonHelper::_CPYTHONHELPER_INSTANCE = nullptr;
+
+#if PY_VERSION_HEX < 0x03050000
+static char*
+Py_EncodeLocale(const wchar_t *arg, size_t *size)
+{
+  return _Py_wchar2char(arg, size);
+}
+static wchar_t*
+Py_DecodeLocale(const char *arg, size_t *size)
+{
+  return _Py_char2wchar(arg, size);
+}
+#endif
+
+SALOME_CPythonHelper *SALOME_CPythonHelper::Singleton()
+{
+  if(!_CPYTHONHELPER_INSTANCE)
+    _CPYTHONHELPER_INSTANCE = new SALOME_CPythonHelper;
+  return _CPYTHONHELPER_INSTANCE;
+}
+
+void SALOME_CPythonHelper::KillSingleton()
+{
+  delete _CPYTHONHELPER_INSTANCE;
+  _CPYTHONHELPER_INSTANCE = nullptr;
+}
 
 void SALOME_CPythonHelper::initializePython(int argc, char *argv[])
 {
   Py_Initialize();
+#if PY_VERSION_HEX < 0x03070000
   PyEval_InitThreads();
+#endif
   wchar_t **changed_argv = new wchar_t*[argc]; // Setting arguments
   for (int i = 0; i < argc; i++)
     changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
@@ -46,8 +77,17 @@ void SALOME_CPythonHelper::initializePython(int argc, char *argv[])
   PyDict_SetItemString(_globals,"socket",socket);
 }
 
+void SALOME_CPythonHelper::allowPythonCallsFromDifferentThread() const
+{
+#if PY_VERSION_HEX < 0x03070000
+  PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
+#endif
+  PyEval_SaveThread(); /* Release the thread state */
+}
+
 void SALOME_CPythonHelper::registerToSalomePiDict(const std::string& processName, long pid) const
 {
+  AutoGIL agil;
   PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
   if(!mod)
     return;
@@ -66,6 +106,7 @@ void SALOME_CPythonHelper::registerToSalomePiDict(const std::string& processName
 
 std::vector<long> SALOME_CPythonHelper::evalVL(const std::string& pyCode) const
 {
+  AutoGIL agil;
   PyObject* code(Py_CompileString(pyCode.c_str(),"evalVL.py", Py_eval_input));
   PyObject *res(PyEval_EvalCode( code, _globals, _locals));
   Py_DECREF(code);
@@ -82,6 +123,7 @@ std::vector<long> SALOME_CPythonHelper::evalVL(const std::string& pyCode) const
 
 std::string SALOME_CPythonHelper::evalS(const std::string& pyCode) const
 {
+  AutoGIL agil;
   PyObject* code(Py_CompileString(pyCode.c_str(),"evalS.py", Py_eval_input));
   PyObject *res(PyEval_EvalCode( code, _globals, _locals));
   Py_DECREF(code);
@@ -90,9 +132,13 @@ std::string SALOME_CPythonHelper::evalS(const std::string& pyCode) const
   return ret;
 }
 
+
 SALOME_CPythonHelper::~SALOME_CPythonHelper()
 {
   // _globals is borrowed ref -> do nothing
+
+  /*if(_locals){ auto refcount_locals = Py_REFCNT(_locals); }*/
+  AutoGIL agil;
   Py_XDECREF(_locals);
   Py_XDECREF(_pickler);
 }