summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Dahlin <johan@src.gnome.org>2004-09-28 15:03:43 +0000
committerJohan Dahlin <johan@src.gnome.org>2004-09-28 15:03:43 +0000
commit44d583628cb7ec1b08d5d7c38bca11479b192424 (patch)
tree339a42392c32ea16ddf79dd583e1657ba998f662
parent66ebbb785442fd411a251ac262763a47252cf272 (diff)
downloadpygobject-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.c65
-rw-r--r--gobject/pygobject-private.h10
-rw-r--r--gobject/pygobject.h13
-rw-r--r--tests/test_thread.py4
-rw-r--r--tests/testhelpermodule.c2
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;
}