Skip to content

Commit faf0fb0

Browse files
committed
Merge remote-tracking branch 'origin/master' into windows-c-target
2 parents 36d3122 + b56a2ea commit faf0fb0

File tree

1 file changed

+28
-19
lines changed

1 file changed

+28
-19
lines changed

org.lflang/src/lib/Python/pythontarget.c

+28-19
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,15 @@ static PyObject* py_request_stop(PyObject *self) {
253253
static PyObject* py_main(PyObject *self, PyObject *args) {
254254
DEBUG_PRINT("Initializing main.");
255255
const char *argv[] = {TOSTRING(MODULE_NAME), NULL };
256+
257+
// Initialize the Python interpreter
258+
Py_Initialize();
259+
260+
DEBUG_PRINT("Initialized the Python interpreter.");
261+
262+
Py_BEGIN_ALLOW_THREADS
256263
lf_reactor_c_main(1, argv);
264+
Py_END_ALLOW_THREADS
257265

258266
Py_INCREF(Py_None);
259267
return Py_None;
@@ -965,25 +973,22 @@ PyObject* convert_C_action_to_py(void* action) {
965973
*/
966974
PyObject*
967975
get_python_function(string module, string class, int instance_id, string func) {
968-
969-
// Set if the interpreter is already initialized
970-
int is_initialized = 0;
971-
972-
if (Py_IsInitialized()) {
973-
is_initialized = 1;
974-
}
975-
976976
DEBUG_PRINT("Starting the function start().");
977977

978978
// Necessary PyObject variables to load the react() function from test.py
979979
PyObject *pFileName, *pModule, *pDict, *pClasses, *pClass, *pFunc;
980980

981981
PyObject *rValue;
982982

983-
// Initialize the Python interpreter
984-
Py_Initialize();
985-
986-
DEBUG_PRINT("Initialized the Python interpreter.");
983+
// According to
984+
// https://docs.python.org/3/c-api/init.html#non-python-created-threads
985+
// the following code does the following:
986+
// - Register this thread with the interpreter
987+
// - Acquire the GIL (Global Interpreter Lock)
988+
// - Store (return) the thread pointer
989+
// When done, we should always call PyGILState_Release(gstate);
990+
PyGILState_STATE gstate;
991+
gstate = PyGILState_Ensure();
987992

988993
// If the Python module is already loaded, skip this.
989994
if (globalPythonModule == NULL) {
@@ -992,8 +997,7 @@ get_python_function(string module, string class, int instance_id, string func) {
992997

993998
// Set the Python search path to be the current working directory
994999
char cwd[PATH_MAX];
995-
if ( getcwd(cwd, sizeof(cwd)) == NULL)
996-
{
1000+
if ( getcwd(cwd, sizeof(cwd)) == NULL) {
9971001
error_print_and_exit("Failed to get the current working directory.");
9981002
}
9991003

@@ -1019,6 +1023,8 @@ get_python_function(string module, string class, int instance_id, string func) {
10191023
if (pDict == NULL) {
10201024
PyErr_Print();
10211025
error_print("Failed to load contents of module %s.", module);
1026+
/* Release the thread. No Python API allowed beyond this point. */
1027+
PyGILState_Release(gstate);
10221028
return 1;
10231029
}
10241030

@@ -1041,6 +1047,8 @@ get_python_function(string module, string class, int instance_id, string func) {
10411047
if (pClasses == NULL){
10421048
PyErr_Print();
10431049
error_print("Failed to load class list \"%s\" in module %s.", class, module);
1050+
/* Release the thread. No Python API allowed beyond this point. */
1051+
PyGILState_Release(gstate);
10441052
return 1;
10451053
}
10461054

@@ -1050,6 +1058,8 @@ get_python_function(string module, string class, int instance_id, string func) {
10501058
if (pClass == NULL) {
10511059
PyErr_Print();
10521060
error_print("Failed to load class \"%s[%d]\" in module %s.", class, instance_id, module);
1061+
/* Release the thread. No Python API allowed beyond this point. */
1062+
PyGILState_Release(gstate);
10531063
return 1;
10541064
}
10551065

@@ -1065,6 +1075,8 @@ get_python_function(string module, string class, int instance_id, string func) {
10651075
if (pFunc && PyCallable_Check(pFunc)) {
10661076
DEBUG_PRINT("Calling function %s from class %s[%d].", func , class, instance_id);
10671077
Py_INCREF(pFunc);
1078+
/* Release the thread. No Python API allowed beyond this point. */
1079+
PyGILState_Release(gstate);
10681080
return pFunc;
10691081
}
10701082
else {
@@ -1085,11 +1097,8 @@ get_python_function(string module, string class, int instance_id, string func) {
10851097

10861098
DEBUG_PRINT("Done with start().");
10871099

1088-
if (is_initialized == 0) {
1089-
/* We are the first to initilize the Pyton interpreter. Destroy it when done. */
1090-
Py_FinalizeEx();
1091-
}
1092-
10931100
Py_INCREF(Py_None);
1101+
/* Release the thread. No Python API allowed beyond this point. */
1102+
PyGILState_Release(gstate);
10941103
return Py_None;
10951104
}

0 commit comments

Comments
 (0)