ruby-changes:63538
From: Samuel <ko1@a...>
Date: Sat, 7 Nov 2020 19:40:21 +0900 (JST)
Subject: [ruby-changes:63538] a08ee8330d (master): Rename to `Fiber#set_scheduler`.
https://git.ruby-lang.org/ruby.git/commit/?id=a08ee8330d From a08ee8330d3d739467bfa34deeb797d83e59ed3c Mon Sep 17 00:00:00 2001 From: Samuel Williams <samuel.williams@o...> Date: Fri, 16 Oct 2020 14:25:58 +1300 Subject: Rename to `Fiber#set_scheduler`. diff --git a/NEWS.md b/NEWS.md index e10300c..dd07085 100644 --- a/NEWS.md +++ b/NEWS.md @@ -198,10 +198,10 @@ Outstanding ones only. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L198 * Thread - * Introduce `Thread#scheduler` for intercepting blocking operations and - `Thread.scheduler` for accessing the current scheduler. See + * Introduce `Fiber.set_scheduler` for intercepting blocking operations and + `Fiber.scheduler` for accessing the current scheduler. See doc/scheduler.md for more details. [[Feature #16786]] - * `Thread#blocking?` tells whether the current execution context is + * `Fiber.blocking?` tells whether the current execution context is blocking. [[Feature #16786]] * `Thread#join` invokes the scheduler hooks `block`/`unblock` in a non-blocking execution context. [[Feature #16786]] diff --git a/cont.c b/cont.c index 2c3c7d3..8d13988 100644 --- a/cont.c +++ b/cont.c @@ -25,6 +25,7 @@ https://github.com/ruby/ruby/blob/trunk/cont.c#L25 #include "internal/mjit.h" #include "internal/proc.h" #include "internal/warnings.h" +#include "internal/scheduler.h" #include "mjit.h" #include "vm_core.h" #include "id_table.h" @@ -1821,7 +1822,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/cont.c#L1822 rb_fiber_initialize_kw(int argc, VALUE* argv, VALUE self, int kw_splat) { VALUE pool = Qnil; - VALUE blocking = Qtrue; + VALUE blocking = Qfalse; if (kw_splat != RB_NO_KEYWORDS) { VALUE options = Qnil; @@ -1830,8 +1831,13 @@ rb_fiber_initialize_kw(int argc, VALUE* argv, VALUE self, int kw_splat) https://github.com/ruby/ruby/blob/trunk/cont.c#L1831 argc = rb_scan_args_kw(kw_splat, argc, argv, ":", &options); rb_get_kwargs(options, fiber_initialize_keywords, 0, 2, arguments); - blocking = arguments[0]; - pool = arguments[1]; + if (arguments[0] != Qundef) { + blocking = arguments[0]; + } + + if (arguments[1] != Qundef) { + pool = arguments[1]; + } } return fiber_initialize(self, rb_block_proc(), rb_fiber_pool_default(pool), RTEST(blocking)); @@ -1872,6 +1878,22 @@ rb_f_fiber(int argc, VALUE *argv, VALUE obj) https://github.com/ruby/ruby/blob/trunk/cont.c#L1878 return rb_f_fiber_kw(argc, argv, rb_keyword_given_p()); } +static VALUE +rb_fiber_scheduler(VALUE klass) +{ + return rb_scheduler_get(); +} + +static VALUE +rb_fiber_set_scheduler(VALUE klass, VALUE scheduler) +{ + // if (rb_scheduler_get() != Qnil) { + // rb_raise(rb_eFiberError, "Scheduler is already defined!"); + // } + + return rb_scheduler_set(scheduler); +} + static void rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt); void @@ -2178,6 +2200,18 @@ rb_fiber_blocking_p(VALUE fiber) https://github.com/ruby/ruby/blob/trunk/cont.c#L2200 return (fiber_ptr(fiber)->blocking == 0) ? Qfalse : Qtrue; } +static VALUE +rb_f_fiber_blocking_p(VALUE klass) +{ + rb_thread_t *thread = GET_THREAD(); + unsigned blocking = thread->blocking; + + if (blocking == 0) + return Qfalse; + + return INT2NUM(blocking); +} + void rb_fiber_close(rb_fiber_t *fiber) { @@ -2594,6 +2628,10 @@ Init_Cont(void) https://github.com/ruby/ruby/blob/trunk/cont.c#L2628 rb_define_method(rb_cFiber, "to_s", fiber_to_s, 0); rb_define_alias(rb_cFiber, "inspect", "to_s"); + rb_define_singleton_method(rb_cFiber, "blocking?", rb_f_fiber_blocking_p, 0); + rb_define_singleton_method(rb_cFiber, "scheduler", rb_fiber_scheduler, 0); + rb_define_singleton_method(rb_cFiber, "set_scheduler", rb_fiber_set_scheduler, 1); + rb_define_singleton_method(rb_cFiber, "schedule", rb_f_fiber, -1); //rb_define_global_function("Fiber", rb_f_fiber, -1); diff --git a/doc/scheduler.md b/doc/scheduler.md index e641dab..19b44ee 100644 --- a/doc/scheduler.md +++ b/doc/scheduler.md @@ -76,13 +76,13 @@ Fibers can be used to create non-blocking execution contexts. https://github.com/ruby/ruby/blob/trunk/doc/scheduler.md#L76 Fiber.new(blocking: false) do puts Fiber.current.blocking? # false - # May invoke `Thread.scheduler&.io_wait`. + # May invoke `Fiber.scheduler&.io_wait`. io.read(...) - # May invoke `Thread.scheduler&.io_wait`. + # May invoke `Fiber.scheduler&.io_wait`. io.write(...) - # Will invoke `Thread.scheduler&.kernel_sleep`. + # Will invoke `Fiber.scheduler&.kernel_sleep`. sleep(n) end.resume ~~~ diff --git a/eval.c b/eval.c index 9a10cb4..a77fb66 100644 --- a/eval.c +++ b/eval.c @@ -30,6 +30,7 @@ https://github.com/ruby/ruby/blob/trunk/eval.c#L30 #include "internal/object.h" #include "internal/thread.h" #include "internal/variable.h" +#include "internal/scheduler.h" #include "iseq.h" #include "mjit.h" #include "probes.h" @@ -149,12 +150,11 @@ ruby_options(int argc, char **argv) https://github.com/ruby/ruby/blob/trunk/eval.c#L150 static void rb_ec_scheduler_finalize(rb_execution_context_t *ec) { - rb_thread_t *thread = rb_ec_thread_ptr(ec); enum ruby_tag_type state; EC_PUSH_TAG(ec); if ((state = EC_EXEC_TAG()) == TAG_NONE) { - rb_thread_scheduler_set(thread->self, Qnil); + rb_scheduler_set(Qnil); } else { state = error_handle(ec, state); diff --git a/internal/scheduler.h b/internal/scheduler.h index 186f4bd..472edc6 100644 --- a/internal/scheduler.h +++ b/internal/scheduler.h @@ -12,6 +12,12 @@ https://github.com/ruby/ruby/blob/trunk/internal/scheduler.h#L12 #include "ruby/ruby.h" #include "ruby/intern.h" +VALUE rb_scheduler_get(); +VALUE rb_scheduler_set(VALUE scheduler); + +VALUE rb_scheduler_current(); +VALUE rb_thread_scheduler_current(VALUE thread); + VALUE rb_scheduler_timeout(struct timeval *timeout); VALUE rb_scheduler_close(VALUE scheduler); diff --git a/internal/thread.h b/internal/thread.h index 13e419b..09b8551 100644 --- a/internal/thread.h +++ b/internal/thread.h @@ -39,12 +39,6 @@ VALUE rb_mutex_owned_p(VALUE self); https://github.com/ruby/ruby/blob/trunk/internal/thread.h#L39 int rb_thread_wait_for_single_fd(int fd, int events, struct timeval * timeout); -VALUE rb_thread_scheduler_get(VALUE thread); -VALUE rb_thread_scheduler_set(VALUE thread, VALUE scheduler); - -VALUE rb_thread_scheduler_if_nonblocking(VALUE thread); -VALUE rb_thread_current_scheduler(); - RUBY_SYMBOL_EXPORT_BEGIN /* Temporary. This API will be removed (renamed). */ VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd); diff --git a/io.c b/io.c index 5b3893f..95a4c7d 100644 --- a/io.c +++ b/io.c @@ -1264,7 +1264,7 @@ io_fflush(rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/io.c#L1264 VALUE rb_io_wait(VALUE io, VALUE events, VALUE timeout) { - VALUE scheduler = rb_thread_current_scheduler(); + VALUE scheduler = rb_scheduler_current(); if (scheduler != Qnil) { return rb_scheduler_io_wait(scheduler, io, events, timeout); @@ -1306,7 +1306,7 @@ rb_io_from_fd(int fd) https://github.com/ruby/ruby/blob/trunk/io.c#L1306 int rb_io_wait_readable(int f) { - VALUE scheduler = rb_thread_current_scheduler(); + VALUE scheduler = rb_scheduler_current(); if (scheduler != Qnil) { return RTEST( rb_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f)) @@ -1337,7 +1337,7 @@ rb_io_wait_readable(int f) https://github.com/ruby/ruby/blob/trunk/io.c#L1337 int rb_io_wait_writable(int f) { - VALUE scheduler = rb_thread_current_scheduler(); + VALUE scheduler = rb_scheduler_current(); if (scheduler != Qnil) { return RTEST( rb_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f)) @@ -1377,7 +1377,7 @@ rb_io_wait_writable(int f) https://github.com/ruby/ruby/blob/trunk/io.c#L1377 int rb_wait_for_single_fd(int fd, int events, struct timeval *timeout) { - VALUE scheduler = rb_thread_current_scheduler(); + VALUE scheduler = rb_scheduler_current(); if (scheduler != Qnil) { return RTEST( @@ -1538,7 +1538,7 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync) https://github.com/ruby/ruby/blob/trunk/io.c#L1538 if ((n = len) <= 0) return n; - VALUE scheduler = rb_thread_current_scheduler(); + VALUE scheduler = rb_scheduler_current(); if (scheduler != Qnil && rb_scheduler_supports_io_write(scheduler)) { ssize_t length = RB_NUM2SSIZE( rb_scheduler_io_write(scheduler, fptr->self, str, offset, len) @@ -2623,7 +2623,7 @@ bufread_call(VALUE arg) https://github.com/ruby/ruby/blob/trunk/io.c#L2623 static long io_fread(VALUE str, long offset, long size, rb_io_t *fptr) { - VALUE scheduler = rb_thread_current_scheduler(); + VALUE scheduler = rb_scheduler_current(); if (scheduler != Qnil && rb_scheduler_supports_io_read(scheduler)) { ssize_t length = RB_NUM2SSIZE( rb_scheduler_io_read(scheduler, fptr->self, str, offset, size) @@ -11077,7 +11077,7 @@ STATIC_ASSERT(pollout_expected, POLLOUT == RB_WAITFD_OUT); https://github.com/ruby/ruby/blob/trunk/io.c#L11077 static int nogvl_wait_for_single_fd(VALUE th, int fd, short events) { - VALUE scheduler = rb_thread_scheduler_if_nonblocking(th); + VALUE scheduler = rb_thread_scheduler_current(th); if (scheduler != Qnil) { struct wait_for_single_fd args = {.scheduler = scheduler, .fd = fd, .events = events}; rb_thread_call_with_gvl(rb_thread_scheduler_wait_for_single_fd, &args); @@ -11096,7 +11096,7 @@ nogvl_wait_for_single_fd(VALUE th, int fd, short events) https://github.com/ruby/ruby/blob/trunk/io.c#L11096 static int nogvl_wait_for_single_fd(VALUE th, int fd, short events) { - VALUE scheduler = rb_thread_scheduler_if_nonblocking(th); + VALUE scheduler = rb_thre (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/