On Nov 16, 2007 9:54 PM, Drake W. [email protected] wrote:
Incidentally, I’m still curious as to the purpose of the presently
existing 100-ms empty timeout that is automatically started in the
current Ruby-GNOME2 C code anyway. It seems to be a shim of some sort
to keep the main loop iterating, but for what? So that unsafe UI
updates from other threads still sort-of-work (i.e., redraw) even
though they’ll sometimes crash anyway?
As far as I understand the code, it seems to be the core of the
solution found to the impossible cooperation between ruby’s mainloop
(the thing which schedules ruby threads) and glib’s mainloop (the
thing which triggers timeouts, idles, emit signals). As far as I know,
there is no native collaboration mechanism between the two’s, and
that’s the core of our problem; I guess other bindings may have
similar problems… indeed Mathieu pointed out the pygtk ticket[1],
which would indicate they’re using a timeout, but that seems to be for
a slightly different problem: it is a problem with kernel signals (e.g
SIGINT, SIGSTOP, SIGCONT etc) and native threads - with rg2 we don’t
use native threads, because Ruby doesn’t use native threads (AFAIK).
Actually, collaboration between gtk and application threads may end up
being very different if involved threads are native (py) or at
interpreter level (rb).
Unfortunately, this problem is going to get worse and worse, because
processor occupancy during idle times is getting tracked more closer
now that environment friendliness is a hype.
Now, to answer more precisely your question, we have a problem: most
of the main developers of rg2 seem to have too little time to get
involved in the discussions, at least in this ML (I know that many
japanese developers also say that they have trouble reading/writing
english); and when it goes so deeply to tough problems, it is
sometimes hard to understand fully what’s going on only from the
source code. When I looked in the source code for solving my threading
problem, rg2 was setting a custom poll function, and installed an
empty timeout, with this source code comment:
/* This forces the custom g_poll function to be called
* with a minimum timeout of 100ms so that the GMainLoop
* iterates from time to time even if there is no event.
* Another way could be to add a wakeup pipe to the selectable
* fds and than wake up the select only when needed.
*/
g_timeout_add(100, empty_timeout_func, NULL);
Here’s how I understood the problem back then:
-
so that Ruby threads are scheduled, a custom poll function was used
(e.g. GTK calls a custom poll function instead of the normal OS poll
call, when its mainloop blocks on a list of file descriptors to wait
for events); this poll function used rb_thread_select instead of the
native poll (or select) call, and rb_thread_select actually schedules
other Ruby threads when they have work to do, instead of just waiting
on the specified file descriptors list (which would prevent ruby
threads from being scheduled)
-
incidentally, this created problems when some GTK code is called not
from the main Ruby thread (this is a complicated matter which is
already explained in one of my previous mails), which is why GTK code
must be called only from the main Ruby thread
Now, that doesn’t explain the needs for this empty timeout. As often
with Ruby, I have problems finding the API documentation, this time
for rb_thread_select :/. Last time I asked for assistance here about
Ruby API documentation, Masao indicated that README.EXT from ruby
tarball is often useful to extension developers, but it seems to not
document rb_thread_select. An assumption can be that rb_thread_select
will not necessarily schedule all the threads, or that non main
threads will somehow “lock” the main thread, hence the need to pump an
event into the file descriptors lists to force rb_thread_select to
return - but that doesn’t really make sense anyway…
Now, according to rg2’s svn, Kouhei recently switched from the custom
poll function approach, to installing a GSource (which calls
rb_thread_schedule from the “prepare” callback).
Working file: rbglib_mainloop.c
r2707 | ktou | 2007-11-17 04:50:39 +0100 (Sat, 17 Nov 2007) | 2 lines
- src/rbglib_mainloop.c: used GSource not poll func overriding.
I see that the “prepare” callback currently sets the returned timeout
value to 1 millisecond, which would indicate that the source tells GTK
that it needs to be rechecked after 1 millisecond only. If I’m
understanding this correctly (trunk untested), it means rg2 is almost
doing active-wait now 
Actually,
http://library.gnome.org/devel/glib/unstable/glib-The-Main-Event-Loop.html
seems to be a worthwhile read to understand the big picture of
GSource. There’s even some explanation geared at integrating the GTK
mainloop to an external mainloop, that may be of some help for rg2?
Kouhei, would you be so kind in participating to the discussion, at
least explaining what’s your modification, what problem are you trying
to solve, and its impact on multi-threading in rg2 applications if you
know it? In the current situation, where I guess some discussion
occurs in the japanese ML only, it is very frustrating and
disappointing, because on this ML, we are left in the dark… I think
that more and more non japanese people interested in ruby/gtk will be
more and more frustrated, if we are only left as powerless spectators
in the actual rg2 development. I can even see that this subject was
discussed between you and Masao in japanese:
http://sourceforge.net/mailarchive/forum.php?thread_name=20071112.235142.1141224146.kou%40cozmixng.org&forum_name=ruby-gnome2-devel-ja
I think that the status of non japanese developers/contributors on rg2
should be clarified. It is not fair that we are considered second-tier
citizens, or then let’s just consider rg2 is a japanese developers
only project and we’ll be able to make decisions according to that
fact. You see that here, this thread discussed that matter; if you
make some related source code modifications, we should not be left
outside.
Thanks!
[1] http://dev.laptop.org/ticket/4680
–
Guillaume C. - http://zarb.org/~gc/