require "sleepy_penguin" include SleepyPenguin
The SleepyPenguin
namespace includes the Epoll
, Inotify
, TimerFD
, EventFD
classes in its top level and no other constants.
If you are uncomfortable including SleepyPenguin
, you may also use the "SP" alias if it doesn't conflict with existing code:
require "sleepy_penguin/sp"
And then access classes via:
SP::Epoll
SP::Epoll::IO
SP::EventFD
SP::Inotify
SP::TimerFD
fcntl() command constant used to return the size of a pipe. This constant is only defined when running Linux 2.6.35 or later.
require 'fcntl' r, w = IO.pipe r.fcntl(SleepyPenguin::F_GETPIPE_SZ) => Integer
Indicate that there may be more data coming into the outbound descriptor. This can allow the kernel to avoid sending partial frames from sockets. Currently only used with splice.
Attempt to move pages instead of copying. This is only a hint and support for it was removed in Linux 2.6.21. It will be re-added for FUSE filesystems only in Linux 2.6.35.
Do not block on pipe I/O. This flag only affects the pipe(s) being spliced from/to and has no effect on the non-pipe descriptor (which requires non-blocking operation to be set explicitly).
The non-blocking flag (O_NONBLOCK) on the pipe descriptors themselves are ignored by this family of functions, and using this flag is the only way to get non-blocking operation out of them.
It is highly recommended this flag be set whenever splicing from a socket into a pipe unless there is another (native) thread or process doing a blocking read on that pipe. Otherwise it is possible to block a single-threaded process if the socket buffers are larger than the pipe buffers.
fcntl() command constant used to set the size of a pipe. This constant is only defined when running Linux 2.6.35 or later.
call-seq:
require 'fcntl' r, w = IO.pipe r.fcntl(SleepyPenguin::F_SETPIPE_SZ, 131072)
SleepyPenguin.copy_file_range(src, dst, len[, keywords]) => # Integer source
Performs and in-kernel copy of len
bytes from src
to dst
, where src
and dst
are regular files on the same filesystem. Returns the number of bytes copied, which may be less than requested.
flags
is currently unused, but may be specified in the future.
Keywords:
:off_in and :off_out if non-nil may be used to specify an Integer offset for each respective descriptor. If specified, the file offsets of each file description will not be moved, providing pread(2)/pwrite(2)-like semantics.
See copy_file_range
(2) manpage for full documentation: man7.org/linux/man-pages/man2/copy_file_range.2.html
This method only works in Linux 4.5+ with sleepy_penguin 3.5.0+, and may require up-to-date kernel headers for non-x86/x86-64 systems.
linux_sendfile (dst, src, len, offset: nil) source
Copies len
bytes from src
to dst
, where src
refers to an open, mmap(2)-able File and dst
refers to a Socket. An optional offset
keyword may be specified for the src
File. Using offset
will not adjust the offset of the underlying file handle itself; in other words: this allows concurrent threads to use linux_sendfile
to write data from one open file to multiple sockets.
Returns the number of bytes written on success, or :wait_writable if the dst
Socket is non-blocking and the operation would block. A return value of zero bytes indicates EOF is reached on the src
file.
Newer OSes may be more flexible in whether or not dst
or src
is a regular file or socket, respectively.
This method was added in sleepy_penguin 3.5.0.
SleepyPenguin.splice(io_in, io_out, len[, flags [, keywords]) => Integer source
Splice len
bytes from/to a pipe. Either io_in
or io_out
MUST be a pipe. io_in
and io_out
may BOTH be pipes as of Linux 2.6.31 or later.
flags
defaults to zero if unspecified. It may be an Integer bitmask, a Symbol, or Array of Symbols
The integer bitmask may any combination of:
SleepyPenguin::F_MOVE
- attempt to move pages instead of copying
SleepyPenguin::F_NONBLOCK
- do not block on pipe I/O (only)
SleepyPenguin::F_MORE
- indicates more data will be sent soon
Symbols may be used as well to specify a single flag:
:move - corresponds to F_MOVE
:nonblock - corresponds to F_NONBLOCK
:more - corresponds to F_MORE
Or, an array of any combination of the above symbols.
Keywords:
:off_in and :off_out if non-nil may be used to
specify an offset for the respective non-pipe file descriptor.
:exception defaults to true
. Setting it to false
will return :EAGAIN symbol instead of raising Errno::EAGAIN. This will also return nil
instead of raising EOFError when io_in
is at the end.
Raises EOFError when io_in
has reached end of file. Raises Errno::EAGAIN if the SleepyPenguin::F_NONBLOCK
flag is set and the pipe has no data to read from or space to write to. May also raise Errno::EAGAIN if the non-pipe descriptor has no data to read from or space to write to.
As splice never exposes buffers to userspace, it will not take into account userspace buffering done by Ruby or stdio. It is also not subject to encoding/decoding filters under Ruby 1.9+.
Consider using `exception: false` if io_out
is a pipe or if you are using non-blocking I/O on both descriptors as it avoids the cost of raising common Errno::EAGAIN exceptions.
See manpage for full documentation: man7.org/linux/man-pages/man2/splice.2.html
Support for this exists in sleepy_penguin 3.5.0+
SleepyPenguin.tee(io_in, io_out, len[, flags[, keywords]) => Integer source
Copies up to len
bytes of data from io_in
to io_out
. io_in
and io_out
must both refer to pipe descriptors. io_in
and io_out
may not be endpoints of the same pipe.
flags
may be zero (the default) or a combination of:
As a shortcut, the `:nonblock` symbol may be used instead.
Other splice-related flags are currently unimplemented in the kernel and have no effect.
Returns the number of bytes duplicated if successful. Raises EOFError when io_in
is closed and emptied. Raises Errno::EAGAIN when io_in
is empty and/or io_out
is full and flags
specifies non-blocking operation
Keywords:
:exception defaults to true
. Setting it to false
will return :EAGAIN symbol instead of raising Errno::EAGAIN. This will also return nil
instead of raising EOFError when io_in
is at the end.
Consider using `exception: false` if io_out
is a pipe or if you are using non-blocking I/O on both descriptors as it avoids the cost of raising common Errno::EAGAIN exceptions.
See manpage for full documentation: man7.org/linux/man-pages/man2/tee.2.html
Support for this exists in sleepy_penguin 3.5.0+
mail archives: https://yhbt.net/sleepy-penguin/ public: sleepy-penguin@yhbt.net source code: git clone https://yhbt.net/sleepy_penguin.git