Re: GTK & threads



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

--- mlake mlake net wrote:

From: Marshall Lake <mlake 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 -- mlake 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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]