diff options
Diffstat (limited to 'gobject/gobjectmodule.c')
-rw-r--r-- | gobject/gobjectmodule.c | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index 2dfd990..f6db634 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -25,6 +25,7 @@ #endif #include "pygobject-private.h" +#include "pythread.h" static PyObject *gerror_exc = NULL; static const gchar *pyginterface_type_id = "PyGInterface::type"; @@ -1454,14 +1455,29 @@ pyg_main_context_default (PyObject *unused) } +static int pyg_thread_state_tls_key = -1; + static int pyg_enable_threads (void) { #ifndef DISABLE_THREADING - PyEval_InitThreads(); - if (!g_threads_got_initialized) - g_thread_init(NULL); - pygobject_api_functions.threads_enabled = TRUE; + if (!pygobject_api_functions.threads_enabled) { + PyEval_InitThreads(); + if (!g_threads_got_initialized) + g_thread_init(NULL); + pygobject_api_functions.threads_enabled = TRUE; + pyg_thread_state_tls_key = PyThread_create_key(); + } + +#ifdef PYGIL_API_IS_BUGGY + { + PyThreadState* state; + state = PyGILState_GetThisThreadState(); + if ( state != NULL ) + PyThread_set_key_value(pyg_thread_state_tls_key, state); + } +#endif + return 0; #else PyErr_SetString(PyExc_RuntimeError, @@ -1470,6 +1486,56 @@ pyg_enable_threads (void) #endif } +static PyThreadState * +pyg_find_thread_state (void) +{ + PyThreadState* state; + + if (pyg_thread_state_tls_key == -1) + return NULL; + state = PyThread_get_key_value(pyg_thread_state_tls_key); + if ( state == NULL ) { + state = PyGILState_GetThisThreadState(); + if ( state != NULL ) + PyThread_set_key_value(pyg_thread_state_tls_key, state); + } + return state; +} + +static int +pyg_gil_state_ensure_py23 (void) +{ +#ifndef PYGIL_API_IS_BUGGY + return PyGILState_Ensure(); +#else + PyThreadState* state = pyg_find_thread_state(); + + if ( state == NULL ) + return PyGILState_LOCKED; + + if ( state == _PyThreadState_Current ) + return PyGILState_LOCKED; + else { + PyEval_RestoreThread(state); + return PyGILState_UNLOCKED; + } +#endif +} + +static void +pyg_gil_state_release_py23 (int flag) +{ +#ifndef PYGIL_API_IS_BUGGY + PyGILState_Release(flag); +#else + if (flag == PyGILState_UNLOCKED) { + PyThreadState* state = pyg_find_thread_state(); + if ( state != NULL ) + PyEval_ReleaseThread(state); + } +#endif +} + static PyObject * pyg_threads_init (PyObject *unused) { @@ -1811,7 +1877,9 @@ struct _PyGObject_Functions pygobject_api_functions = { pyg_flags_from_gtype, FALSE, /* threads_enabled */ - pyg_enable_threads + pyg_enable_threads, + pyg_gil_state_ensure_py23, + pyg_gil_state_release_py23 }; #define REGISTER_TYPE(d, type, name) \ |