about summary refs log tree commit homepage
path: root/ext/io_splice
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-05-18 15:36:52 -0700
committerEric Wong <normalperson@yhbt.net>2011-05-18 15:54:57 -0700
commita2ae924fb1c372cc559a59feca40780a9a37ba33 (patch)
tree905a2cca5553c158060a1407b73bed8303b0e469 /ext/io_splice
parentaad5139884ad055d8aafb4316360e9f486b2d452 (diff)
downloadruby_io_splice-a2ae924fb1c372cc559a59feca40780a9a37ba33.tar.gz
limit maximum splice length to 1 << 30
This is the same value haproxy has to work around the same
issue on 64-bit platforms.

ref: a9de333aa58e6cb76f08a50e8ba2c5931184068f in
     http://git.1wt.eu/git/haproxy.git
Diffstat (limited to 'ext/io_splice')
-rw-r--r--ext/io_splice/io_splice_ext.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/ext/io_splice/io_splice_ext.c b/ext/io_splice/io_splice_ext.c
index 23cc34f..cbbdbfc 100644
--- a/ext/io_splice/io_splice_ext.c
+++ b/ext/io_splice/io_splice_ext.c
@@ -15,6 +15,9 @@
 static VALUE sym_EAGAIN;
 #define WAITALL 0x4000000
 
+/* taken from haproxy */
+#define MAX_AT_ONCE (1 << 30)
+
 #ifndef F_LINUX_SPECIFIC_BASE
 #  define F_LINUX_SPECIFIC_BASE 1024
 #endif
@@ -130,6 +133,9 @@ static VALUE nogvl_splice(void *ptr)
 {
         struct splice_args *a = ptr;
 
+        if (a->len > MAX_AT_ONCE)
+                a->len = MAX_AT_ONCE;
+
         return (VALUE)splice(a->fd_in, a->off_in, a->fd_out, a->off_out,
                              a->len, a->flags);
 }
@@ -276,6 +282,9 @@ static VALUE nogvl_tee(void *ptr)
 {
         struct tee_args *a = ptr;
 
+        if (a->len > MAX_AT_ONCE)
+                a->len = MAX_AT_ONCE;
+
         return (VALUE)tee(a->fd_in, a->fd_out, a->len, a->flags);
 }
 
@@ -682,6 +691,14 @@ void Init_io_splice_ext(void)
          */
         rb_define_const(mSplice, "PIPE_BUF", UINT2NUM(PIPE_BUF));
 
+        /*
+         * The maximum size we're allowed to splice at once.  Larger
+         * sizes will be broken up and retried if the WAITALL flag or
+         * IO::Splice.copy_stream is used.
+         */
+        rb_define_const(mSplice, "MAX_AT_ONCE", SIZET2NUM(MAX_AT_ONCE));
+
+
         if (uname(&utsname) == -1)
                 rb_sys_fail("uname");