Project

General

Profile

Feature #13362

[PATCH] socket: avoid fcntl for read/write_nonblock on Linux

Added by normalperson (Eric Wong) over 3 years ago. Updated over 3 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:80302]

Description

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.


Files

Updated by normalperson (Eric Wong) over 3 years ago

normalperson@yhbt.net wrote:

Feature #13362: [PATCH] socket: avoid fcntl for read/write_nonblock on Linux
https://bugs.ruby-lang.org/issues/13362

Any comment?

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.

Thanks.

Updated by akr (Akira Tanaka) over 3 years ago

  • 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.
It is better style that such application set nonblocking flag explicitly.

Updated by normalperson (Eric Wong) over 3 years ago

akr@fsij.org wrote:

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.

Right.

Should I commit?

Updated by akr (Akira Tanaka) over 3 years ago

I think we can try it to see the incompatibility is really minor or not.
So, it should be described in NEWS.

#5

Updated by Anonymous over 3 years ago

  • Status changed from Feedback to Closed

Applied in changeset trunk|r58400.


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.

Perhaps in the future, side-effect-free non-blocking I/O can
be standard on all files and OSes: https://cr.yp.to/unix/nonblock.html

  • ext/socket/lib/socket.rb (read_nonblock, write_nonblock): Linux-specific wrapper without side effects [ruby-core:80780] [Feature #13362]
  • test/socket/test_basicsocket.rb (test_read_write_nonblock): new test

Updated by normalperson (Eric Wong) over 3 years ago

akr@fsij.org wrote:

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.

Also available in: Atom PDF