summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-05-09 00:13:47 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-06-22 22:17:53 +1200
commit3deb5d7113e1fd6e4b468e09464d524d390d811e (patch)
tree0c54b41e0d773435622b8a0e87f1a9612aeaf701 /io.c
parentff609eee98dc5c20f68b7befac147537e640aad1 (diff)
Direct io for accept, send, sendmsg, recvfrom, and related methods.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4477
Diffstat (limited to 'io.c')
-rw-r--r--io.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/io.c b/io.c
index d11f4076bb..c5cd348f4d 100644
--- a/io.c
+++ b/io.c
@@ -1392,6 +1392,42 @@ rb_wait_for_single_fd(int fd, int events, struct timeval *timeout)
return rb_thread_wait_for_single_fd(fd, events, timeout);
}
+VALUE rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout)
+{
+ switch (error) {
+ case EINTR:
+#if defined(ERESTART)
+ case ERESTART:
+#endif
+ // We might have pending interrupts since the previous syscall was interrupted:
+ rb_thread_check_ints();
+
+ // The operation was interrupted, so retry it immediately:
+ return events;
+
+ case EAGAIN:
+#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
+ // The operation would block, so wait for the specified events:
+ return rb_io_wait(io, events, timeout);
+
+ default:
+ // Non-specific error, no event is ready:
+ return RB_INT2NUM(0);
+ }
+}
+
+int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout)
+{
+ return RB_NUM2INT(rb_io_maybe_wait(error, io, RB_INT2NUM(RUBY_IO_READABLE), timeout));
+}
+
+int rb_io_maybe_wait_writable(int error, VALUE io, VALUE timeout)
+{
+ return RB_NUM2INT(rb_io_maybe_wait(error, io, RB_INT2NUM(RUBY_IO_WRITABLE), timeout));
+}
+
static void
make_writeconv(rb_io_t *fptr)
{