cardoso_tiago / hotmail.com wrote:
> > What operation(s) are you doing for "socket monitoring"?
> 
> i'm using plain IO.select. So the idea is, I have a selector
> thread, which pushes ready descriptors to a queue; other
> threads pull from that queue, and read/write from descriptors;
> if must wait, send them back to selector thread. 

Is there any chance you're calling IO.select on an IO object
which already got pushed into the queue?

In other words, you may forget to remove an IO from the
IO.select arg set once it's "armed" and pushed into the queue;
so it could be in the queue twice, and used by two threads (or
more).

I just checked again: IO.select won't touch String buffers,
it'll only check the internal Ruby buffers which are protected
by GVL, anyways.


Finally, select(2) (and thus IO.select) behavior regarding FD
aliasing/recycling is (I believe to be) undefined and subject
to race conditions...

IO#close, #accept, IO.select, File.open all release the GVL;
which opens up some nasty race conditions especially when
the underlying select(2) syscall operates on an FD; while
IO.select operates on Ruby IO objects.

I can provide a more detailed explanation at another time; but
in short, you REALLY need to be careful with race conditions
around close, select and FD-allocating syscalls in MT code.
Especially since POSIX stipulates FD-allocating syscalls need to
use the lowest-numbered available FD (which is often the most
recently closed FD).

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>