@@ -253,7 +253,15 @@ static PyObject* py_request_stop(PyObject *self) {
253
253
static PyObject * py_main (PyObject * self , PyObject * args ) {
254
254
DEBUG_PRINT ("Initializing main." );
255
255
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
256
263
lf_reactor_c_main (1 , argv );
264
+ Py_END_ALLOW_THREADS
257
265
258
266
Py_INCREF (Py_None );
259
267
return Py_None ;
@@ -965,25 +973,22 @@ PyObject* convert_C_action_to_py(void* action) {
965
973
*/
966
974
PyObject *
967
975
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
-
976
976
DEBUG_PRINT ("Starting the function start()." );
977
977
978
978
// Necessary PyObject variables to load the react() function from test.py
979
979
PyObject * pFileName , * pModule , * pDict , * pClasses , * pClass , * pFunc ;
980
980
981
981
PyObject * rValue ;
982
982
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 ();
987
992
988
993
// If the Python module is already loaded, skip this.
989
994
if (globalPythonModule == NULL ) {
@@ -992,8 +997,7 @@ get_python_function(string module, string class, int instance_id, string func) {
992
997
993
998
// Set the Python search path to be the current working directory
994
999
char cwd [PATH_MAX ];
995
- if ( getcwd (cwd , sizeof (cwd )) == NULL )
996
- {
1000
+ if ( getcwd (cwd , sizeof (cwd )) == NULL ) {
997
1001
error_print_and_exit ("Failed to get the current working directory." );
998
1002
}
999
1003
@@ -1019,6 +1023,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1019
1023
if (pDict == NULL ) {
1020
1024
PyErr_Print ();
1021
1025
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 );
1022
1028
return 1 ;
1023
1029
}
1024
1030
@@ -1041,6 +1047,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1041
1047
if (pClasses == NULL ){
1042
1048
PyErr_Print ();
1043
1049
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 );
1044
1052
return 1 ;
1045
1053
}
1046
1054
@@ -1050,6 +1058,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1050
1058
if (pClass == NULL ) {
1051
1059
PyErr_Print ();
1052
1060
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 );
1053
1063
return 1 ;
1054
1064
}
1055
1065
@@ -1065,6 +1075,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1065
1075
if (pFunc && PyCallable_Check (pFunc )) {
1066
1076
DEBUG_PRINT ("Calling function %s from class %s[%d]." , func , class , instance_id );
1067
1077
Py_INCREF (pFunc );
1078
+ /* Release the thread. No Python API allowed beyond this point. */
1079
+ PyGILState_Release (gstate );
1068
1080
return pFunc ;
1069
1081
}
1070
1082
else {
@@ -1085,11 +1097,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1085
1097
1086
1098
DEBUG_PRINT ("Done with start()." );
1087
1099
1088
- if (is_initialized == 0 ) {
1089
- /* We are the first to initilize the Pyton interpreter. Destroy it when done. */
1090
- Py_FinalizeEx ();
1091
- }
1092
-
1093
1100
Py_INCREF (Py_None );
1101
+ /* Release the thread. No Python API allowed beyond this point. */
1102
+ PyGILState_Release (gstate );
1094
1103
return Py_None ;
1095
1104
}
0 commit comments