Actually, I'm starting to think it is a bug.

I decided to implement a more thorough proof-of-concept, and it fails
in the same way that my larger project fails in. The simple proof of
concepts, without any select calls, worked fine. But it seems the
problem comes when you try to throw an SSLSocket into a select() call.
It doesn't work as expected. It seems to always return that there's
something to read, and when you call SSLSocket#read (not recv,
apparently), it blocks. SSLSocket doesn't seem to incorporate
io/nonblock, so you can't SSLSocket.nonblock = true as you can with
normal sockets, so there's no chance of getting an Errno:EWOULDBLOCK.

This is either a bug in Ruby, or more likely a bug in OpenSSL/OpenSSL
Ruby bindings.

My (rather hacked up) code is at http://www.ericw.org/ruby/echo/.