GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sun Oct 26, 2014 1:47 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: gtk_dialog_run deadlock
PostPosted: Tue Jan 10, 2012 8:12 pm 
Offline

Joined: Tue Jan 10, 2012 7:37 pm
Posts: 3
Good Evening,

I am trying to get a GTK+ application running (actually, it's kernelshark from Steven Rostedt) on my Ubuntu box, and all I got so far are reproducible deadlock when selecting Items in the menu bar. I have written a minimal application that shows the problem, see below.

Information about my box:
Quote:
nh2@ubuntu:~$ uname -a
Linux ubuntu 2.6.35-30-generic #61-Ubuntu SMP Tue Oct 11 15:29:15 UTC 2011 i686 GNU/Linux
nh2@ubuntu:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.10
DISTRIB_CODENAME=maverick
DISTRIB_DESCRIPTION="Ubuntu 10.10"

The problem seems to be related to the gtk_dialog_run() and the gdk_threads_enter/leave(). Setting a hook with gdk_threads_set_lock_functions(), I have seen that gtk_dialog_run() calls gdk_threads_enter() before leaving, which is also then called by the gtk_main() hence causing a deadlock.

What is the portable way for that kind of construct? To wrap the gtk_dialog_run() with a pair of gdk_threads_enter/leave()? This seems to do it. However, note that the very same program that deadlocks on one box, didn't on another Ubuntu box. This is somewhat surprising?

Another problem aside. I am unable to use a GMutex since the definition of the struct _GMutex definition isn't found anywhere by the compiler. Are some package missing, perhaps?


PS> Note that I have only a few hours of experience with GTK+ ... So I might be missing the obvious!

Thanks in advance,
/nh2

Code:
#include <gtk/gtk.h>
#include <signal.h>
#include <stdlib.h>

static void sig_end(int sig)
{
    fprintf(stderr, "Received SIGINT\n");
    exit(0);
}

GtkResponseType trace_dialog(GtkWindow *parent,
                 gchar *str)
{
    GtkWidget *dialog;
    GtkMessageType mtype = GTK_MESSAGE_INFO;
    GtkButtonsType btype = GTK_BUTTONS_CLOSE;
    int result;

    g_debug("trace_dialog");
    dialog = gtk_message_dialog_new(parent,
                    GTK_DIALOG_DESTROY_WITH_PARENT,
                    mtype,
                    btype,
                    "%s", str);
    g_debug("+gtk_dialog_run");
    result = gtk_dialog_run(GTK_DIALOG(dialog));
    g_debug("-gtk_dialog_run");

    gtk_widget_destroy(dialog);
    return result;
}


/* Callback for the clicked signal of the help about button */
static void
help_about_clicked (gpointer data)
{
    GtkWidget* window = data;

    trace_dialog(GTK_WINDOW(window),
             "My beautifull information");
}

int main(int argc, char* argv[])
{
    GtkWidget* window;
    GtkWidget* vbox;
    GtkWidget* menu_bar;
    GtkWidget* menu;
    GtkWidget* menu_item;
    GtkWidget* sub_item;

    g_thread_init(NULL);
    gdk_threads_init();
    gtk_init(&argc, &argv);

    signal(SIGINT, sig_end);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    vbox = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER (window), vbox);
    gtk_widget_show(vbox);

    menu_bar = gtk_menu_bar_new();
    gtk_box_pack_start(GTK_BOX (vbox), menu_bar, FALSE, FALSE, 0);
    gtk_widget_show(menu_bar);

    menu_item = gtk_menu_item_new_with_label("Help");
    gtk_widget_show(menu_item);
    gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), menu_item);
    menu = gtk_menu_new();    /* Don't need to show menus */

    /* --- Help - About Option --- */
    sub_item = gtk_menu_item_new_with_label("About");

    /* Add them to the menu */
    gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);

    /* We can attach the Quit menu item to our exit function */
    g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
                  G_CALLBACK (help_about_clicked),
                  (gpointer) window);

    /* We do need to show menu items */
    gtk_widget_show(sub_item);

    /* --- End Help Options --- */
    gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu);

    gdk_threads_enter();             
    gtk_widget_show (window);
    g_debug("main");
    gtk_main ();
    gdk_threads_leave();
}


Top
 Profile  
 
 Post subject: Re: gtk_dialog_run deadlock
PostPosted: Wed Jan 11, 2012 9:26 am 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 764
Location: UK
Hi,

To use GMutex you need to include the header <glib.h> and be able to link in with the Glib library and the gthread-2.0 library. If you have been able to compile and run the code you gave then you should be able to include <glib.h>. If not check that you have the development packages for Glib installed.

Your code runs as I would expect it to. Yes if you do call gtk_dialog_run() then it will run the dialog only and block every thing else. Please read the documentation on this http://developer.gnome.org/gtk/stable/GtkDialog.html#gtk-dialog-run. This is nothing to do with threads. I am unsure why you have initialised threads here as you have not used any threads at all.

I would avoid threads if I can and avoid calls to GTK/GDK from multiple threads if I do use threads. GTK/GDK is thread aware but not thread safe as only one thread at a time can call GTK/GDK, which is why we have the GDK locking system, it only works on X11 back ends and is fairly complex to use so not really suitable if you have just started programming with GTK (note you will also have a slight performance hit with all the locking and unlocking needed). If you have to use multiple threads then I would advise using one of the inter-process communication systems to pass information from the worker thread to the thread containing the GUI.

There are a few other things about your code. First you are using gtk_menu_bar_append() which is deprecated and you should use gtk_menu_shell_append() instead. You do not handle the "delete-event" signal of the window, by handling this and calling gtk_main_quit() you make exiting the application easier instead of manually having to terminate it from another application or the command line.

Although you have given the distribution and Linux kernel version you are using you do not give which version of GTK which for programming with GTK is more important. The answer we give does depend a lot on the GTK version when it comes to programming information.

To find out which version type out on the command line this for GTK 2.xx
Code:
pkg-config --modversion gtk+-2.0
and for GTK 3.xx
Code:
pkg-config --modversion gtk+-3.0


Every thing here is assumed you are using GTK 2.xx

As for kernelshark there is a package for it for Ubuntu Maverick. http://packages.ubuntu.com/maverick/kernelshark

_________________
E.


Top
 Profile  
 
 Post subject: Re: gtk_dialog_run deadlock
PostPosted: Thu Jan 12, 2012 4:48 am 
Offline

Joined: Tue Jan 10, 2012 7:37 pm
Posts: 3
Hi,

Thanks a lot for your time.

errol wrote:
To use GMutex you need to include the header <glib.h> and be able to link in with the Glib library and the gthread-2.0 library. If you have been able to compile and run the code you gave then you should be able to include <glib.h>. If not check that you have the development packages for Glib installed.

I found the problem. I have glib 2.26.1, it seems that there was a change starting from glib 2.30. Apparently I still have to use GStaticMutex for static mutex.

Quote:
Your code runs as I would expect it to. Yes if you do call gtk_dialog_run() then it will run the dialog only and block every thing else. Please read the documentation on this http://developer.gnome.org/gtk/stable/GtkDialog.html#gtk-dialog-run. This is nothing to do with threads. I am unsure why you have initialised threads here as you have not used any threads at all.

Yes, but once the dialog emits a response, it should then be closed. On my box, the app freezes after clicking on [Close]. As I explained, this is due to two consecutive gdk_threads_enter(),

There is no thread is this simple example, nor is "delete event" signal handled, etc. because I just wanted to focus on the main problem I am facing with the real app.

Quote:
Although you have given the distribution and Linux kernel version you are using you do not give which version of GTK which for programming with GTK is more important. The answer we give does depend a lot on the GTK version when it comes to programming information.

Yeah, sorry about that.
Code:
nh2@ubuntu:~$ pkg-config --modversion gtk+-2.0
2.22.0
nh2@ubuntu:~$ pkg-config --modversion glib-2.0
2.26.1


Quote:
As for kernelshark there is a package for it for Ubuntu Maverick. http://packages.ubuntu.com/maverick/kernelshark

I wanted to check out the latest version, for which I have only the source.


Top
 Profile  
 
 Post subject: Re: gtk_dialog_run deadlock
PostPosted: Thu Jan 12, 2012 9:52 am 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 764
Location: UK
The only changes with respect threads in Glib 2.26 to 2.30 is the addition of bit locks and additional atomic functions. So to use a static mutex even in Glib 2.30 you still have to use GStaticMutex. To use GMutext you need a pointer to it that must be initialised using g_mutext_new().

I compiled your code using Glib 2.30.2 and GTK 2.24.8 and the code worked fine. Maybe it could be a bug the the GTK version you are using, as you did say it did work on another Ubuntu box and you found uneven use of GDK enter/leave. There is a bug report on something similar sounding see https://bugzilla.gnome.org/show_bug.cgi?id=606796, but I as well as the person who closed the bug report do not think it is really a bug. Is there a load of information that you have not given that will definitely reproduce what you think is a bug?

_________________
E.


Top
 Profile  
 
 Post subject: Re: gtk_dialog_run deadlock
PostPosted: Sat Jan 14, 2012 5:15 am 
Offline

Joined: Tue Jan 10, 2012 7:37 pm
Posts: 3
No. As far as I can judge, I gave you all information already... Moving to glib 2.28.6 and gtk+ 2.24.4 solved automatically the problem. So I would tend for a bug in the previous gtk version I was using.

Thanks for you help!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group