After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 580800 - GTK threading and deadlocks on win32
GTK threading and deadlocks on win32
Status: RESOLVED DUPLICATE of bug 60620
Product: gtk+
Classification: Platform
Component: Backend: X11
2.16.x
Other All
: Normal major
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2009-04-29 19:49 UTC by Jonathan Olson
Modified: 2009-04-29 22:52 UTC
See Also:
GNOME target: ---
GNOME version: 2.25/2.26



Description Jonathan Olson 2009-04-29 19:49:45 UTC
Please describe the problem:
I have been working on porting a ruby-gnome application from the older 1.8 green threads environment to the newer ruby 1.9 native thread virtual machine.  In doing so, I've encountered compatibility issues between the GTK+ threading and Win32 threading model which make reliable multi-threaded operation difficult to impossible on Win32.

The GTK+ event model and threading model uses a single event thread dispatcher combined with a GTK toolkit mutex lock to manage concurrent access from multiple threads.  For any thread other than the event thread to access to the GTK toolkit, the recommended procedure is to call the following methods to lock and release this mutex.

gdk_threads_enter();
// do something with GTK
gdk_threads_leave();

This works quite well in X-Windows or MacOSX Quartz environments where any thread can directly access the GUI.

Unfortunately, WIN32 uses a much different threading model which is largely undocumented and poorly understood.

1) The WIN32 event model requires the thread which calls CreateWindow() to process all events for that window.  In WIN32, either the GTK event thread must create all windows or there must be a separate event loop for EVERY thread which creates windows!

2) If any thread other than the creator of the window invokes win32 functions such as ShowWIndow(), SendMessage(), SetWindowPos(), etc., WIN32 puts the request on the window owner's event queue and blocks the caller until the request completes.

All this means that any multi-threaded GTK application written to use the standard gdk_threads_enter()/gdk_threads_exit() sequence will deadlock whenever a thread other than the GTK event thread makes any GTK calls with the global GTK mutex locked, since the GTK mutex is held by the thread which is blocked in the WIN32 system call.

Currently the only work-around is to post operations which may block GTK to the event loop using a call like g_timeout_add().

Ideally, the logic to post certain operations to the main event loop should be integrated into the WIN32 GDK port.  Note that only certain WIN32 system calls actually block until the window's owner processes the message.  However the blocking behavior of WIN32 doesn't seem to be documented in any MS documentation so determining which calls must be forwarded to the event loop requires trial and error.

Steps to reproduce:
1. create or resize window from non event-loop thread with gdk_threads_enter() mutex locked.
2. 
3. 


Actual results:
application deadlocks.

Expected results:


Does this happen every time?
yes

Other information:
Comment 1 Tor Lillqvist 2009-04-29 22:52:47 UTC
Well known and documented fact.

*** This bug has been marked as a duplicate of 60620 ***