@@ -254,7 +254,15 @@ static PyObject* py_request_stop(PyObject *self) {
254
254
static PyObject * py_main (PyObject * self , PyObject * args ) {
255
255
DEBUG_PRINT ("Initializing main." );
256
256
const char * argv [] = {TOSTRING (MODULE_NAME ), NULL };
257
+
258
+ // Initialize the Python interpreter
259
+ Py_Initialize ();
260
+
261
+ DEBUG_PRINT ("Initialized the Python interpreter." );
262
+
263
+ Py_BEGIN_ALLOW_THREADS
257
264
lf_reactor_c_main (1 , argv );
265
+ Py_END_ALLOW_THREADS
258
266
259
267
Py_INCREF (Py_None );
260
268
return Py_None ;
@@ -966,25 +974,22 @@ PyObject* convert_C_action_to_py(void* action) {
966
974
*/
967
975
PyObject *
968
976
get_python_function (string module , string class , int instance_id , string func ) {
969
-
970
- // Set if the interpreter is already initialized
971
- int is_initialized = 0 ;
972
-
973
- if (Py_IsInitialized ()) {
974
- is_initialized = 1 ;
975
- }
976
-
977
977
DEBUG_PRINT ("Starting the function start()." );
978
978
979
979
// Necessary PyObject variables to load the react() function from test.py
980
980
PyObject * pFileName , * pModule , * pDict , * pClasses , * pClass , * pFunc ;
981
981
982
982
PyObject * rValue ;
983
983
984
- // Initialize the Python interpreter
985
- Py_Initialize ();
986
-
987
- DEBUG_PRINT ("Initialized the Python interpreter." );
984
+ // According to
985
+ // https://docs.python.org/3/c-api/init.html#non-python-created-threads
986
+ // the following code does the following:
987
+ // - Register this thread with the interpreter
988
+ // - Acquire the GIL (Global Interpreter Lock)
989
+ // - Store (return) the thread pointer
990
+ // When done, we should always call PyGILState_Release(gstate);
991
+ PyGILState_STATE gstate ;
992
+ gstate = PyGILState_Ensure ();
988
993
989
994
// If the Python module is already loaded, skip this.
990
995
if (globalPythonModule == NULL ) {
@@ -993,8 +998,7 @@ get_python_function(string module, string class, int instance_id, string func) {
993
998
994
999
// Set the Python search path to be the current working directory
995
1000
char cwd [PATH_MAX ];
996
- if ( getcwd (cwd , sizeof (cwd )) == NULL )
997
- {
1001
+ if ( getcwd (cwd , sizeof (cwd )) == NULL ) {
998
1002
error_print_and_exit ("Failed to get the current working directory." );
999
1003
}
1000
1004
@@ -1004,7 +1008,7 @@ get_python_function(string module, string class, int instance_id, string func) {
1004
1008
1005
1009
Py_SetPath (wcwd );
1006
1010
1007
- DEBUG_PRINT ("Loading module %s in %s." , module , cwd );
1011
+ DEBUG_PRINT ("Loading module %s in %s." , module , cwd );
1008
1012
1009
1013
pModule = PyImport_Import (pFileName );
1010
1014
@@ -1020,6 +1024,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1020
1024
if (pDict == NULL ) {
1021
1025
PyErr_Print ();
1022
1026
error_print ("Failed to load contents of module %s." , module );
1027
+ /* Release the thread. No Python API allowed beyond this point. */
1028
+ PyGILState_Release (gstate );
1023
1029
return 1 ;
1024
1030
}
1025
1031
@@ -1042,6 +1048,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1042
1048
if (pClasses == NULL ){
1043
1049
PyErr_Print ();
1044
1050
error_print ("Failed to load class list \"%s\" in module %s." , class , module );
1051
+ /* Release the thread. No Python API allowed beyond this point. */
1052
+ PyGILState_Release (gstate );
1045
1053
return 1 ;
1046
1054
}
1047
1055
@@ -1051,6 +1059,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1051
1059
if (pClass == NULL ) {
1052
1060
PyErr_Print ();
1053
1061
error_print ("Failed to load class \"%s[%d]\" in module %s." , class , instance_id , module );
1062
+ /* Release the thread. No Python API allowed beyond this point. */
1063
+ PyGILState_Release (gstate );
1054
1064
return 1 ;
1055
1065
}
1056
1066
@@ -1066,6 +1076,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1066
1076
if (pFunc && PyCallable_Check (pFunc )) {
1067
1077
DEBUG_PRINT ("Calling function %s from class %s[%d]." , func , class , instance_id );
1068
1078
Py_INCREF (pFunc );
1079
+ /* Release the thread. No Python API allowed beyond this point. */
1080
+ PyGILState_Release (gstate );
1069
1081
return pFunc ;
1070
1082
}
1071
1083
else {
@@ -1086,11 +1098,8 @@ get_python_function(string module, string class, int instance_id, string func) {
1086
1098
1087
1099
DEBUG_PRINT ("Done with start()." );
1088
1100
1089
- if (is_initialized == 0 ) {
1090
- /* We are the first to initilize the Pyton interpreter. Destroy it when done. */
1091
- Py_FinalizeEx ();
1092
- }
1093
-
1094
1101
Py_INCREF (Py_None );
1102
+ /* Release the thread. No Python API allowed beyond this point. */
1103
+ PyGILState_Release (gstate );
1095
1104
return Py_None ;
1096
1105
}
0 commit comments