Re: GTK & threads




Just to let everyone know ...

I discovered that I was having an issue with my socket logic which was the main cause of my problem outlined below. Once I resolved that issue and incorporated g_idle_add() along with GCond & GMutex into my code everything is working.



(When you reply, please add CC to devel mailing list, so other peoples know it's progress and may help you more).

--- mlake mlake net wrote:

From: Marshall Lake <mlake mlake net>
To: Ardhan Madras <ajhwb knac com>
Subject: Re: GTK & threads
Date: Wed, 8 Jul 2009 12:21:34 -0400 (EDT)


Thanks for your feedback.  I think what you say is likely my problem.



On Wed, 8 Jul 2009, Ardhan Madras wrote:

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


--
Marshall Lake -- mlake mlake net -- http://mlake.net



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