On platforms where MSG_DONTWAIT works reliably on all sockets
(so far, I know of Linux), we can avoid fcntl syscalls and
implement IO#write_nonblock and IO#read_nonblock in terms of the
socket-specific send and recv family of syscalls.
This avoids side effects on the socket, and also encourages
generic code to be written in cases where IO wrappers like
OpenSSL::SSL::SSLSocket are used.
I could've sworn I sent something like this years ago, but
maybe I'm confusing it with kgio or socket_dontwait.
Also, this patch avoids the race condition where another thread
or process can clear the nonblocking flag via fcntl immediately
after {read,write}_nonblock sets it and causes the
{read,write}_nonblock caller to get stuck.
If some non-Ruby application depend on nonblocking flag set by Ruby,
such application will be affected, though.
It is better style that such application set nonblocking flag explicitly.
Issue #13362 has been updated by akr (Akira Tanaka).
Status changed from Open to Feedback
I think it's possible on such platforms.
If some non-Ruby application depend on nonblocking flag set by Ruby,
such application will be affected, though.
Yes, there may be some code which depends on side-effects.
However, I think it is a minor concern and anything which
inherits sockets ought to know to set flags correctly.
Normal Ruby code does not have this problem, since blocking
methods know to call rb_io_wait_*able on EAGAIN/EWOULDBLOCK.
It is better style that such application set nonblocking flag explicitly.
socket: avoid fcntl for read/write_nonblock on Linux
On platforms where MSG_DONTWAIT works reliably on all sockets
(so far, I know of Linux), we can avoid fcntl syscalls and
implement IO#write_nonblock and IO#read_nonblock in terms of the
socket-specific send and recv family of syscalls.
This avoids side effects on the socket, and also encourages
generic code to be written in cases where IO wrappers like
OpenSSL::SSL::SSLSocket are used.
I think we can try it to see the incompatibility is really minor or not.
So, it should be described in NEWS.
OK, r58400.
I think Ruby 1.8 => 1.9 introduced similar minor incompatibility
for all pipe and sockets, too, since 1.8 always used
non-blocking I/O to implement blocking IO with green threads.