Quoth Kouhei S. [email protected], on 2007-11-23 12:36:50 +0900:
And I don’t want to add a new API like main_thread_do_async.
If adding sources to the main loop from Ruby code is safe, we can make
sure to wake up the main loop ourselves (preferably inside
Ruby-GNOME2, but not necessarily in C) after adding each source.
If this is true, that is good. That is the most compatible with old
Ruby-GNOME2 programs, and does not need a new function.
But adding sources to the main loop from Ruby code may not be safe,
as a result of GLib not knowing how to do appropriate locking.
If this is true, old Ruby-GNOME2 programs that use idle blocks that
way are in trouble no matter what we do.
Then either Ruby-GNOME2 needs to add a new function, or each program
needs to add that function, and it would be better to put it in
Ruby-GNOME2 core because it is very useful to have.
In all of these cases, you have to have some way to wake up the main
loop. That is why the pipe is there.
Now, when I tried making this in Ruby before (with an IOChannel), it
didn’t seem to work; I don’t know why. It looks like it’s possible,
though. Some Ruby code is attached showing multiple styles of this:
-
main-idle-wakeup just adds idle blocks from other threads, then
uses a wakeup function to make sure the main loop wakes.
This sometimes randomly segfaults. It sometimes randomly
produces “broken pipe” errors. This is why I think adding
idle blocks from other threads may not be safe.
-
main-iochannel-queue uses a queue and has one function from the
queue called for each byte read from the pipe.
This works fine, at least on GNU/Linux, except for the problem
below.
In both of these, if you feed blocks too fast, the UI gets
unresponsive, but that’s hard to avoid anyway. These would still need
a few tweaks before being production-quality. (Checking for the main
thread hanging on its own pipe, for instance.)
Both of these function as described under a version of Ruby-GNOME2
equivalent to r2704, minus the empty_timeout_funcs (to make sure that
they do the wakeup correctly). In that case, they both sleep and do
not wake up until there is something to do.
They also function as described under the current version of
Ruby-GNOME2 in Debian unstable. In that case, of course, they do not
sleep, because they cannot get rid of the empty_timeout_func.
kou
—> Drake W.