aboutsummaryrefslogtreecommitdiffstats
path: root/io.c
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2023-03-31 00:48:55 +1300
committerGitHub <noreply@github.com>2023-03-31 00:48:55 +1300
commit648870b5c577239b3274b0b48c82fb74910dfabf (patch)
treef944e0a1919bcb46537e1f3bd522beee9e72288c /io.c
parent6f122965cf8704f019445faead58040e9be2effb (diff)
downloadruby-648870b5c577239b3274b0b48c82fb74910dfabf.tar.gz
Support `IO#pread` / `IO#pwrite` using fiber scheduler. (#7594)
* Skip test if non-blocking file IO is not supported.
Diffstat (limited to 'io.c')
-rw-r--r--io.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/io.c b/io.c
index a023039209..be5d479099 100644
--- a/io.c
+++ b/io.c
@@ -6066,6 +6066,7 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
#if defined(HAVE_PREAD) || defined(HAVE_PWRITE)
struct prdwr_internal_arg {
+ VALUE io;
int fd;
void *buf;
size_t count;
@@ -6075,17 +6076,28 @@ struct prdwr_internal_arg {
#if defined(HAVE_PREAD)
static VALUE
-internal_pread_func(void *arg)
+internal_pread_func(void *_arg)
{
- struct prdwr_internal_arg *p = arg;
- return (VALUE)pread(p->fd, p->buf, p->count, p->offset);
+ struct prdwr_internal_arg *arg = _arg;
+
+ return (VALUE)pread(arg->fd, arg->buf, arg->count, arg->offset);
}
static VALUE
-pread_internal_call(VALUE arg)
+pread_internal_call(VALUE _arg)
{
- struct prdwr_internal_arg *p = (struct prdwr_internal_arg *)arg;
- return rb_thread_io_blocking_region(internal_pread_func, p, p->fd);
+ struct prdwr_internal_arg *arg = (struct prdwr_internal_arg *)_arg;
+
+ VALUE scheduler = rb_fiber_scheduler_current();
+ if (scheduler != Qnil) {
+ VALUE result = rb_fiber_scheduler_io_pread_memory(scheduler, arg->io, arg->offset, arg->buf, arg->count, 0);
+
+ if (!UNDEF_P(result)) {
+ return rb_fiber_scheduler_io_result_apply(result);
+ }
+ }
+
+ return rb_thread_io_blocking_region(internal_pread_func, arg, arg->fd);
}
/*
@@ -6122,7 +6134,7 @@ rb_io_pread(int argc, VALUE *argv, VALUE io)
VALUE len, offset, str;
rb_io_t *fptr;
ssize_t n;
- struct prdwr_internal_arg arg;
+ struct prdwr_internal_arg arg = {.io = io};
int shrinkable;
rb_scan_args(argc, argv, "21", &len, &offset, &str);
@@ -6158,9 +6170,19 @@ rb_io_pread(int argc, VALUE *argv, VALUE io)
#if defined(HAVE_PWRITE)
static VALUE
-internal_pwrite_func(void *ptr)
+internal_pwrite_func(void *_arg)
{
- struct prdwr_internal_arg *arg = ptr;
+ struct prdwr_internal_arg *arg = _arg;
+
+ VALUE scheduler = rb_fiber_scheduler_current();
+ if (scheduler != Qnil) {
+ VALUE result = rb_fiber_scheduler_io_pwrite_memory(scheduler, arg->io, arg->offset, arg->buf, arg->count, 0);
+
+ if (!UNDEF_P(result)) {
+ return rb_fiber_scheduler_io_result_apply(result);
+ }
+ }
+
return (VALUE)pwrite(arg->fd, arg->buf, arg->count, arg->offset);
}
@@ -6195,7 +6217,7 @@ rb_io_pwrite(VALUE io, VALUE str, VALUE offset)
{
rb_io_t *fptr;
ssize_t n;
- struct prdwr_internal_arg arg;
+ struct prdwr_internal_arg arg = {.io = io};
VALUE tmp;
if (!RB_TYPE_P(str, T_STRING))