Re: Glib 2.32.x, Win32 and threading



On Tue, 03 Jul 2012 20:59:11 +0200
"Martin Schlemmer" <Martin Schlemmer nwu ac za> wrote:
> Hi,
> 
> Bit long, sorry.
> 
> I build my own GTK+ stack with MinGW (TDM-4.6.1) and have been using
> 2.16 and Glib 2.28 (with Gtk2-Perl bindings mostly) for a long time,
> then switched to GTK+ 2.24 when that started to get stable enough.
> Wanting to start with WebKit I switched to Glib 2.30 to be able to
> use GObject-Introspection from Dieter's git repo.
> 
> This still worked fine, but needing later G-O-I interfaces from
> WebKit, I tried to build 1.8 which needs Glib 2.31 or later, so I
> switched to Glib 2.32.3, and this is where my problems started.
> 
> All threaded Gtk2-Perl apps locked up on startup and I initially
> thought it was a Gtk2-Perl problem, but building the example from the
> FAQ:
> 
> http://developer.gnome.org/gtk-faq/stable/x481.html
> 
> result in the same problem. The easiest way to reproduce it is to
> start the example and then move the window which immediately results
> in a deadlock.

GTK+/GDK has never been thread-safe on Win32.  If the GDK global lock
appeared to work for you in the past you just got lucky.  From the
documentation at
http://developer.gnome.org/gdk/stable/gdk-Threads.html :

"GTK+ is "thread aware" but not thread safe — it provides a global lock
controlled by gdk_threads_enter()/gdk_threads_leave() which protects
all use of GTK+. That is, only one thread can use GTK+ at any given
time.

"Unfortunately the above holds with the X11 backend only. With the Win32
backend, GDK calls should not be attempted from multiple threads at
all."

In due course gdk_threads_init()/gdk_threads_enter()/gdk_threads_leave()
are to be deprecated in the X11 backend, although that is not relevant
to your code.

Win32 users (and in due course X11 users) should use
g_idle_add()/g_idle_add_full() to send event callbacks from worker
threads to the gui thread which invoke the GTK+ functions you want to
call. With glib < 2.32, you will need to call g_thread_init()
(g_thread_init() is not needed on glib >= 2.32 and is a no-op.)  This
also happens to be a much cleaner design than using the GDK global lock.

The FAQ on this is, I agree, misleading - I should file a documentation
bug.

Chris


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]