From 04c7abba11abb54fe8f43b027ed42ed4ff46aa82 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 29 Jul 2010 00:52:34 -0400 Subject: [PATCH] Work around deadlock in unix-streams test --- gio/tests/unix-streams.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/gio/tests/unix-streams.c b/gio/tests/unix-streams.c index 50b2d8c..b8b383b 100644 --- a/gio/tests/unix-streams.c +++ b/gio/tests/unix-streams.c @@ -34,6 +34,17 @@ int writer_pipe[2], reader_pipe[2]; GCancellable *writer_cancel, *reader_cancel, *main_cancel; GMainLoop *loop; +static gboolean +cancel_main (gpointer data) +{ + GCancellable *main_cancel = data; + + g_cancellable_cancel (main_cancel); + + return FALSE; +} + + static gpointer writer_thread (gpointer user_data) { @@ -64,7 +75,17 @@ writer_thread (gpointer user_data) if (g_cancellable_is_cancelled (writer_cancel)) { - g_cancellable_cancel (main_cancel); + /* FIXME: directly calling g_cancellable_cancel (main_cancel) here + * leads to sporadic deadlock, because it will try to wake up the + * main context, for which it needs to acquire the main context lock. + * This lock may be held by the main loop running in the main thread, + * and it may be held while the main thread is blocking in + * fd_source_finalize -> g_cancellable_disconnect + * until the ::cancelled callbacks have run. + * + * Work around by deferring the cancellation to a timeout. + */ + g_timeout_add (0, cancel_main, main_cancel); g_object_unref (out); return NULL; } -- 2.7.4