f4745acc7bd7189deab75244128135a3c4b2a763
15 static VALUE sym_EAGAIN
;
16 #define WAITALL 0x4000000
18 /* taken from haproxy */
19 #define MAX_AT_ONCE (1 << 30)
21 #ifndef F_LINUX_SPECIFIC_BASE
22 # define F_LINUX_SPECIFIC_BASE 1024
26 # define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
27 # define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
31 # define rb_io_t OpenFile
35 # define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
37 # if !HAVE_RB_IO_T || (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
38 # define FPTR_TO_FD(fptr) fileno(fptr->f)
40 # define FPTR_TO_FD(fptr) fptr->fd
45 # define SSIZET2NUM(x) LONG2NUM(x)
48 # define NUM2SSIZET(x) NUM2LONG(x)
51 # define SIZET2NUM(x) ULONG2NUM(x)
54 # define NUM2SIZET(x) NUM2ULONG(x)
57 static int my_fileno(VALUE io
)
63 case T_FIXNUM
: return FIX2INT(io
);
65 GetOpenFile(io
, fptr
);
66 return FPTR_TO_FD(fptr
);
69 io
= rb_convert_type(io
, T_FILE
, "IO", "to_io");
75 static int check_fileno(VALUE io
)
77 int saved_errno
= errno
;
78 int fd
= my_fileno(io
);
83 /* partial emulation of the 1.9 rb_thread_blocking_region under 1.8 */
84 #if defined(HAVE_RB_THREAD_BLOCKING_REGION) && \
85 defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
87 * Ruby 1.9 - 2.1 (we use deprecated rb_thread_blocking_region in 2.0+
88 * because we can detect (but not use) rb_thread_blocking_region in 1.9.3
90 typedef VALUE (*my_blocking_fn_t
)(void*);
91 # define WITHOUT_GVL(fn,a,ubf,b) \
92 rb_thread_blocking_region((my_blocking_fn_t)(fn),(a),(ubf),(b))
93 #elif defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) /* Ruby 2.2+ */
94 #include <ruby/thread.h>
95 # define WITHOUT_GVL(fn,a,ubf,b) \
96 rb_thread_call_without_gvl((fn),(a),(ubf),(b))
99 # define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
100 typedef void rb_unblock_function_t(void *);
101 typedef void * rb_blocking_function_t(void *);
102 static void * WITHOUT_GVL(rb_blocking_function_t
*func
, void *data1
,
103 rb_unblock_function_t
*ubf
, void *data2
)
107 assert(RUBY_UBF_IO
== ubf
&& "RUBY_UBF_IO required for emulation");
115 #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
118 # define RSTRING_PTR(s) (RSTRING(s)->ptr)
121 # define RSTRING_LEN(s) (RSTRING(s)->len)
124 # define RARRAY_LEN(s) (RARRAY(s)->len)
127 #define io_run(fn,data) WITHOUT_GVL((fn),(data),RUBY_UBF_IO,0)
138 static void * nogvl_splice(void *ptr
)
140 struct splice_args
*a
= ptr
;
142 if (a
->len
> MAX_AT_ONCE
)
143 a
->len
= MAX_AT_ONCE
;
145 return (void *)splice(a
->fd_in
, a
->off_in
, a
->fd_out
, a
->off_out
,
149 static ssize_t
do_splice(int argc
, VALUE
*argv
, unsigned dflags
)
152 VALUE io_in
, off_in
, io_out
, off_out
, len
, flags
;
153 struct splice_args a
;
158 rb_scan_args(argc
, argv
, "51",
159 &io_in
, &off_in
, &io_out
, &off_out
, &len
, &flags
);
161 a
.off_in
= NIL_P(off_in
) ? NULL
: (i
= NUM2OFFT(off_in
), &i
);
162 a
.off_out
= NIL_P(off_out
) ? NULL
: (o
= NUM2OFFT(off_out
), &o
);
163 a
.len
= NUM2SIZET(len
);
164 a
.flags
= NIL_P(flags
) ? dflags
: NUM2UINT(flags
) | dflags
;
165 waitall
= a
.flags
& WAITALL
;
170 a
.fd_in
= check_fileno(io_in
);
171 a
.fd_out
= check_fileno(io_out
);
172 bytes
= (ssize_t
)io_run(nogvl_splice
, &a
);
176 if (waitall
&& errno
== EAGAIN
) {
177 rb_io_wait_readable(check_fileno(io_in
));
179 rb_io_wait_writable(check_fileno(io_out
));
185 } else if (bytes
== 0) {
187 } else if (waitall
) {
189 if ((a
.len
-= bytes
) == 0)
203 * IO.splice(io_in, off_in, io_out, off_out, len) => integer
204 * IO.splice(io_in, off_in, io_out, off_out, len, flags) => integer
206 * Splice +len+ bytes from/to a pipe. Either +io_in+ or +io_out+
207 * MUST be a pipe. +io_in+ and +io_out+ may BOTH be pipes as of
208 * Linux 2.6.31 or later.
210 * +off_in+ and +off_out+ if non-nil may be used to
211 * specify an offset for the non-pipe file descriptor.
213 * +flags+ defaults to zero if unspecified.
214 * +flags+ may be a bitmask of the following flags:
216 * * IO::Splice::F_MOVE
217 * * IO::Splice::F_NONBLOCK
218 * * IO::Splice::F_MORE
220 * Returns the number of bytes spliced.
221 * Raises EOFError when +io_in+ has reached end of file.
222 * Raises Errno::EAGAIN if the IO::Splice::F_NONBLOCK flag is set
223 * and the pipe has no data to read from or space to write to. May
224 * also raise Errno::EAGAIN if the non-pipe descriptor has no data
225 * to read from or space to write to.
227 * As splice never exposes buffers to userspace, it will not take
228 * into account userspace buffering done by Ruby or stdio. It is
229 * also not subject to encoding/decoding filters under Ruby 1.9.
231 * Consider using IO.trysplice if +io_out+ is a pipe or if you are using
232 * non-blocking I/O on both descriptors as it avoids the cost of raising
233 * common Errno::EAGAIN exceptions.
235 * See manpage for full documentation:
236 * http://kernel.org/doc/man-pages/online/pages/man2/splice.2.html
238 static VALUE
my_splice(int argc
, VALUE
*argv
, VALUE self
)
240 ssize_t n
= do_splice(argc
, argv
, 0);
245 rb_sys_fail("splice");
246 return SSIZET2NUM(n
);
251 * IO.trysplice(io_in, off_in, io_out, off_out, len) => integer
252 * IO.trysplice(io_in, off_in, io_out, off_out, len, flags) => integer
254 * Exactly like IO.splice, except +:EAGAIN+ is returned when either
255 * the read or write end would block instead of raising Errno::EAGAIN.
257 * IO::Splice::F_NONBLOCK is always passed for the pipe descriptor,
258 * but this can still block if the non-pipe descriptor is blocking.
260 * See IO.splice documentation for more details.
262 * This method is recommended whenever +io_out+ is a pipe.
264 static VALUE
trysplice(int argc
, VALUE
*argv
, VALUE self
)
266 ssize_t n
= do_splice(argc
, argv
, SPLICE_F_NONBLOCK
);
273 rb_sys_fail("splice");
275 return SSIZET2NUM(n
);
285 /* runs without GVL */
286 static void * nogvl_tee(void *ptr
)
288 struct tee_args
*a
= ptr
;
290 if (a
->len
> MAX_AT_ONCE
)
291 a
->len
= MAX_AT_ONCE
;
293 return (void *)tee(a
->fd_in
, a
->fd_out
, a
->len
, a
->flags
);
296 static ssize_t
do_tee(int argc
, VALUE
*argv
, unsigned dflags
)
298 VALUE io_in
, io_out
, len
, flags
;
304 rb_scan_args(argc
, argv
, "31", &io_in
, &io_out
, &len
, &flags
);
305 a
.len
= (size_t)NUM2SIZET(len
);
306 a
.flags
= NIL_P(flags
) ? dflags
: NUM2UINT(flags
) | dflags
;
307 waitall
= a
.flags
& WAITALL
;
312 a
.fd_in
= check_fileno(io_in
);
313 a
.fd_out
= check_fileno(io_out
);
314 bytes
= (ssize_t
)io_run(nogvl_tee
, &a
);
318 if (waitall
&& errno
== EAGAIN
) {
319 rb_io_wait_readable(check_fileno(io_in
));
321 rb_io_wait_writable(check_fileno(io_out
));
327 } else if (bytes
== 0) {
329 } else if (waitall
) {
331 if ((a
.len
-= bytes
) == 0)
343 * IO.tee(io_in, io_out, len) => integer
344 * IO.tee(io_in, io_out, len, flags) => integer
346 * Copies up to +len+ bytes of data from +io_in+ to +io_out+. +io_in+
347 * and +io_out+ must both refer to pipe descriptors. +io_in+ and +io_out+
348 * may not be endpoints of the same pipe.
350 * +flags+ may be zero (the default) or a combination of:
351 * * IO::Splice::F_NONBLOCK
353 * Other IO::Splice flags are currently unimplemented or have no effect.
355 * Returns the number of bytes duplicated if successful.
356 * Raises EOFError when +io_in+ is closed and emptied.
357 * Raises Errno::EAGAIN when +io_in+ is empty and/or +io_out+ is full
358 * and +flags+ contains IO::Splice::F_NONBLOCK
360 * Consider using IO.trytee if you are using IO::Splice::F_NONBLOCK
361 * as it avoids the cost of raising common Errno::EAGAIN exceptions.
363 * See manpage for full documentation:
364 * http://kernel.org/doc/man-pages/online/pages/man2/tee.2.html
366 static VALUE
my_tee(int argc
, VALUE
*argv
, VALUE self
)
368 ssize_t n
= do_tee(argc
, argv
, 0);
375 return SSIZET2NUM(n
);
380 * IO.trytee(io_in, io_out, len) => integer
381 * IO.trytee(io_in, io_out, len, flags) => integer
383 * Exactly like IO.tee, except +:EAGAIN+ is returned when either
384 * the read or write end would block instead of raising Errno::EAGAIN.
386 * IO::Splice::F_NONBLOCK is always passed for the pipe descriptor,
387 * but this can still block if the non-pipe descriptor is blocking.
389 * See IO.tee documentation for more details.
391 static VALUE
trytee(int argc
, VALUE
*argv
, VALUE self
)
393 ssize_t n
= do_tee(argc
, argv
, SPLICE_F_NONBLOCK
);
403 return SSIZET2NUM(n
);
406 struct vmsplice_args
{
409 unsigned long nr_segs
;
413 static void * nogvl_vmsplice(void *ptr
)
415 struct vmsplice_args
*a
= ptr
;
417 return (void *)vmsplice(a
->fd
, a
->iov
, a
->nr_segs
, a
->flags
);
420 /* this can't be a function since we use alloca() */
421 #define ARY2IOVEC(iov,iovcnt,expect,ary) \
425 iovcnt = (unsigned long)RARRAY_LEN(ary); \
426 if (iovcnt > IOV_MAX) \
427 rb_raise(rb_eArgError, "array is larger than IOV_MAX"); \
428 iov = tmp = alloca(sizeof(struct iovec) * iovcnt); \
430 for (i = 0; i < iovcnt; tmp++, i++) { \
431 VALUE cur = rb_ary_entry(ary, (long)i); \
432 Check_Type(cur, T_STRING); \
433 tmp->iov_base = RSTRING_PTR(cur); \
434 tmp->iov_len = RSTRING_LEN(cur); \
435 expect += tmp->iov_len; \
439 static void advance_vmsplice_args(struct vmsplice_args
*a
, long n
)
441 struct iovec
*new_iov
= a
->iov
;
444 /* skip over iovecs we've already written completely */
445 for (i
= 0; i
< a
->nr_segs
; i
++, new_iov
++) {
449 * partially written iov,
450 * modify and retry with current iovec in
453 if (new_iov
->iov_len
> (size_t)n
) {
454 VALUE base
= (VALUE
)new_iov
->iov_base
;
456 new_iov
->iov_len
-= n
;
457 new_iov
->iov_base
= (void *)(base
+ n
);
461 n
-= new_iov
->iov_len
;
464 /* setup to retry without the already-written iovecs */
471 * IO.vmsplice(io, string_array) => integer
472 * IO.vmsplice(io, string_array, flags) => integer
473 * IO.vmsplice(io, string) => integer
474 * IO.vmsplice(io, string, flags) => integer
476 * Transfers an array of strings into the pipe descriptor given by io.
477 * +io+ must be the writable end of a pipe.
479 * This may allow the kernel to avoid data copies in some cases.
480 * but is (probably) of limited usefulness in Ruby. If you have
481 * use cases or ideas for making this more useful for Ruby users,
482 * please tell us at ruby.io.splice@librelist.org!
484 * Also consider the "sendfile" RubyGem or IO.copy_stream in Ruby 1.9
485 * if you want to do zero-copy file transfers to pipes or sockets. As
486 * of Linux 2.6.33, sendfile(2) can copy to any output descriptor,
489 * See manpage for full documentation:
490 * http://kernel.org/doc/man-pages/online/pages/man2/vmsplice.2.html
492 static VALUE
my_vmsplice(int argc
, VALUE
* argv
, VALUE self
)
496 struct vmsplice_args a
;
500 VALUE io
, data
, flags
;
502 rb_scan_args(argc
, argv
, "21", &io
, &data
, &flags
);
504 switch (TYPE(data
)) {
506 iov
.iov_base
= RSTRING_PTR(data
);
507 iov
.iov_len
= (size_t)(left
= (ssize_t
)RSTRING_LEN(data
));
512 ARY2IOVEC(a
.iov
, a
.nr_segs
, left
, data
);
515 rb_raise(rb_eTypeError
, "wrong argument type %s "
516 "(expected a String or Array of strings)",
517 rb_obj_classname(data
));
520 a
.flags
= NIL_P(flags
) ? 0 : NUM2UINT(flags
);
523 a
.fd
= check_fileno(io
);
524 n
= (ssize_t
)io_run(nogvl_vmsplice
, &a
);
527 if (errno
== EAGAIN
) {
528 if (a
.flags
& SPLICE_F_NONBLOCK
)
529 rb_sys_fail("vmsplice");
530 if (rb_io_wait_writable(check_fileno(io
)))
532 /* fall through on error */
535 * unlikely to hit this case, return the
536 * already written bytes, we'll let the next
537 * write (or close) fail instead
543 rb_sys_fail("vmsplice");
550 advance_vmsplice_args(&a
, n
);
553 return SSIZET2NUM(rv
);
558 * reader, writer = IO.pipe
559 * reader.pipe_size => integer
561 * Returns the pipe capacity of the underlying pipe in bytes. The
562 * default capacity is 65536 bytes since Linux 2.6.11, and 4096 bytes
563 * in previous kernels.
565 * Since the pipe is a circular buffer in the same kernel, the size
566 * of the reader is exactly the same as the size of the writer.
568 * This method is only exposed on Linux 2.6.35 or later.
570 static VALUE
pipe_size(VALUE self
)
572 int size
= fcntl(my_fileno(self
), F_GETPIPE_SZ
);
575 rb_sys_fail("fcntl(F_GETPIPE_SZ)");
577 return INT2NUM(size
);
582 * reader, writer = IO.pipe
583 * reader.pipe_size = integer
585 * Sets and returns the pipe capacity of the underlying pipe in bytes.
587 * This MUST be a power-of-two, or Errno::EINVAL will be raised.
588 * Linux will silently increase this to be equal to the page size
589 * (4096 bytes on most architectures) if the specified value is
590 * less than the size of a page.
592 * For users without CAP_SYS_RESOURCE, this raises Errno::EPERM when
593 * attempting to specify a value greater than the value in
594 * /proc/sys/fs/pipe-max-size.
596 * Since the pipe is a circular buffer in the same kernel, the size
597 * of the reader is exactly the same as the size of the writer.
599 * Raises Errno::EBUSY if the assigned value is less than
600 * the currently filled portion of the pipe.
602 * This method is only exposed on Linux 2.6.35 or later.
604 static VALUE
set_pipe_size(VALUE self
, VALUE size
)
606 int fd
= my_fileno(self
);
607 int bytes
= NUM2INT(size
);
608 int rv
= fcntl(fd
, F_SETPIPE_SZ
, bytes
);
611 if (errno
== ENOMEM
) {
613 rv
= fcntl(fd
, F_SETPIPE_SZ
, bytes
);
616 rb_sys_fail("fcntl(F_SETPIPE_SZ)");
622 static int can_mod_pipe_size(void)
625 * pipe2 appeared in Linux 2.6.27, F_*PIPE_SZ appeared in 2.6.35,
626 * thus not having pipe2 automatically disqualifies us from having
631 int rc
= pipe2(fds
, O_CLOEXEC
);
634 rc
= fcntl(fds
[0], F_GETPIPE_SZ
);
641 * weird error, but don't raise during init, this could be
648 #else /* ! HAVE_PIPE2 */
650 #endif /* ! HAVE_PIPE2 */
653 #define NODOC_CONST(klass,name,value) \
654 rb_define_const((klass),(name),(value))
656 void Init_io_splice_ext(void)
658 VALUE mSplice
= rb_define_module_under(rb_cIO
, "Splice");
660 rb_define_singleton_method(rb_cIO
, "splice", my_splice
, -1);
661 rb_define_singleton_method(rb_cIO
, "trysplice", trysplice
, -1);
662 rb_define_singleton_method(rb_cIO
, "tee", my_tee
, -1);
663 rb_define_singleton_method(rb_cIO
, "trytee", trytee
, -1);
664 rb_define_singleton_method(rb_cIO
, "vmsplice", my_vmsplice
, -1);
667 * Attempt to move pages instead of copying. This is only a hint
668 * and support for it was removed in Linux 2.6.21. It will be
669 * re-added for FUSE filesystems only in Linux 2.6.35.
671 rb_define_const(mSplice
, "F_MOVE", UINT2NUM(SPLICE_F_MOVE
));
672 assert(WAITALL
!= SPLICE_F_MOVE
&& "WAITALL == F_MOVE");
675 * Do not block on pipe I/O. This flag only affects the pipe(s)
676 * being spliced from/to and has no effect on the non-pipe
677 * descriptor (which requires non-blocking operation to be set
680 * The non-blocking flag (O_NONBLOCK) on the pipe descriptors
681 * themselves are ignored by this family of functions, and
682 * using this flag is the only way to get non-blocking operation
685 * It is highly recommended this flag be set (or IO.trysplice used)
686 * whenever splicing from a socket into a pipe unless there is
687 * another (native) thread or process doing a blocking read on that
688 * pipe. Otherwise it is possible to block a single-threaded process
689 * if the socket buffers are larger than the pipe buffers.
691 rb_define_const(mSplice
, "F_NONBLOCK", UINT2NUM(SPLICE_F_NONBLOCK
));
692 assert(WAITALL
!= SPLICE_F_NONBLOCK
&& "WAITALL == F_NONBLOCK");
695 * Indicate that there may be more data coming into the outbound
696 * descriptor. This can allow the kernel to avoid sending partial
697 * frames from sockets. Currently only used with splice.
699 rb_define_const(mSplice
, "F_MORE", UINT2NUM(SPLICE_F_MORE
));
700 assert(WAITALL
!= SPLICE_F_MORE
&& "WAITALL == F_MORE");
703 * Only usable by vmsplice. This flag probably not useful in the
704 * context of Ruby applications which cannot control alignment.
706 rb_define_const(mSplice
, "F_GIFT", UINT2NUM(SPLICE_F_GIFT
));
707 assert(WAITALL
!= SPLICE_F_GIFT
&& "WAITALL == F_GIFT");
710 * Retry until the requested transfer is complete, this will
711 * cause IO.splice/IO.tee to never return less than the requested
712 * transfer size unless an error occored.
714 * IO.vmsplice always defaults to this behavior.
716 NODOC_CONST(mSplice
, "WAITALL", UINT2NUM(WAITALL
));
719 * The maximum size of an atomic write to a pipe
720 * POSIX requires this to be at least 512 bytes.
721 * Under Linux, this is 4096 bytes.
723 rb_define_const(mSplice
, "PIPE_BUF", UINT2NUM(PIPE_BUF
));
726 * The maximum size we're allowed to splice at once. Larger
727 * sizes will be broken up and retried if the WAITALL flag or
728 * IO::Splice.copy_stream is used.
730 rb_define_const(mSplice
, "MAX_AT_ONCE", SIZET2NUM(MAX_AT_ONCE
));
732 if (can_mod_pipe_size()) {
733 rb_define_method(rb_cIO
, "pipe_size", pipe_size
, 0);
734 rb_define_method(rb_cIO
, "pipe_size=", set_pipe_size
, 1);
737 * fcntl() command constant used to return the size of a pipe.
738 * This constant is only defined when running Linux 2.6.35
739 * or later. For convenience, use IO#pipe_size instead.
741 rb_define_const(mSplice
, "F_GETPIPE_SZ",
742 UINT2NUM(F_GETPIPE_SZ
));
745 * fcntl() command constant used to set the size of a pipe.
746 * This constant is only defined when running Linux 2.6.35
747 * or later. For convenience, use IO#pipe_size= instead.
749 rb_define_const(mSplice
, "F_SETPIPE_SZ",
750 UINT2NUM(F_SETPIPE_SZ
));
753 sym_EAGAIN
= ID2SYM(rb_intern("EAGAIN"));