GNOME Bugzilla – Bug 426729
gdk_threads_init causes hangs on XP
Last modified: 2007-04-26 22:47:59 UTC
The following simple program does not run, it displays a window but does not draw anything in the window: #!/usr/bin/perl use Gtk2 qw( -init -threads-init ); die "Glib::Object thread safety failed" unless Glib::Object->set_threadsafe(1); my $win = Gtk2::Window->new(); my $but = Gtk2::Button->new("Start Thread"); $win->add($but); $win->show_all; # Start the main loop. Gtk2->main; exit 1; If you remove the "-threads-init" line then the program works fine. I also tried using the Gtk2::Gdk::Threads->init and Gtk2->init calls instead; the results are the same. I have the latest version of everything: ActiveState Perl 5.8.8-820 Gtk2.pm 1.141 Glib.pm 1.142 Cairo.pm 1.021 ExtUtils-Depends.pm 0.205 ExtUtils-PkgConfig.pm 1.07 Gtk2 2.10.11 (windows runtime from http://gladewin32.sourceforge.net/modules/wfdownloads/) On a fresh install of Windows XP SP2 (I did install older versions of the packages which I removed and upgraded to the most recent versions to test for this bug report). Of course this program does nothing useful, but it is stripped down from a larger more complicated program where I am using threads. Notice that this program doesn't use threads, it simply initializes them. My large program has exactly the same behavior and it does use threads. Thanks for all your hard work! Jason
Just to be sure I went to http://www.lostmind.de/gtk2-perl/ and downloaded the versions of ActiveState, Gtk2 run-time, and perl modules from his website. I then removed (uninstalled and deleted c:\Perl and c:\GTK) Gtk and Perl from my system and installed those newly downloaded versions. The bug presents the same problem: window is displayed but nothing is drawn in the window. If I remove the "-threads-init" then everything works. Gtk 2.8.20 ActiveState 5.8.8 819 are the only differences from the original report.
I do not see this behavior on linux (and have no access to a windows system). Can you verify whether a similar C program exhibits the same behavior on windows? Something along these lines: #include <gtk/gtk.h> int main (int argc, char *argv[]) { GtkWidget * window; GtkWidget * button; gtk_threads_init (); gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); button = gtk_button_new_with_label ("Click me"); gtk_container_add (GTK_CONTAINER (window), button); gtk_widget_show_all (window); gtk_main (); return 0; }
The C code above doesn't link. Instead I used the following code and tested on a Windows XP machine (using Visual C Express 2005 to compile): #include <gtk/gtk.h> int main (int argc, char *argv[]) { GtkWidget * window; GtkWidget * button; g_thread_init (NULL); gdk_threads_init (); gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); button = gtk_button_new_with_label ("Click me"); gtk_container_add (GTK_CONTAINER (window), button); gtk_widget_show_all (window); gtk_main (); return 0; } This produces the same problem as before: the GtkWindow is displayed but the contents are not drawn and the application is non-responsive. I tested with Gtk 2.8.20 (the most recent version supported by the binary distributions of gtk2-perl) and Gtk 2.10.11 (the most recent binary/devel download from http://gladewin32.sourceforge.net/modules/wfdownloads/). Jason
Just to verify, I added some print statements and the code is making it to the gtk_main() call (which should be obvious since the window is displayed). An attempt to click the close button (top right Windows 'X') causes Windows to display the "This Program is Not Responding" error message. The default behavior is normally the window is destroyed but the application continues to run. Jason
When the line for gdk_threads_init (); is removed the code works. There seems to be no problems related to g_thread_init (NULL);.
Looks like a gtk+ problem then.
Hmm. I agree that it is a bit surprising that the simple program in comment #3 hangs. I will debug this and figure out the cause. But read on... Hopefully you know that using gdk functions from multiple threads won't work anyway on win32, and this is not going to be fixed anytime soon. So whether this simple sample program that calls gdk_threads_init(), but still doesn't actually create any threads, works or not is rather pointless. A "real" program that would call gdk_threads_init() because it uses gdk from multiple threads won't work anyway.
The problem in the sample program is that it doesn't call gdk_threads_enter() before calling gtk_main(). Compare with the first sample program on the page http://developer.gnome.org/doc/API/2.0/gdk/gdk-Threads.html . Once I add a gdk_threads_enter() call (and a corrsponding gdk_threads_leave() call after gtk_main(), but that presumably is not strictly necessary), the program works fine. But as I said in my previous comment, a "real" multithreaded gdk-using (gtk+-using) program will not work on Win32 anyway. It is commonly said that using gtk+ from multiple threads is not a good idea on X11 either, even if it would work. The usual recommendation is that it's fine to use threads to do non-interactive computations or whatever, but gtk+ calls should be done in the main thread only. Use g_timeout_add() or g_idle_add() to schedule functions to be called in the main thread. The corrected sample program looks like this: #include <gtk/gtk.h> int main (int argc, char *argv[]) { GtkWidget * window; GtkWidget * button; g_thread_init (NULL); gdk_threads_init (); gdk_threads_enter (); gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); button = gtk_button_new_with_label ("Click me"); gtk_container_add (GTK_CONTAINER (window), button); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); gtk_widget_show_all (window); gtk_main (); gdk_threads_leave (); return 0; }