Re: GTK deadlock in gtk_main
2010/8/3 Tomas Soltys tomas.sol...@range-software.com All right, so at the end it was my bug :) Thank you all for your explanations. Note also that part of the magic of gdk_threads_enter/leave that you can use on unix to use gtk functions in subthreads does not work on win32 (and also on OSX). I had really some bad headaches trying to use it in a cross platform way then I gave up and redesigned the application to use a lot of small idle functions executed when needed (returning false they are executed only once, and you can queue multiple idle functions also from different threads in a safe way since the idle function queue is protected by a lock) from the subthreads to update the GUI so that every GTK function is called on the main thread. This works quite well and does not require locking at all. -- Bye, Gabry ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
GTK deadlock in gtk_main
Hi all, I am not sure if this is a bug or just my misunderstanding of how the synchronization is done in GTK. Below is a simple test.c example in which the deadlock occurs. Basically program deadlocks itself when idle_func is done and control is returned to gtk_main. Thanks for your help in advance, Tomas #include stdlib.h #include glib.h #include gtk/gtk.h #include gdk/gdk.h static GStaticMutex customMutex = G_STATIC_MUTEX_INIT; static void custom_enter (void) { g_print (LOCK\n); g_static_mutex_lock (customMutex); } static void custom_leave (void) { g_static_mutex_unlock (customMutex); g_print (UNLOCK\n); } static gboolean on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) { gtk_widget_destroy (widget); gtk_main_quit (); return TRUE; } static gboolean idle_func (gpointer user_data) { /* Do something */ g_print (IDLE start\n); gtk_main_iteration_do (FALSE); g_print (IDLE end\n); return FALSE; } int main (int argc, char *argv[]) { GtkWidget *window; gdk_threads_set_lock_functions (custom_enter, custom_leave); g_thread_init (NULL); gdk_threads_init (); gdk_threads_enter (); gtk_init (argc, argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT(window), delete-event, G_CALLBACK(on_delete_event), NULL); g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, idle_func, NULL, NULL); gtk_widget_show (window); gtk_main (); gdk_threads_leave (); return EXIT_SUCCESS; } compile command: gcc test.c -o gtkTest `pkg-config --cflags --libs gtk+-2.0` LINUX dist.: Fedora 13 GTK version: 2.20.1 ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: GTK deadlock in gtk_main
Hi. You're having troubles because gtk_main_iteration_do() does it's own unlock/lock cycle. When your idle callback is executed, your mutex is unlocked. gtk_main_iteration_do() unlocks it again, executes whatever is there to be executed and locks it. Now control returns back to main loop, which tries to lock mutex and here you have your lock. Tadej -- Tadej Borovšak tadeboro.blogspot.com tadeb...@gmail.com tadej.borov...@gmail.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: GTK deadlock in gtk_main
Hi, So what you suggest is to have gdk_threads_enter and gdk_threads_leave at the beginning and at the end of the idle function? Is this really intended? Anyway, thanks for your help. Regards, Tomas Hi. You're having troubles because gtk_main_iteration_do() does it's own unlock/lock cycle. When your idle callback is executed, your mutex is unlocked. gtk_main_iteration_do() unlocks it again, executes whatever is there to be executed and locks it. Now control returns back to main loop, which tries to lock mutex and here you have your lock. Tadej -- Tadej Borovšak tadeboro.blogspot.com tadeb...@gmail.com tadej.borov...@gmail.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: GTK deadlock in gtk_main
Hi. So what you suggest is to have gdk_threads_enter and gdk_threads_leave at the beginning and at the end of the idle function? Is this really intended? Yes, this is how things should be done. But for your convenience, GDK provides a function that will wrap your idle callback in lock/unlock: gdk_threads_add_idle(). Tadej -- Tadej Borovšak tadeboro.blogspot.com tadeb...@gmail.com tadej.borov...@gmail.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: GTK deadlock in gtk_main
2010/8/4 Tomas Soltys tomas.sol...@range-software.com: Hi, So what you suggest is to have gdk_threads_enter and gdk_threads_leave at the beginning and at the end of the idle function? Is this really intended? YES, check http://library.gnome.org/devel/gdk/unstable/gdk3-Threads.html Idles, timeouts, and input functions from GLib, such as g_idle_add(), are executed outside of the main GTK+ lock. So, if you need to call GTK+ inside of such a callback, you must surround the callback with a gdk_threads_enter()/gdk_threads_leave() pair or use gdk_threads_add_idle_full() which does this for you. However, event dispatching from the mainloop is still executed within the main GTK+ lock, so callback functions connected to event signals like GtkWidget::button-press-event, do not need thread protection. Regards KC Anyway, thanks for your help. Regards, Tomas Hi. You're having troubles because gtk_main_iteration_do() does it's own unlock/lock cycle. When your idle callback is executed, your mutex is unlocked. gtk_main_iteration_do() unlocks it again, executes whatever is there to be executed and locks it. Now control returns back to main loop, which tries to lock mutex and here you have your lock. Tadej -- Tadej Borovšak tadeboro.blogspot.com tadeb...@gmail.com tadej.borov...@gmail.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list