Permalink
Browse files

threads: Do not release the GDK lock if it hasn't been acquired yet

Since GLib ≥ 2.41, attempting to release an unlocked mutex will abort(),
as it happens on most systems already.

Given the lack of proper documentation on how to use GDK with threads,
there is code in the wild that does:

    gdk_threads_init ();
    gdk_init ();

    ...

    gtk_main ();

instead of the idiomatically correct:

    gdk_threads_init ();
    gdk_threads_enter ();

    gtk_init ();

    ...

    gtk_main ();

    ...

    gdk_threads_leave ();

Which means that gtk_main() will try to release the GDK lock, and thus
trigger an error from GLib.

we cannot really fix all the wrong code everywhere, and since it does
not cost us anything, we can work around the issue inside GDK itself, by
trying to acquire the GDK lock inside gdk_threads_leave() with
trylock().

https://bugzilla.gnome.org/show_bug.cgi?id=735428
  • Loading branch information...
ebassi authored and Matthias Clasen committed Aug 26, 2014
1 parent 0f0fc59 commit 79c3ff3c4ed74bbcc820dac2d5180fa4d48d55ec
Showing with 20 additions and 0 deletions.
  1. +20 −0 gdk/gdk.c
View
@@ -555,6 +555,26 @@ gdk_threads_impl_lock (void)
static void
gdk_threads_impl_unlock (void)
{
+ /* we need a trylock() here because trying to unlock a mutex
+ * that hasn't been locked yet is:
+ *
+ * a) not portable
+ * b) fail on GLib ≥ 2.41
+ *
+ * trylock() will either succeed because nothing is holding the
+ * GDK mutex, and will be unlocked right afterwards; or it's
+ * going to fail because the mutex is locked already, in which
+ * case we unlock it as expected.
+ *
+ * this is needed in the case somebody called gdk_threads_init()
+ * without calling gdk_threads_enter() before calling gtk_main().
+ * in theory, we could just say that this is undefined behaviour,
+ * but our documentation has always been *less* than explicit as
+ * to what the behaviour should actually be.
+ *
+ * see bug: https://bugzilla.gnome.org/show_bug.cgi?id=735428
+ */
+ g_mutex_trylock (&gdk_threads_mutex);
g_mutex_unlock (&gdk_threads_mutex);
}

0 comments on commit 79c3ff3

Please sign in to comment.