diff options
| author | Jon Trowbridge <trow@ximian.com> | 2003-01-08 22:06:08 +0000 |
|---|---|---|
| committer | Jon Trowbridge <trow@src.gnome.org> | 2003-01-08 22:06:08 +0000 |
| commit | 2e05f66b0007e874d65ae984e6baa92df54e41e7 (patch) | |
| tree | 6bcb4dc961e8e809e46de8c59891c8c5a903bbd9 | |
| parent | 89083a7ab53881da21787ce43653ac1d61b434d0 (diff) | |
| download | pygtk-2e05f66b0007e874d65ae984e6baa92df54e41e7.tar.gz | |
Wrap Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS around the call to
2003-01-08 Jon Trowbridge <trow@ximian.com>
* pygobject.c (pygobject_dealloc): Wrap
Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS around the call to
g_object_unref. We need to do this because the object finalizers
might trigger other code that has to acquire the interpreter lock,
causing a deadlock. Fixes #102756.
* gtk/gtk-types.c (pygtk_style_helper_dealloc): Wrap the call to
g_object_unref in Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS.
This should let us avoid other instances of bug #102756.
(pygtk_style_helper_setitem): Ditto.
(pygtk_tree_model_row_dealloc): Ditto.
(pygtk_tree_model_row_iter_dealloc): Ditto.
* gtk/gdk.override (pygdk_unblock_threads, pygdk_unblock_threads):
Restored David I Lehn's patch (#98380). His patch was fine ---
it just caused bug #102756 to emerge.
| -rw-r--r-- | ChangeLog | 19 | ||||
| -rw-r--r-- | gobject/pygobject.c | 8 | ||||
| -rw-r--r-- | gtk/gdk.override | 31 | ||||
| -rw-r--r-- | gtk/gtk-types.c | 18 | ||||
| -rw-r--r-- | pygobject.c | 8 |
5 files changed, 68 insertions, 16 deletions
@@ -1,3 +1,22 @@ +2003-01-08 Jon Trowbridge <trow@ximian.com> + + * pygobject.c (pygobject_dealloc): Wrap + Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS around the call to + g_object_unref. We need to do this because the object finalizers + might trigger other code that has to acquire the interpreter lock, + causing a deadlock. Fixes #102756. + + * gtk/gtk-types.c (pygtk_style_helper_dealloc): Wrap the call to + g_object_unref in Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS. + This should let us avoid other instances of bug #102756. + (pygtk_style_helper_setitem): Ditto. + (pygtk_tree_model_row_dealloc): Ditto. + (pygtk_tree_model_row_iter_dealloc): Ditto. + + * gtk/gdk.override (pygdk_unblock_threads, pygdk_unblock_threads): + Restored David I Lehn's patch (#98380). His patch was fine --- + it just caused bug #102756 to emerge. + 2003-01-07 Johan Dahlin <jdahlin@async.com.br> * pygtk.py (_get_available_versions): Rewrite using glob.glob, diff --git a/gobject/pygobject.c b/gobject/pygobject.c index ca41dd8a..3affe469 100644 --- a/gobject/pygobject.c +++ b/gobject/pygobject.c @@ -216,7 +216,10 @@ pygobject_dealloc(PyGObject *self) self->hasref = TRUE; g_object_set_qdata_full(obj, pygobject_ownedref_key, self, pyg_destroy_notify); + + Py_BEGIN_ALLOW_THREADS; g_object_unref(obj); + Py_END_ALLOW_THREADS; /* we ref the type, so subtype_dealloc() doesn't kill off our * instance's type. */ @@ -231,8 +234,11 @@ pygobject_dealloc(PyGObject *self) return; } - if (obj && !self->hasref) /* don't unref the GObject if it owns us */ + if (obj && !self->hasref) { /* don't unref the GObject if it owns us */ + Py_BEGIN_ALLOW_THREADS; g_object_unref(obj); + Py_END_ALLOW_THREADS; + } PyObject_ClearWeakRefs((PyObject *)self); diff --git a/gtk/gdk.override b/gtk/gdk.override index e46d6cef..7a5211ee 100644 --- a/gtk/gdk.override +++ b/gtk/gdk.override @@ -56,36 +56,39 @@ override gdk_threads_init noargs */ #ifdef ENABLE_PYGTK_THREADING static GStaticPrivate pythreadstate_key = G_STATIC_PRIVATE_INIT; -static GStaticPrivate counter_key = G_STATIC_PRIVATE_INIT; -#define INITIAL_LOCK_COUNT 1 +static GStaticPrivate lock_count_key = G_STATIC_PRIVATE_INIT; +static PyInterpreterState *pyinterpstate = NULL; static void pygdk_block_threads (void) { - gint counter = GPOINTER_TO_INT(g_static_private_get(&counter_key)); + gint lock_count = GPOINTER_TO_INT(g_static_private_get(&lock_count_key)); - if (counter == INITIAL_LOCK_COUNT) { - PyThreadState *_save; + if (lock_count == 0) { + PyThreadState *_save; _save = g_static_private_get(&pythreadstate_key); + if (_save == NULL) { + _save = PyThreadState_New(pyinterpstate); + } Py_BLOCK_THREADS; } - counter--; - g_static_private_set(&counter_key, GINT_TO_POINTER(counter), NULL); + lock_count++; + g_static_private_set(&lock_count_key, GINT_TO_POINTER(lock_count), NULL); } static void pygdk_unblock_threads (void) { - gint counter = GPOINTER_TO_INT(g_static_private_get(&counter_key)); + gint lock_count = GPOINTER_TO_INT(g_static_private_get(&lock_count_key)); - counter++; - if (counter == INITIAL_LOCK_COUNT) { - PyThreadState *_save; + lock_count--; + if (lock_count == 0) { + PyThreadState *_save; Py_UNBLOCK_THREADS; g_static_private_set(&pythreadstate_key, _save, NULL); } - g_static_private_set(&counter_key, GINT_TO_POINTER(counter), NULL); + g_static_private_set(&lock_count_key, GINT_TO_POINTER(lock_count), NULL); } #endif @@ -96,7 +99,11 @@ _wrap_gdk_threads_init(PyObject *self) /* register gdk thread block/unblock routines with gobjectmodule */ pyg_set_thread_block_funcs (pygdk_block_threads, pygdk_unblock_threads); + PyEval_InitThreads(); gdk_threads_init(); + g_static_private_set(&lock_count_key, GINT_TO_POINTER(1), NULL); + + pyinterpstate = PyThreadState_Get()->interp; Py_INCREF(Py_None); return Py_None; diff --git a/gtk/gtk-types.c b/gtk/gtk-types.c index 94985db0..825a9443 100644 --- a/gtk/gtk-types.c +++ b/gtk/gtk-types.c @@ -55,7 +55,9 @@ _pygtk_style_helper_new(GtkStyle *style, int type, gpointer array) static void pygtk_style_helper_dealloc(PyGtkStyleHelper_Object *self) { + Py_BEGIN_ALLOW_THREADS; g_object_unref(self->style); + Py_END_ALLOW_THREADS; PyObject_DEL(self); } @@ -126,7 +128,11 @@ pygtk_style_helper_setitem(PyGtkStyleHelper_Object *self, int pos, PyErr_SetString(PyExc_TypeError, "can only assign a GdkGC"); return -1; } - if (array[pos]) g_object_unref(array[pos]); + if (array[pos]) { + Py_BEGIN_ALLOW_THREADS; + g_object_unref(array[pos]); + Py_END_ALLOW_THREADS; + } array[pos] = GDK_GC(g_object_ref(pygobject_get(value))); return 0; } @@ -139,7 +145,11 @@ pygtk_style_helper_setitem(PyGtkStyleHelper_Object *self, int pos, "can only assign a GdkPixmap or None"); return -1; } - if (array[pos]) g_object_unref(array[pos]); + if (array[pos]) { + Py_BEGIN_ALLOW_THREADS; + g_object_unref(array[pos]); + Py_END_ALLOW_THREADS; + } if (value != Py_None) array[pos] = GDK_PIXMAP(g_object_ref(pygobject_get(value))); else @@ -790,7 +800,9 @@ _pygtk_tree_model_row_new(GtkTreeModel *model, GtkTreeIter *iter) static void pygtk_tree_model_row_dealloc(PyGtkTreeModelRow *self) { + Py_BEGIN_ALLOW_THREADS; g_object_unref(self->model); + Py_END_ALLOW_THREADS; PyObject_DEL(self); } @@ -998,7 +1010,9 @@ _pygtk_tree_model_row_iter_new(GtkTreeModel *model, GtkTreeIter *parent_iter) static void pygtk_tree_model_row_iter_dealloc(PyGtkTreeModelRowIter *self) { + Py_BEGIN_ALLOW_THREADS; g_object_unref(self->model); + Py_END_ALLOW_THREADS; PyObject_DEL(self); } diff --git a/pygobject.c b/pygobject.c index ca41dd8a..3affe469 100644 --- a/pygobject.c +++ b/pygobject.c @@ -216,7 +216,10 @@ pygobject_dealloc(PyGObject *self) self->hasref = TRUE; g_object_set_qdata_full(obj, pygobject_ownedref_key, self, pyg_destroy_notify); + + Py_BEGIN_ALLOW_THREADS; g_object_unref(obj); + Py_END_ALLOW_THREADS; /* we ref the type, so subtype_dealloc() doesn't kill off our * instance's type. */ @@ -231,8 +234,11 @@ pygobject_dealloc(PyGObject *self) return; } - if (obj && !self->hasref) /* don't unref the GObject if it owns us */ + if (obj && !self->hasref) { /* don't unref the GObject if it owns us */ + Py_BEGIN_ALLOW_THREADS; g_object_unref(obj); + Py_END_ALLOW_THREADS; + } PyObject_ClearWeakRefs((PyObject *)self); |
