From 328b8849ee7e8db2cb02c710a2fadaaac20d0da3 Mon Sep 17 00:00:00 2001 From: Paul Pogonyshev Date: Wed, 27 Aug 2008 21:37:30 +0000 Subject: Bug 547633 – cannot create new threads when pygtk is used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-08-28 Paul Pogonyshev Bug 547633 – cannot create new threads when pygtk is used * glib/pyglib.c (pyglib_notify_on_enabling_threads): New function. (pyglib_enable_threads): Invoke all callbacks added with new pyglib_notify_on_enabling_threads(). * gobject/gobjectmodule.c (pyg_note_threads_enabled): New function (callback for new pyglib_notify_on_enabling_threads()). (PYGLIB_MODULE_START): Initialize 'pygobject_api_functions.threads_enabled' and also watch for thread being enabled later on. svn path=/trunk/; revision=952 --- ChangeLog | 14 ++++++++++++++ glib/pyglib.c | 25 ++++++++++++++++++++++++- glib/pyglib.h | 2 ++ gobject/gobjectmodule.c | 9 +++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e7f6dc7..ded2d7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-08-28 Paul Pogonyshev + + Bug 547633 – cannot create new threads when pygtk is used + + * glib/pyglib.c (pyglib_notify_on_enabling_threads): New function. + (pyglib_enable_threads): Invoke all callbacks added with new + pyglib_notify_on_enabling_threads(). + + * gobject/gobjectmodule.c (pyg_note_threads_enabled): New + function (callback for new pyglib_notify_on_enabling_threads()). + (PYGLIB_MODULE_START): Initialize + 'pygobject_api_functions.threads_enabled' and also watch for + thread being enabled later on. + 2008-08-28 Paul Pogonyshev Bug 547088 – wrap g_content_types_get_registered() diff --git a/glib/pyglib.c b/glib/pyglib.c index 2bb0d7b..4d8ea8b 100644 --- a/glib/pyglib.c +++ b/glib/pyglib.c @@ -135,13 +135,25 @@ pyglib_enable_threads(void) "pyglib threading disabled at compile time"); return FALSE; } + +void +pyglib_notify_on_enabling_threads(PyGLibThreadsEnabledFunc callback) +{ + /* Ignore, threads cannot be enabled. */ +} + #else + +static GSList *thread_enabling_callbacks = NULL; + /* Enable threading; note that the GIL must be held by the current * thread when this function is called */ gboolean pyglib_enable_threads(void) { + GSList *callback; + g_return_val_if_fail (_PyGLib_API != NULL, FALSE); if (_PyGLib_API->threads_enabled) @@ -153,9 +165,20 @@ pyglib_enable_threads(void) _PyGLib_API->threads_enabled = TRUE; pyglib_thread_state_tls_key = PyThread_create_key(); - + + for (callback = thread_enabling_callbacks; callback; callback = callback->next) + ((PyGLibThreadsEnabledFunc) callback->data) (); + + g_slist_free(thread_enabling_callbacks); return TRUE; } + +void +pyglib_notify_on_enabling_threads(PyGLibThreadsEnabledFunc callback) +{ + if (callback && !pyglib_threads_enabled()) + thread_enabling_callbacks = g_slist_append(thread_enabling_callbacks, callback); +} #endif int diff --git a/glib/pyglib.h b/glib/pyglib.h index 66ac139..6b476e0 100644 --- a/glib/pyglib.h +++ b/glib/pyglib.h @@ -28,6 +28,7 @@ G_BEGIN_DECLS +typedef void (*PyGLibThreadsEnabledFunc) (void); typedef void (*PyGLibThreadBlockFunc) (void); void pyglib_init(void); @@ -35,6 +36,7 @@ void pyglib_init_internal(PyObject *api); PyGILState_STATE pyglib_gil_state_ensure(void); void pyglib_gil_state_release(PyGILState_STATE state); int pyglib_enable_threads(void); +void pyglib_notify_on_enabling_threads(PyGLibThreadsEnabledFunc callback); gboolean pyglib_error_check(GError **error); gboolean pyglib_gerror_exception_check(GError **error); PyObject *pyglib_register_exception_for_domain(gchar *name, diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index 29ccdf2..95d1b76 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -1812,6 +1812,12 @@ pygobject_enable_threads(void) return 0; } +static void +pyg_note_threads_enabled(void) +{ + pygobject_api_functions.threads_enabled = TRUE; +} + static PyObject * pyg_signal_accumulator_true_handled(PyObject *unused, PyObject *args) { @@ -2594,5 +2600,8 @@ PYGLIB_MODULE_START(_gobject, "gobject._gobject") /* signal registration recognizes this special accumulator 'constant' */ _pyg_signal_accumulator_true_handled_func = \ PyDict_GetItemString(d, "signal_accumulator_true_handled"); + + pygobject_api_functions.threads_enabled = pyglib_threads_enabled(); + pyglib_notify_on_enabling_threads(pyg_note_threads_enabled); } PYGLIB_MODULE_END -- cgit