Re: GTK & threads



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Marshall Lake wrote:

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.

If I'm not mistaken, X isn't tread-safe, which may be the root cause of the
specific error message that you're seeing. The implication is that any call
which may invoke X should be done from the main thread. When an auxiliary thread
does need to do some drawing, one way to achieve that would be with a
g_idle_add(), which will get invoked by the main thread when there is nothing
else to do.

Hope this helps,

- -Greg

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;
}



- --
+---------------------------------------------------------------------+

Please also check the log file at "/dev/null" for additional information.
                (from /var/log/Xorg.setup.log)

| Greg Hosler                                   ghosler redhat com    |
+---------------------------------------------------------------------+
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkpU99MACgkQ404fl/0CV/QP0gCdFjSI6ASkdRfr70QXpy5amjQn
z28AoKG55bgTe2t9dUERYc1G8wxPULaT
=DMvb
-----END PGP SIGNATURE-----



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