Yasushi Shoji <yashi / yashi.com> wrote:
> using gtk_timeout_add turns into busy wait and it consumes most of the
> cpu time by itself.  That was why we, or I should say Masaki
> Fukushima, fukusima / goto.info.waseda.ac.jp, changed it to idle_add in
> ruby-list:16691.

Sorry for late response.  I've been absent this week.
Yes, I proposed to use rb_thread_wait_for(100ms).

> the problem, ruby keeps scheduling at least 100ms once it gets, was
> already known at the time.  He, Masaki Fukushima, also suggested using
> only one select but both Ruby and Gtk+ has a chance to wait on I/O, so
> he said it's difficult, if not impossible, to do it with current Ruby
> and Gtk+.

I also made a patch to integrate two `select' functions (gtk's
one  and ruby's) by using g_main_set_poll_func() and
rb_thread_select().  I attached the patch below.

But current rb_thread_select() has busy wait problem with more
than one thread.  So the patch is not applied to current
Ruby/Gtk.

---
Masaki Fukushima


--- rbgtk.c.orig	Sun Sep 12 22:34:29 1999
+++ rbgtk.c	Mon Sep 13 22:33:53 1999
@@ -2209,6 +2209,69 @@
     return Qtrue;
 }
 
+#if 0 /* rb_thread_select() may cause busy wait */
+
+#ifdef NATIVE_WIN32
+# error see gmain.c(g_poll) and implement WIN32 version of rbgtk_poll()
+#else /* not NATIVE_WIN32 */
+
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+
+static gint 
+rbgtk_poll (GPollFD *fds,
+	    guint    nfds,
+	    gint     timeout)
+{
+  struct timeval tv;
+  fd_set rset, wset, xset;
+  GPollFD *f;
+  int ready;
+  int maxfd = 0;
+
+  FD_ZERO (&rset);
+  FD_ZERO (&wset);
+  FD_ZERO (&xset);
+
+  for (f = fds; f < &fds[nfds]; ++f)
+    if (f->fd >= 0)
+      {
+	if (f->events & G_IO_IN)
+	  FD_SET (f->fd, &rset);
+	if (f->events & G_IO_OUT)
+	  FD_SET (f->fd, &wset);
+	if (f->events & G_IO_PRI)
+	  FD_SET (f->fd, &xset);
+	if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
+	  maxfd = f->fd;
+      }
+  tv.tv_sec = timeout / 1000;
+  tv.tv_usec = (timeout % 1000) * 1000;
+
+  ready = rb_thread_select (maxfd + 1, &rset, &wset, &xset,
+			    timeout == -1 ? NULL : &tv);
+  if (ready > 0)
+    for (f = fds; f < &fds[nfds]; ++f)
+      {
+	f->revents = 0;
+	if (f->fd >= 0)
+	  {
+	    if (FD_ISSET (f->fd, &rset))
+	      f->revents |= G_IO_IN;
+	    if (FD_ISSET (f->fd, &wset))
+	      f->revents |= G_IO_OUT;
+	    if (FD_ISSET (f->fd, &xset))
+	      f->revents |= G_IO_PRI;
+	  }
+      }
+
+  return ready;
+}
+#endif /* not NATIVE_WIN32 */
+
+#endif /* 0 */
+
 /*
  * Init
  */
@@ -2398,6 +2461,9 @@
 #else
     /* use timeout to avoid busy wait */
     gtk_timeout_add(100, (GtkFunction)idle, 0);
+#endif
+#if 0
+    g_main_set_poll_func(rbgtk_poll);
 #endif
 
     rb_global_variable(&warn_handler);