I'm considering using Ruby for some work I'm doing. This program has been
prototyped in Squeak (Smalltalk), using Squeak's threads.
In Squeak, socket IO does not block all of Squeak. It's possible to have a
read from a socket merely put the current thread to sleep if data isn't yet
available. This is accomplished by having the kernel call select() and
signal a semaphore that is part of the Smalltlalk-side socket state when
the socket is ready to read or write. This appears to me to be the Right
Thing to do with async IO in general.
Unfortunately, Squeak does not (yet) support this same model for other file
handles. Notably (at least for my application), the SerialPort class had to
be implemented so as not to do blocking reads or writes, and instead just
return no characters on a read if none are available. This makes for an
unnatural polling architecture:
delay := Delay forMilliseconds: 500.
[
delay wait.
str := port read.
str size > 0 ifTrue: [ ... process data ... ]
] repeat
The major problem with this is efficiency and latency. Too short a delay
and you burn too much time polling, too long and you have excessive latency
between receiving characters and processing them.
I'm hoping Ruby has worked around this kind of problem by having a
generalized method for async IO support in threads. I'd rather not have to
use polling like this for sockets as well (or other file handles). I know
about Errno::EWOULDBLOCK and Fcntl::O_NONBLOCK, but that would be the same
nasty and inefficient polling architecture.
Does Ruby do the Right Thing and just block a single thread on pending IO?
If not, when/how will it?