GNOME Bugzilla – Bug 642968
GCancellable deadlock when disconnecting
Last modified: 2013-10-18 18:23:55 UTC
Apparently you can't call g_cancellable_disconnect() from a ::cancelled handler. Here's the stack trace:
+ Trace 226060
Thread 1 (Thread 0x7fe8ba0ac960 (LWP 19089))
A debugging session is active.
Created attachment 181632 [details] Minimal test case Here's a test case. It should go in gio/tests. Makefile.am changes: diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am index 5f49e6c..97710d6 100644 --- a/gio/tests/Makefile.am +++ b/gio/tests/Makefile.am @@ -45,6 +45,7 @@ TEST_PROGS += \ gdbus-message \ socket \ pollable \ + cancellable \ $(NULL) if OS_UNIX @@ -212,6 +213,9 @@ socket_LDADD = $(progs_ldadd) pollable_SOURCE = pollable.c pollable_LDADD = $(progs_ldadd) +cancellable_SOURCE = cancellable.c +cancellable_LDADD = $(progs_ldadd) + contexts_SOURCES = contexts.c contexts_LDADD = $(progs_ldadd) \ $(top_builddir)/gthread/libgthread-2.0.la
From the disconnect docs: * Additionally, in the event that a * signal handler is currently running, this call will block until the * handler has finished. Calling this function from a * #GCancellable::cancelled signal handler will therefore result in a * deadlock. This waiting is to protect the connecting side, so that its code doesn't run after the callback has been disconnected. Why do you need to disconnect at the cancellation event? After a cancellation everything will wind back to a normal error return from the cancellable method, thats generally the place where disconnection happens.
(In reply to comment #2) > From the disconnect docs: > > * Additionally, in the event that a > * signal handler is currently running, this call will block until the > * handler has finished. Calling this function from a > * #GCancellable::cancelled signal handler will therefore result in a > * deadlock. > > This waiting is to protect the connecting side, so that its code doesn't run > after the callback has been disconnected. Ah, yeah, I forgot about that. Hmm, I'm wondering if we can do something clever here. At least we should use g_warning() (or even g_critical()) instead of deadlocking so it's clear that it's a programming error... > Why do you need to disconnect at the cancellation event? After a cancellation > everything will wind back to a normal error return from the cancellable method, > thats generally the place where disconnection happens. The cancellation triggers a D-Bus method return. This includes cleanup and the cleanup includes disconnecting the signal... pretty much run of the mill.. I mean, this is something I expect lots of people to do... right?
Btw, for gnome-shell I worked around this by just moving the code into an idle handler...
more discussion and such in the newer bug so duping forward *** This bug has been marked as a duplicate of bug 705395 ***