[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]