From: DaVinci <bombadil / wanadoo.es>
Subject: [ruby-talk:04013] Slow GTK+ and Tk bindings
Date: Fri, 14 Jul 2000 15:41:16 +0200

> 	I have probed samples of Gtk+ and Tk for Ruby.
> 
> 	Why are they so slow?.

any example?

using ruby 1.5.x and g_main_set_poll_func() patch by Masaki Fukushima
should fix 100ms prob. pointed while ago on this list.

regards,
--
         yashi

--- rbgtk.c.orig Sun May 21 22:48:58 2000 +++ rbgtk.c Mon May 22 01:28:50 2000 @@ -2309,6 +2309,75 @@ /* * Gtk module */ +#include <version.h> +#if RUBY_VERSION_CODE >= 154 +# define USE_POLL_FUNC 1 +#else +# undef USE_POLL_FUNC /* rb_thread_select() may cause busy wait */ +#endif + +#ifdef NATIVE_WIN32 +# undef USE_POLL_FUNC /* I don't know whether this works for win32. */ +#endif + +#ifdef USE_POLL_FUNC + +#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; +} + +#else /* !USE_POLL_FUNC */ + static gint idle() { @@ -2323,6 +2392,8 @@ return Qtrue; } +#endif /* !USE_POLL_FUNC */ + /* * Init */ @@ -2510,11 +2581,15 @@ gItemFactory = rb_define_class_under(mGtk, "ItemFactory", rb_cData); Init_gtk_calendar(); -#if 1 - gtk_idle_add((GtkFunction)idle, 0); +#ifdef USE_POLL_FUNC + g_main_set_poll_func(rbgtk_poll); #else +# if 1 + gtk_idle_add((GtkFunction)idle, 0); +# else /* use timeout to avoid busy wait */ gtk_timeout_add(100, (GtkFunction)idle, 0); +# endif #endif rb_global_variable(&warn_handler);