Hi,

You should be aware when call GTK+ function in another thread, if you do this 
from another thread, GTK+ is likely not send commands to the X server. When you 
run a dialog in the main thread, main loop is blocked, so the dialog's window 
remain displayed until a response was given (eg. button was clicked). But in 
you code, you run the dialog outside the main loop (main thread) the main loop 
of course is not blocked, and it fails to show the dialog. See 
http://library.gnome.org/devel/gtk-faq/stable/x499.html on howto send GTK+ 
funcs to the main loop. Another way is to provide mechanism so you can run the 
dialog from the main thread by using such as condition variable (GCond).

-- ajhwb

--- ml...@mlake.net wrote:

From: Marshall Lake <ml...@mlake.net>
To: gtk-app-devel-list@gnome.org
Subject: GTK & threads
Date: Wed, 8 Jul 2009 09:38:30 -0400 (EDT)


I posted this on gtk-list but in the hope of catching a wider audience ...

I'm developing a program(s) which runs in the client/server environment. 
I'm using GTK, sockets, and threads.  (GTK and threads only on the client 
side.)  I don't have very much experience using threads and this is the 
first time I've tried to call GTK functions within a thread, and I'm 
having problems.  I've tried different ways of approaching the problem but 
can't seem to get anywhere.  I suspect there's something I don't 
understand about thread processing or I'm under some misconception. 
Maybe someone can help me?  Any help is much appreciated.

I get the following errors when trying to run the code below (the errors 
show up when the program calls gtk_dialog_run() in the thread 
(Wait4Challenge()):

src/xcb_io.c:242: process_responses: Assertion `(((long) 
(dpy->last_request_read) - (long) (dpy->request)) <= 0)' failed.
Fatal IO error 0 (Success) on X server :0.0.


void *
Wait4Challenge () {
       int wsock, x, port = 0, listensock, connected;
       char buffer[5000], *msg[5], challenger[50];

       listensock = -1;
       for (x = 0; x < 5; x++)
           msg[x] = NULL;

       wsock = get_connection (SOCK_STREAM, port, &listensock);

       connected = 1;
       while (connected) {
           GtkWidget *dialog;
           int response;

           if (sock_gets (wsock, &buffer[0], sizeof (buffer)) < 0) {
               msg[0] = "There is a problem with the server.\n\n";
               outMessage (msg);
               connected = 0;
           }

           if (buffer[0] == 'R')
               connected = 0;

           if (buffer[0] != 'C')
               continue;

           strcpy (&challenger[0], &buffer[1]);

           gdk_threads_enter ();

           dialog = gtk_message_dialog_new (GTK_WINDOW (mainwin), 
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
                               GTK_BUTTONS_YES_NO, "%s has challenged you to a 
game.  Do you wish to play?", challenger);
           gtk_window_set_title (GTK_WINDOW (dialog), "Play Challenger?");
           response = gtk_dialog_run (GTK_DIALOG (dialog));
           gtk_widget_destroy (dialog);

           gdk_flush();
           gdk_threads_leave ();

           if (response == GTK_RESPONSE_YES) {
               sock_puts (wsock, "OK\n");
               connected = 0;
           }
           else {
               sock_puts (wsock, "NO\n");
               for (x = 0; x < 5; x++)
                   msg[x] = NULL;
               continue;
           }
       }

       shutdown (wsock, SHUT_RDWR);
       close (wsock);
       return (NULL);
}

int
main (int argc, char *argv[]) {
       g_thread_init (NULL);
       gdk_threads_init ();

       gtk_init (&argc, &argv);

       mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
       gtk_widget_set_usize (mainwin, WINSIZEX, WINSIZEY);
       gtk_widget_realize (mainwin);

       gtk_widget_add_events (mainwin, GDK_BUTTON_PRESS_MASK);
       gtk_signal_connect (GTK_OBJECT (mainwin), "delete_event", 
GTK_SIGNAL_FUNC (delete_event), 0);

       gtk_widget_show_all (mainwin);

       if (!g_thread_create (Wait4Challenge, NULL, FALSE, NULL))
           syslog (LOG_INFO, "error trying to create new thread");

       gdk_threads_enter ();

       gtk_main ();

       gdk_flush();
       gdk_threads_leave ();

       return 0;
}

-- 
Marshall Lake -- ml...@mlake.net -- http://mlake.net
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list




_____________________________________________________________
Listen to KNAC, Hit the Home page and Tune In Live! ---> http://www.knac.com
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to