diff options
author | Johan Dahlin <johan@src.gnome.org> | 2004-09-28 15:03:43 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2004-09-28 15:03:43 +0000 |
commit | 44d583628cb7ec1b08d5d7c38bca11479b192424 (patch) | |
tree | 339a42392c32ea16ddf79dd583e1657ba998f662 | |
parent | 66ebbb785442fd411a251ac262763a47252cf272 (diff) | |
download | pygobject-44d583628cb7ec1b08d5d7c38bca11479b192424.tar.gz pygobject-44d583628cb7ec1b08d5d7c38bca11479b192424.tar.xz pygobject-44d583628cb7ec1b08d5d7c38bca11479b192424.zip |
Apply slighly modified fix from bug 149845PYGTK_2_3_97
This is make threading usable for both users of the threading
module and users that requires interaction with threads from
other extension modules.
-rw-r--r-- | gobject/gobjectmodule.c | 65 | ||||
-rw-r--r-- | gobject/pygobject-private.h | 10 | ||||
-rw-r--r-- | gobject/pygobject.h | 13 | ||||
-rw-r--r-- | tests/test_thread.py | 4 | ||||
-rw-r--r-- | tests/testhelpermodule.c | 2 |
5 files changed, 43 insertions, 51 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index f6db634..55b4298 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -34,6 +34,8 @@ GQuark pyginterface_type_key = 0; static void pyg_flags_add_constants(PyObject *module, GType flags_type, const gchar *strip_prefix); +static gboolean use_gil_state_api = FALSE; + /* -------------- GDK threading hooks ---------------------------- */ /** @@ -1458,8 +1460,11 @@ pyg_main_context_default (PyObject *unused) static int pyg_thread_state_tls_key = -1; static int -pyg_enable_threads (void) +pyg_enable_threads () { + if (getenv ("PYGTK_USE_GIL_STATE_API")) + use_gil_state_api = TRUE; + #ifndef DISABLE_THREADING if (!pygobject_api_functions.threads_enabled) { PyEval_InitThreads(); @@ -1468,15 +1473,12 @@ pyg_enable_threads (void) pygobject_api_functions.threads_enabled = TRUE; pyg_thread_state_tls_key = PyThread_create_key(); } - -#ifdef PYGIL_API_IS_BUGGY - { + if (PYGIL_API_IS_BUGGY && !use_gil_state_api) { PyThreadState* state; state = PyGILState_GetThisThreadState(); if ( state != NULL ) PyThread_set_key_value(pyg_thread_state_tls_key, state); } -#endif return 0; #else @@ -1490,13 +1492,13 @@ 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 ) { + if (state == NULL) { state = PyGILState_GetThisThreadState(); - if ( state != NULL ) + if (state != NULL) PyThread_set_key_value(pyg_thread_state_tls_key, state); } return state; @@ -1505,42 +1507,43 @@ pyg_find_thread_state (void) 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 (PYGIL_API_IS_BUGGY && !use_gil_state_api) { + PyThreadState* state = pyg_find_thread_state(); - if ( state == _PyThreadState_Current ) - return PyGILState_LOCKED; - else { - PyEval_RestoreThread(state); - return PyGILState_UNLOCKED; + if (state == NULL) + return PyGILState_LOCKED; + + if (state == _PyThreadState_Current) + return PyGILState_LOCKED; + else { + PyEval_RestoreThread(state); + return PyGILState_UNLOCKED; + } + } else { + return PyGILState_Ensure(); } -#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); + if (PYGIL_API_IS_BUGGY && !use_gil_state_api) { + if (flag == PyGILState_UNLOCKED) { + PyThreadState* state = pyg_find_thread_state(); + if (state != NULL) + PyEval_ReleaseThread(state); + } + } else { + PyGILState_Release(flag); } -#endif } static PyObject * -pyg_threads_init (PyObject *unused) +pyg_threads_init (PyObject *unused, PyObject *args, PyObject *kwargs) { if (pyg_enable_threads()) return NULL; + Py_INCREF(Py_None); return Py_None; } @@ -1562,7 +1565,7 @@ static PyMethodDef pygobject_functions[] = { { "io_add_watch", (PyCFunction)pyg_io_add_watch, METH_VARARGS|METH_KEYWORDS }, { "source_remove", pyg_source_remove, METH_VARARGS }, { "main_context_default", (PyCFunction)pyg_main_context_default, METH_NOARGS }, - { "threads_init", (PyCFunction)pyg_threads_init, METH_NOARGS }, + { "threads_init", (PyCFunction)pyg_threads_init, METH_VARARGS|METH_KEYWORDS }, { NULL, NULL, 0 } }; diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h index eb4b107..d826f92 100644 --- a/gobject/pygobject-private.h +++ b/gobject/pygobject-private.h @@ -21,21 +21,13 @@ extern struct _PyGObject_Functions pygobject_api_functions; #define pyg_threads_enabled (pygobject_api_functions.threads_enabled) -#ifndef PYGIL_API_IS_BUGGY -#define pyg_gil_state_ensure() (pygobject_api_functions.threads_enabled? (PyGILState_Ensure()) : 0) -#define pyg_gil_state_release(state) G_STMT_START { \ - if (pygobject_api_functions.threads_enabled) \ - PyGILState_Release(state); \ - } G_STMT_END -#else + #define pyg_gil_state_ensure() (pygobject_api_functions.threads_enabled? (pygobject_api_functions.gil_state_ensure()) : 0) #define pyg_gil_state_release(state) G_STMT_START { \ if (pygobject_api_functions.threads_enabled) \ pygobject_api_functions.gil_state_release(state); \ } G_STMT_END -#endif - #define pyg_begin_allow_threads \ G_STMT_START { \ PyThreadState *_save = NULL; \ diff --git a/gobject/pygobject.h b/gobject/pygobject.h index 4c99031..ec06faa 100644 --- a/gobject/pygobject.h +++ b/gobject/pygobject.h @@ -9,7 +9,9 @@ /* Work around bugs in PyGILState api fixed in 2.4.0a4 */ #if PY_HEXVERSION < 0x020400A4 -#define PYGIL_API_IS_BUGGY +#define PYGIL_API_IS_BUGGY TRUE +#else +#define PYGIL_API_IS_BUGGY FALSE #endif /* PyGClosure is a _private_ structure */ @@ -214,21 +216,12 @@ struct _PyGObject_Functions *_PyGObject_API; #define pyg_threads_enabled (_PyGObject_API->threads_enabled) -#ifndef PYGIL_API_IS_BUGGY -#define pyg_gil_state_ensure() (_PyGObject_API->threads_enabled? (PyGILState_Ensure()) : 0) -#define pyg_gil_state_release(state) G_STMT_START { \ - if (_PyGObject_API->threads_enabled) \ - PyGILState_Release(state); \ - } G_STMT_END -#else #define pyg_gil_state_ensure() (_PyGObject_API->threads_enabled? (_PyGObject_API->gil_state_ensure()) : 0) #define pyg_gil_state_release(state) G_STMT_START { \ if (_PyGObject_API->threads_enabled) \ _PyGObject_API->gil_state_release(state); \ } G_STMT_END -#endif - #define pyg_begin_allow_threads \ G_STMT_START { \ PyThreadState *_save = NULL; \ diff --git a/tests/test_thread.py b/tests/test_thread.py index a40b99f..d58a30f 100644 --- a/tests/test_thread.py +++ b/tests/test_thread.py @@ -1,7 +1,11 @@ +import os import unittest from common import gobject, gtk, testhelper +# Enable PyGILState API +os.environ['PYGTK_USE_GIL_STATE_API'] = '' + gobject.threads_init() class TestThread(unittest.TestCase): diff --git a/tests/testhelpermodule.c b/tests/testhelpermodule.c index 6c787d9..7eb7867 100644 --- a/tests/testhelpermodule.c +++ b/tests/testhelpermodule.c @@ -110,7 +110,7 @@ static void test_thread_class_init (TestThreadClass *klass) g_signal_new ("from-thread", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (TestThreadClass, from_thread), NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, - test_thread_enum_get_type()); + test_thread_enum_get_type ()); klass->emit_signal = test_thread_emit_signal; } |