summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Trowbridge <trow@ximian.com>2003-01-08 22:06:08 +0000
committerJon Trowbridge <trow@src.gnome.org>2003-01-08 22:06:08 +0000
commit2e05f66b0007e874d65ae984e6baa92df54e41e7 (patch)
tree6bcb4dc961e8e809e46de8c59891c8c5a903bbd9
parent89083a7ab53881da21787ce43653ac1d61b434d0 (diff)
downloadpygtk-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--ChangeLog19
-rw-r--r--gobject/pygobject.c8
-rw-r--r--gtk/gdk.override31
-rw-r--r--gtk/gtk-types.c18
-rw-r--r--pygobject.c8
5 files changed, 68 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index b9e7a486..5dd298e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);