ruby-changes:62922
From: Samuel <ko1@a...>
Date: Mon, 14 Sep 2020 13:44:33 +0900 (JST)
Subject: [ruby-changes:62922] 701dcbb3ca (master): Add support for hooking `IO#read`.
https://git.ruby-lang.org/ruby.git/commit/?id=701dcbb3ca From 701dcbb3ca9bf04b61cc07156608c61aaf9173f0 Mon Sep 17 00:00:00 2001 From: Samuel Williams <samuel.williams@o...> Date: Fri, 21 Aug 2020 00:53:08 +1200 Subject: Add support for hooking `IO#read`. diff --git a/include/ruby/io.h b/include/ruby/io.h index fc6240a..19b2036 100644 --- a/include/ruby/io.h +++ b/include/ruby/io.h @@ -59,6 +59,8 @@ PACKED_STRUCT_UNALIGNED(struct rb_io_buffer_t { https://github.com/ruby/ruby/blob/trunk/include/ruby/io.h#L59 typedef struct rb_io_buffer_t rb_io_buffer_t; typedef struct rb_io_t { + VALUE self; + FILE *stdio_file; /* stdio ptr for read/write if available */ int fd; /* file descriptor */ int mode; /* mode flags: FMODE_XXXs */ diff --git a/internal/scheduler.h b/internal/scheduler.h index be976d7..f5a41af 100644 --- a/internal/scheduler.h +++ b/internal/scheduler.h @@ -21,7 +21,10 @@ VALUE rb_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeou https://github.com/ruby/ruby/blob/trunk/internal/scheduler.h#L21 VALUE rb_scheduler_io_wait_readable(VALUE scheduler, VALUE io); VALUE rb_scheduler_io_wait_writable(VALUE scheduler, VALUE io); -VALUE rb_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, VALUE offset, VALUE length); -VALUE rb_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, VALUE offset, VALUE length); +int rb_scheduler_supports_io_read(VALUE scheduler); +VALUE rb_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length); + +int rb_scheduler_supports_io_write(VALUE scheduler); +VALUE rb_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length); #endif /* RUBY_SCHEDULER_H */ diff --git a/io.c b/io.c index fbc913b..f73a508 100644 --- a/io.c +++ b/io.c @@ -2619,6 +2619,11 @@ bufread_call(VALUE arg) https://github.com/ruby/ruby/blob/trunk/io.c#L2619 static long io_fread(VALUE str, long offset, long size, rb_io_t *fptr) { + VALUE scheduler = rb_thread_current_scheduler(); + if (scheduler != Qnil && rb_scheduler_supports_io_read(scheduler)) { + return rb_scheduler_io_read(scheduler, fptr->self, str, offset, size); + } + long len; struct bufread_arg arg; @@ -8511,6 +8516,7 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L8516 fmode |= FMODE_PREP; } MakeOpenFile(io, fp); + fp->self = io; fp->fd = fd; fp->mode = fmode; fp->encs = convconfig; diff --git a/scheduler.c b/scheduler.c index 4eaf12b..9821d07 100644 --- a/scheduler.c +++ b/scheduler.c @@ -59,13 +59,23 @@ VALUE rb_scheduler_io_wait_writable(VALUE scheduler, VALUE io) https://github.com/ruby/ruby/blob/trunk/scheduler.c#L59 return rb_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_WRITABLE), Qnil); } -VALUE rb_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, VALUE offset, VALUE length) +int rb_scheduler_supports_io_read(VALUE scheduler) { - return rb_funcall(scheduler, id_io_read, 4, io, buffer, offset, length); + return rb_respond_to(scheduler, id_io_read); } -VALUE rb_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, VALUE offset, VALUE length) +VALUE rb_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length) +{ + return rb_funcall(scheduler, id_io_read, 4, io, buffer, SIZET2NUM(offset), SIZET2NUM(length)); +} + +int rb_scheduler_supports_io_write(VALUE scheduler) +{ + return rb_respond_to(scheduler, id_io_write); +} + +VALUE rb_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length) { // We should ensure string has capacity to receive data, and then resize it afterwards. - return rb_funcall(scheduler, id_io_write, 4, io, buffer, offset, length); + return rb_funcall(scheduler, id_io_write, 4, io, buffer, SIZET2NUM(offset), SIZET2NUM(length)); } -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/