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

ruby-changes:73954

From: Samuel <ko1@a...>
Date: Wed, 12 Oct 2022 08:59:30 +0900 (JST)
Subject: [ruby-changes:73954] ced1d17280 (master): Improvements to IO::Buffer implementation and documentation. (#6525)

https://git.ruby-lang.org/ruby.git/commit/?id=ced1d17280

From ced1d172804b6dfe39aa31a323ffab80a25223b9 Mon Sep 17 00:00:00 2001
From: Samuel Williams <samuel.williams@o...>
Date: Wed, 12 Oct 2022 12:59:05 +1300
Subject: Improvements to IO::Buffer implementation and documentation. (#6525)

---
 common.mk                      |   5 +
 cont.c                         |  37 +++-
 include/ruby/fiber/scheduler.h |  22 ++-
 include/ruby/io/buffer.h       |  10 +-
 io_buffer.c                    | 435 ++++++++++++++++++++++++++++-------------
 scheduler.c                    |  28 +--
 test/fiber/scheduler.rb        |  81 ++++----
 test/ruby/test_io_buffer.rb    |  22 ++-
 vm_core.h                      |   2 +-
 9 files changed, 418 insertions(+), 224 deletions(-)

diff --git a/common.mk b/common.mk
index 0fe5217566..464f64cb76 100644
--- a/common.mk
+++ b/common.mk
@@ -7717,12 +7717,17 @@ io.$(OBJEXT): {$(VPATH)}vm_core.h https://github.com/ruby/ruby/blob/trunk/common.mk#L7717
 io.$(OBJEXT): {$(VPATH)}vm_opts.h
 io_buffer.$(OBJEXT): $(hdrdir)/ruby/ruby.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/array.h
+io_buffer.$(OBJEXT): $(top_srcdir)/internal/bignum.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/bits.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/compilers.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/error.h
+io_buffer.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+io_buffer.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+io_buffer.$(OBJEXT): $(top_srcdir)/internal/serial.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/string.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/thread.h
+io_buffer.$(OBJEXT): $(top_srcdir)/internal/vm.h
 io_buffer.$(OBJEXT): {$(VPATH)}assert.h
 io_buffer.$(OBJEXT): {$(VPATH)}backward/2/assume.h
 io_buffer.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
diff --git a/cont.c b/cont.c
index 499e1e7910..39f0fc8171 100644
--- a/cont.c
+++ b/cont.c
@@ -2410,20 +2410,34 @@ rb_fiber_transfer(VALUE fiber_value, int argc, const VALUE *argv) https://github.com/ruby/ruby/blob/trunk/cont.c#L2410
 VALUE
 rb_fiber_blocking_p(VALUE fiber)
 {
-    return RBOOL(fiber_ptr(fiber)->blocking != 0);
+    return RBOOL(fiber_ptr(fiber)->blocking);
 }
 
 static VALUE
-fiber_blocking_yield(VALUE fiber)
+fiber_blocking_yield(VALUE fiber_value)
 {
-    fiber_ptr(fiber)->blocking += 1;
-    return rb_yield(fiber);
+    rb_fiber_t *fiber = fiber_ptr(fiber_value);
+    rb_thread_t * volatile th = fiber->cont.saved_ec.thread_ptr;
+
+    // fiber->blocking is `unsigned int : 1`, so we use it as a boolean:
+    fiber->blocking = 1;
+
+    // Once the fiber is blocking, and current, we increment the thread blocking state:
+    th->blocking += 1;
+
+    return rb_yield(fiber_value);
 }
 
 static VALUE
-fiber_blocking_ensure(VALUE fiber)
+fiber_blocking_ensure(VALUE fiber_value)
 {
-    fiber_ptr(fiber)->blocking -= 1;
+    rb_fiber_t *fiber = fiber_ptr(fiber_value);
+    rb_thread_t * volatile th = fiber->cont.saved_ec.thread_ptr;
+
+    // We are no longer blocking:
+    fiber->blocking = 0;
+    th->blocking -= 1;
+
     return Qnil;
 }
 
@@ -2440,8 +2454,15 @@ fiber_blocking_ensure(VALUE fiber) https://github.com/ruby/ruby/blob/trunk/cont.c#L2454
 VALUE
 rb_fiber_blocking(VALUE class)
 {
-    VALUE fiber = rb_fiber_current();
-    return rb_ensure(fiber_blocking_yield, fiber, fiber_blocking_ensure, fiber);
+    VALUE fiber_value = rb_fiber_current();
+    rb_fiber_t *fiber = fiber_ptr(fiber_value);
+
+    // If we are already blocking, this is essentially a no-op:
+    if (fiber->blocking) {
+        return rb_yield(fiber_value);
+    } else {
+        return rb_ensure(fiber_blocking_yield, fiber_value, fiber_blocking_ensure, fiber_value);
+    }
 }
 
 /*
diff --git a/include/ruby/fiber/scheduler.h b/include/ruby/fiber/scheduler.h
index d38651da5c..37985e1285 100644
--- a/include/ruby/fiber/scheduler.h
+++ b/include/ruby/fiber/scheduler.h
@@ -23,6 +23,8 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/fiber/scheduler.h#L23
 
 RBIMPL_SYMBOL_EXPORT_BEGIN()
 
+#define RUBY_FIBER_SCHEDULER_VERSION 2
+
 struct timeval;
 
 /**
@@ -248,10 +250,11 @@ VALUE rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io); https://github.com/ruby/ruby/blob/trunk/include/ruby/fiber/scheduler.h#L250
  * @param[out]  io           An io object to read from.
  * @param[out]  buffer       Return buffer.
  * @param[in]   length       Requested number of bytes to read.
+ * @param[in]   offset       The offset in the buffer to read to.
  * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_read`.
  * @return      otherwise    What `scheduler.io_read` returns `[-errno, size]`.
  */
-VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t length);
+VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset);
 
 /**
  * Nonblocking write to the passed IO.
@@ -260,36 +263,39 @@ VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t https://github.com/ruby/ruby/blob/trunk/include/ruby/fiber/scheduler.h#L263
  * @param[out]  io           An io object to write to.
  * @param[in]   buffer       What to write.
  * @param[in]   length       Number of bytes to write.
+ * @param[in]   offset       The offset in the buffer to write from.
  * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_write`.
  * @return      otherwise    What `scheduler.io_write` returns `[-errno, size]`.
  */
-VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t length);
+VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset);
 
 /**
  * Nonblocking read from the passed IO at the specified offset.
  *
  * @param[in]   scheduler    Target scheduler.
  * @param[out]  io           An io object to read from.
- * @param[out]  buffer       Return buffer.
+ * @param[in]   from         The offset in the given IO to read the data from.
+ * @param[out]  buffer       The buffer to read the data to.
  * @param[in]   length       Requested number of bytes to read.
- * @param[in]   offset       The offset in the given IO to read the data from.
+ * @param[in]   offset       The offset in the buffer to read to.
  * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_read`.
  * @return      otherwise    What `scheduler.io_read` returns.
  */
-VALUE rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, VALUE buffer, size_t length, rb_off_t offset);
+VALUE rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset);
 
 /**
  * Nonblocking write to the passed IO at the specified offset.
  *
  * @param[in]   scheduler    Target scheduler.
  * @param[out]  io           An io object to write to.
- * @param[in]   buffer       What to write.
+ * @param[in]   from         The offset in the given IO to write the data to.
+ * @param[in]   buffer       The buffer to write the data from.
  * @param[in]   length       Number of bytes to write.
- * @param[in]   offset       The offset in the given IO to write the data to.
+ * @param[in]   offset       The offset in the buffer to write from.
  * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_write`.
  * @return      otherwise    What `scheduler.io_write` returns.
  */
-VALUE rb_fiber_scheduler_io_pwrite(VALUE scheduler, VALUE io, VALUE buffer, size_t length, rb_off_t offset);
+VALUE rb_fiber_scheduler_io_pwrite(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset);
 
 /**
  * Nonblocking read from the passed IO using a native buffer.
diff --git a/include/ruby/io/buffer.h b/include/ruby/io/buffer.h
index 16b23ec629..dd92db5bbe 100644
--- a/include/ruby/io/buffer.h
+++ b/include/ruby/io/buffer.h
@@ -21,6 +21,8 @@ RBIMPL_SYMBOL_EXPORT_BEGIN() https://github.com/ruby/ruby/blob/trunk/include/ruby/io/buffer.h#L21
 // WARNING: This entire interface is experimental and may change in the future!
 #define RB_IO_BUFFER_EXPERIMENTAL 1
 
+#define RUBY_IO_BUFFER_VERSION 2
+
 RUBY_EXTERN VALUE rb_cIOBuffer;
 RUBY_EXTERN size_t RUBY_IO_BUFFER_PAGE_SIZE;
 RUBY_EXTERN size_t RUBY_IO_BUFFER_DEFAULT_SIZE;
@@ -81,10 +83,10 @@ void rb_io_buffer_resize(VALUE self, size_t size); https://github.com/ruby/ruby/blob/trunk/include/ruby/io/buffer.h#L83
 void rb_io_buffer_clear(VALUE self, uint8_t value, size_t offset, size_t length);
 
 // The length is the minimum required length.
-VALUE rb_io_buffer_read(VALUE self, VALUE io, size_t length);
-VALUE rb_io_buffer_pread(VALUE self, VALUE io, size_t length, rb_off_t offset);
-VALUE rb_io_buffer_write(VALUE self, VALUE io, size_t length);
-VALUE rb_io_buffer_pwrite(VALUE self, VALUE io, size_t length, rb_off_t offset);
+VALUE rb_io_buffer_read(VALUE self, VALUE io, size_t length, size_t offset);
+VALUE rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset);
+VALUE rb_io_buffer_write(VALUE self, VALUE io, size_t length, size_t offset);
+VALUE rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset);
 
 RBIMPL_SYMBOL_EXPORT_END()
 
diff --git a/io_buffer.c b/io_buffer.c
index 4326d21def..bc5fac8118 100644
--- a/io_buffer.c
+++ b/io_buffer.c
@@ -14,6 +14,7 @@ https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L14
 #include "internal/array.h"
 #include "internal/bits.h"
 #include "internal/error.h"
+#include "internal/numeric.h"
 #include "internal/string.h"
 #include "internal/thread.h"
 
@@ -439,27 +440,29 @@ rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer_flags https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L440
  *  mapping, you need to open a file in read-write mode, and explicitly pass
  *  +flags+ argument without IO::Buffer::IMMUTABLE.
  *
- *     File.write('test.txt', 'test')
+ *  Example:
  *
- *     buffer = IO::Buffer.map(File.open('test.txt'), nil, 0, IO::Buffer::READONLY)
- *     # => #<IO::Buffer 0x00000001014a0000+4 MAPPED READONLY>
+ *   (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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