Project

General

Profile

Actions

Feature #11377

closed

[PATCH] IO.copy_stream uses poll on Linux

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

Status:
Closed
Target version:
-
[ruby-core:70051]

Description

poll and ppoll have a superior API which doesn't require the
kernel to scan a potentially large bitmap to find a high-numbered
FD [ruby-core:35572]. So favor using poll in case IO.copy_stream
encounters a non-blocking FD.

We cannot reliably use poll on most OSes, because file types (e.g.
FIFOs) which work with select may not work with poll. Fortunately,
Linux uses a common notification mechanism between all
select/poll/epoll variants, so all file types are equally supported
between the notification mechanisms.

Verified by watching strace on the following scripts:

*** maygvl_copy_stream_wait_read ***
require 'io/nonblock'
r, w = IO.pipe
r.nonblock = true
IO.copy_stream(r, "/dev/null")

*** nogvl_copy_stream_wait_write ***
require 'io/nonblock'
r, w = IO.pipe
w.nonblock = true
IO.copy_stream("/dev/zero", w)

  • io.c (nogvl_wait_for_single_fd): new function for Linux
    (maygvl_copy_stream_wait_read): Linux-specific version
    (nogvl_copy_stream_wait_write): use nogvl_wait_for_single_fd

Files

Actions #1

Updated by Anonymous over 8 years ago

  • Status changed from Open to Closed

Applied in changeset r51305.


io.c: IO.copy_stream uses poll on Linux

poll and ppoll have a superior API which doesn't require the
kernel to scan a potentially large bitmap to find a high-numbered
FD [ruby-core:35572]. So favor using poll in case IO.copy_stream
encounters a non-blocking FD.

We cannot reliably use poll on most OSes, because file types (e.g.
FIFOs) which work with select may not work with poll. Fortunately,
Linux uses a common notification mechanism between all
select/poll/epoll variants, so all file types are equally supported
between the notification mechanisms.

Verified by watching strace on the following scripts:

*** maygvl_copy_stream_wait_read ***
require 'io/nonblock'
r, w = IO.pipe
r.nonblock = true
IO.copy_stream(r, "/dev/null")

*** nogvl_copy_stream_wait_write ***
require 'io/nonblock'
r, w = IO.pipe
w.nonblock = true
IO.copy_stream("/dev/zero", w)

  • io.c (nogvl_wait_for_single_fd): new function for Linux
    (maygvl_copy_stream_wait_read): Linux-specific version
    (nogvl_copy_stream_wait_write): use nogvl_wait_for_single_fd
    [ruby-core:70051] [Feature #11377]
Actions

Also available in: Atom PDF

Like0
Like0