From af9da960a4b2683d27c946c308ae105958abdd26 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 9 May 2011 13:12:25 -0700 Subject: retry on EINTR This makes things consistent with Ruby core IO methods --- ext/io_splice/io_splice_ext.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'ext') diff --git a/ext/io_splice/io_splice_ext.c b/ext/io_splice/io_splice_ext.c index a0ba381..eab1333 100644 --- a/ext/io_splice/io_splice_ext.c +++ b/ext/io_splice/io_splice_ext.c @@ -92,22 +92,12 @@ rb_thread_blocking_region( static VALUE io_run(rb_blocking_function_t *fn, void *data) { - return rb_thread_blocking_region(fn, data, RUBY_UBF_IO, 0); -} - -/* - * Releases GVL only iff blocking I/O is used. - * Only use this if all file descriptors in data are pipes. - * We'll trust programmers who use non-blocking I/O explicitly to - * want the fastest possible performance without resorting to threads, - * so releasing and them immediately reacquiring the GVL would be - * a waste of time. - */ -static VALUE nb_io_run(rb_blocking_function_t *fn, void *data, unsigned flags) -{ - if (flags & SPLICE_F_NONBLOCK) - return fn(data); - return io_run(fn, data); + ssize_t n; +retry: + n = (ssize_t)rb_thread_blocking_region(fn, data, RUBY_UBF_IO, 0); + if (n == -1 && errno == EINTR) + goto retry; + return (VALUE)n; } struct splice_args { @@ -252,7 +242,7 @@ static long do_tee(int argc, VALUE *argv, unsigned dflags) a.len = (size_t)NUM2ULONG(len); a.flags = NIL_P(flags) ? dflags : NUM2UINT(flags) | dflags; - return (long)nb_io_run(nogvl_tee, &a, a.flags); + return (long)io_run(nogvl_tee, &a); } /* @@ -437,7 +427,7 @@ static VALUE my_vmsplice(int argc, VALUE * argv, VALUE self) a.flags = NIL_P(flags) ? 0 : NUM2UINT(flags); for (;;) { - long n = (long)nb_io_run(nogvl_vmsplice, &a, a.flags); + long n = (long)io_run(nogvl_vmsplice, &a); if (n < 0) { if (errno == EAGAIN) { -- cgit v1.2.3-24-ge0c7