summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-02-09 19:39:56 +1300
committerGitHub <noreply@github.com>2021-02-09 19:39:56 +1300
commit5f69a7f60467fa58c2f998daffab43e118bff36c (patch)
treef60e3a5add29eb9cc7e68433c4e373e2a2facab7
parent3c593f28ede99b77d4fe3258f9bda78dcee238a3 (diff)
Expose scheduler as public interface & bug fixes. (#3945)
* Rename `rb_scheduler` to `rb_fiber_scheduler`. * Use public interface if available. * Use `rb_check_funcall` where possible. * Don't use `unblock` unless the fiber was non-blocking.
Notes
Notes: Merged-By: ioquatix <samuel@codeotaku.com>
-rw-r--r--common.mk20
-rw-r--r--cont.c15
-rw-r--r--eval.c8
-rw-r--r--ext/io/console/console.c7
-rw-r--r--ext/io/console/extconf.rb2
-rw-r--r--ext/psych/depend185
-rw-r--r--include/ruby/fiber/scheduler.h40
-rw-r--r--inits.c2
-rw-r--r--internal/cont.h1
-rw-r--r--internal/scheduler.h44
-rw-r--r--io.c62
-rw-r--r--process.c13
-rw-r--r--scheduler.c84
-rw-r--r--test/fiber/http.rb11
-rw-r--r--test/fiber/scheduler.rb24
-rw-r--r--test/fiber/test_thread.rb45
-rw-r--r--thread.c16
-rw-r--r--thread_sync.c20
18 files changed, 355 insertions, 244 deletions
diff --git a/common.mk b/common.mk
index 810530c..1a3de30 100644
--- a/common.mk
+++ b/common.mk
@@ -3196,13 +3196,13 @@ cont.$(OBJEXT): $(CCAN_DIR)/list/list.h
cont.$(OBJEXT): $(CCAN_DIR)/str/str.h
cont.$(OBJEXT): $(hdrdir)/ruby.h
cont.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+cont.$(OBJEXT): $(top_srcdir)/include/ruby/fiber/scheduler.h
cont.$(OBJEXT): $(top_srcdir)/internal/array.h
cont.$(OBJEXT): $(top_srcdir)/internal/compilers.h
cont.$(OBJEXT): $(top_srcdir)/internal/cont.h
cont.$(OBJEXT): $(top_srcdir)/internal/gc.h
cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h
cont.$(OBJEXT): $(top_srcdir)/internal/proc.h
-cont.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
cont.$(OBJEXT): $(top_srcdir)/internal/serial.h
cont.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
cont.$(OBJEXT): $(top_srcdir)/internal/vm.h
@@ -3224,6 +3224,7 @@ cont.$(OBJEXT): {$(VPATH)}cont.c
cont.$(OBJEXT): {$(VPATH)}debug_counter.h
cont.$(OBJEXT): {$(VPATH)}defines.h
cont.$(OBJEXT): {$(VPATH)}eval_intern.h
+cont.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
cont.$(OBJEXT): {$(VPATH)}gc.h
cont.$(OBJEXT): {$(VPATH)}id.h
cont.$(OBJEXT): {$(VPATH)}id_table.h
@@ -5215,6 +5216,7 @@ eval.$(OBJEXT): $(CCAN_DIR)/list/list.h
eval.$(OBJEXT): $(CCAN_DIR)/str/str.h
eval.$(OBJEXT): $(hdrdir)/ruby.h
eval.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+eval.$(OBJEXT): $(top_srcdir)/include/ruby/fiber/scheduler.h
eval.$(OBJEXT): $(top_srcdir)/internal/array.h
eval.$(OBJEXT): $(top_srcdir)/internal/class.h
eval.$(OBJEXT): $(top_srcdir)/internal/compilers.h
@@ -5226,7 +5228,6 @@ eval.$(OBJEXT): $(top_srcdir)/internal/imemo.h
eval.$(OBJEXT): $(top_srcdir)/internal/inits.h
eval.$(OBJEXT): $(top_srcdir)/internal/io.h
eval.$(OBJEXT): $(top_srcdir)/internal/object.h
-eval.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
eval.$(OBJEXT): $(top_srcdir)/internal/serial.h
eval.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
eval.$(OBJEXT): $(top_srcdir)/internal/string.h
@@ -5254,6 +5255,7 @@ eval.$(OBJEXT): {$(VPATH)}eval.c
eval.$(OBJEXT): {$(VPATH)}eval_error.c
eval.$(OBJEXT): {$(VPATH)}eval_intern.h
eval.$(OBJEXT): {$(VPATH)}eval_jump.c
+eval.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
eval.$(OBJEXT): {$(VPATH)}gc.h
eval.$(OBJEXT): {$(VPATH)}id.h
eval.$(OBJEXT): {$(VPATH)}id_table.h
@@ -6562,6 +6564,7 @@ io.$(OBJEXT): $(CCAN_DIR)/list/list.h
io.$(OBJEXT): $(CCAN_DIR)/str/str.h
io.$(OBJEXT): $(hdrdir)/ruby.h
io.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+io.$(OBJEXT): $(top_srcdir)/include/ruby/fiber/scheduler.h
io.$(OBJEXT): $(top_srcdir)/internal/array.h
io.$(OBJEXT): $(top_srcdir)/internal/bignum.h
io.$(OBJEXT): $(top_srcdir)/internal/bits.h
@@ -6577,7 +6580,6 @@ io.$(OBJEXT): $(top_srcdir)/internal/io.h
io.$(OBJEXT): $(top_srcdir)/internal/numeric.h
io.$(OBJEXT): $(top_srcdir)/internal/object.h
io.$(OBJEXT): $(top_srcdir)/internal/process.h
-io.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
io.$(OBJEXT): $(top_srcdir)/internal/serial.h
io.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
io.$(OBJEXT): $(top_srcdir)/internal/string.h
@@ -6604,6 +6606,7 @@ io.$(OBJEXT): {$(VPATH)}defines.h
io.$(OBJEXT): {$(VPATH)}dln.h
io.$(OBJEXT): {$(VPATH)}encindex.h
io.$(OBJEXT): {$(VPATH)}encoding.h
+io.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
io.$(OBJEXT): {$(VPATH)}id.h
io.$(OBJEXT): {$(VPATH)}id_table.h
io.$(OBJEXT): {$(VPATH)}intern.h
@@ -10017,6 +10020,7 @@ process.$(OBJEXT): $(CCAN_DIR)/list/list.h
process.$(OBJEXT): $(CCAN_DIR)/str/str.h
process.$(OBJEXT): $(hdrdir)/ruby.h
process.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+process.$(OBJEXT): $(top_srcdir)/include/ruby/fiber/scheduler.h
process.$(OBJEXT): $(top_srcdir)/internal/array.h
process.$(OBJEXT): $(top_srcdir)/internal/bits.h
process.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -10029,7 +10033,6 @@ process.$(OBJEXT): $(top_srcdir)/internal/hash.h
process.$(OBJEXT): $(top_srcdir)/internal/imemo.h
process.$(OBJEXT): $(top_srcdir)/internal/object.h
process.$(OBJEXT): $(top_srcdir)/internal/process.h
-process.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
process.$(OBJEXT): $(top_srcdir)/internal/serial.h
process.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
process.$(OBJEXT): $(top_srcdir)/internal/string.h
@@ -10055,6 +10058,7 @@ process.$(OBJEXT): {$(VPATH)}debug_counter.h
process.$(OBJEXT): {$(VPATH)}defines.h
process.$(OBJEXT): {$(VPATH)}dln.h
process.$(OBJEXT): {$(VPATH)}encoding.h
+process.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
process.$(OBJEXT): {$(VPATH)}hrtime.h
process.$(OBJEXT): {$(VPATH)}id.h
process.$(OBJEXT): {$(VPATH)}id_table.h
@@ -12357,11 +12361,11 @@ scheduler.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
scheduler.$(OBJEXT): $(CCAN_DIR)/list/list.h
scheduler.$(OBJEXT): $(CCAN_DIR)/str/str.h
scheduler.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+scheduler.$(OBJEXT): $(top_srcdir)/include/ruby/fiber/scheduler.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/array.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-scheduler.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/serial.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/vm.h
@@ -12380,7 +12384,9 @@ scheduler.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
scheduler.$(OBJEXT): {$(VPATH)}config.h
scheduler.$(OBJEXT): {$(VPATH)}defines.h
scheduler.$(OBJEXT): {$(VPATH)}encoding.h
+scheduler.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
scheduler.$(OBJEXT): {$(VPATH)}id.h
+scheduler.$(OBJEXT): {$(VPATH)}include/ruby/fiber/scheduler.h
scheduler.$(OBJEXT): {$(VPATH)}intern.h
scheduler.$(OBJEXT): {$(VPATH)}internal.h
scheduler.$(OBJEXT): {$(VPATH)}internal/anyargs.h
@@ -12512,7 +12518,6 @@ scheduler.$(OBJEXT): {$(VPATH)}internal/module.h
scheduler.$(OBJEXT): {$(VPATH)}internal/newobj.h
scheduler.$(OBJEXT): {$(VPATH)}internal/rgengc.h
scheduler.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-scheduler.$(OBJEXT): {$(VPATH)}internal/scheduler.h
scheduler.$(OBJEXT): {$(VPATH)}internal/special_consts.h
scheduler.$(OBJEXT): {$(VPATH)}internal/static_assert.h
scheduler.$(OBJEXT): {$(VPATH)}internal/stdalign.h
@@ -14034,6 +14039,7 @@ thread.$(OBJEXT): $(CCAN_DIR)/list/list.h
thread.$(OBJEXT): $(CCAN_DIR)/str/str.h
thread.$(OBJEXT): $(hdrdir)/ruby.h
thread.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+thread.$(OBJEXT): $(top_srcdir)/include/ruby/fiber/scheduler.h
thread.$(OBJEXT): $(top_srcdir)/internal/array.h
thread.$(OBJEXT): $(top_srcdir)/internal/bits.h
thread.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -14046,7 +14052,6 @@ thread.$(OBJEXT): $(top_srcdir)/internal/imemo.h
thread.$(OBJEXT): $(top_srcdir)/internal/io.h
thread.$(OBJEXT): $(top_srcdir)/internal/object.h
thread.$(OBJEXT): $(top_srcdir)/internal/proc.h
-thread.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
thread.$(OBJEXT): $(top_srcdir)/internal/serial.h
thread.$(OBJEXT): $(top_srcdir)/internal/signal.h
thread.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@@ -14073,6 +14078,7 @@ thread.$(OBJEXT): {$(VPATH)}debug_counter.h
thread.$(OBJEXT): {$(VPATH)}defines.h
thread.$(OBJEXT): {$(VPATH)}encoding.h
thread.$(OBJEXT): {$(VPATH)}eval_intern.h
+thread.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
thread.$(OBJEXT): {$(VPATH)}gc.h
thread.$(OBJEXT): {$(VPATH)}hrtime.h
thread.$(OBJEXT): {$(VPATH)}id.h
diff --git a/cont.c b/cont.c
index 694c2d9..abd6a2f 100644
--- a/cont.c
+++ b/cont.c
@@ -24,7 +24,7 @@
#include "internal/cont.h"
#include "internal/proc.h"
#include "internal/warnings.h"
-#include "internal/scheduler.h"
+#include "ruby/fiber/scheduler.h"
#include "mjit.h"
#include "vm_core.h"
#include "id_table.h"
@@ -1156,6 +1156,11 @@ VALUE rb_fiberptr_self(struct rb_fiber_struct *fiber)
return fiber->cont.self;
}
+unsigned int rb_fiberptr_blocking(struct rb_fiber_struct *fiber)
+{
+ return fiber->blocking;
+}
+
// This is used for root_fiber because other fibers call cont_init_mjit_cont through cont_new.
void
rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber)
@@ -1975,7 +1980,7 @@ rb_f_fiber(int argc, VALUE *argv, VALUE obj)
static VALUE
rb_fiber_scheduler(VALUE klass)
{
- return rb_scheduler_get();
+ return rb_fiber_scheduler_get();
}
/*
@@ -1997,11 +2002,7 @@ rb_fiber_scheduler(VALUE klass)
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);
+ return rb_fiber_scheduler_set(scheduler);
}
static void rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt);
diff --git a/eval.c b/eval.c
index 55d66b5..ed8a88c 100644
--- a/eval.c
+++ b/eval.c
@@ -29,7 +29,7 @@
#include "internal/object.h"
#include "internal/thread.h"
#include "internal/variable.h"
-#include "internal/scheduler.h"
+#include "ruby/fiber/scheduler.h"
#include "iseq.h"
#include "mjit.h"
#include "probes.h"
@@ -147,13 +147,13 @@ ruby_options(int argc, char **argv)
}
static void
-rb_ec_scheduler_finalize(rb_execution_context_t *ec)
+rb_ec_fiber_scheduler_finalize(rb_execution_context_t *ec)
{
enum ruby_tag_type state;
EC_PUSH_TAG(ec);
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
- rb_scheduler_set(Qnil);
+ rb_fiber_scheduler_set(Qnil);
}
else {
state = error_handle(ec, state);
@@ -165,7 +165,7 @@ static void
rb_ec_teardown(rb_execution_context_t *ec)
{
// If the user code defined a scheduler for the top level thread, run it:
- rb_ec_scheduler_finalize(ec);
+ rb_ec_fiber_scheduler_finalize(ec);
EC_PUSH_TAG(ec);
if (EC_EXEC_TAG() == TAG_NONE) {
diff --git a/ext/io/console/console.c b/ext/io/console/console.c
index 2e24670..6999a3f 100644
--- a/ext/io/console/console.c
+++ b/ext/io/console/console.c
@@ -80,8 +80,11 @@ static ID id_getc, id_console, id_close, id_min, id_time, id_intr;
static ID id_gets, id_chomp_bang;
#endif
-#ifdef HAVE_RB_SCHEDULER_TIMEOUT
+#if defined HAVE_RUBY_FIBER_SCHEDULER_H
+# include "ruby/fiber/scheduler.h"
+#elif defined HAVE_RB_SCHEDULER_TIMEOUT
extern VALUE rb_scheduler_timeout(struct timeval *timeout);
+# define rb_fiber_scheduler_timeout rb_scheduler_timeout
#endif
#define sys_fail_fptr(fptr) rb_sys_fail_str((fptr)->pathv)
@@ -534,7 +537,7 @@ console_getch(int argc, VALUE *argv, VALUE io)
tv.tv_sec = optp->vtime / 10;
tv.tv_usec = (optp->vtime % 10) * 100000;
# ifdef HAVE_RB_IO_WAIT
- timeout = rb_scheduler_timeout(&tv);
+ timeout = rb_fiber_scheduler_make_timeout(&tv);
# endif
}
switch (optp->vmin) {
diff --git a/ext/io/console/extconf.rb b/ext/io/console/extconf.rb
index 3efdd6e..40af8c0 100644
--- a/ext/io/console/extconf.rb
+++ b/ext/io/console/extconf.rb
@@ -24,7 +24,7 @@ when true
# rb_funcallv: 2.1.0
# RARRAY_CONST_PTR: 2.1.0
# rb_sym2str: 2.2.0
- if have_func("rb_scheduler_timeout")
+ if have_func("rb_fiber_scheduler_make_timeout")
have_func("rb_io_wait")
end
$defs << "-D""ENABLE_IO_GETPASS=1"
diff --git a/ext/psych/depend b/ext/psych/depend
index 2017319..06f24f4 100644
--- a/ext/psych/depend
+++ b/ext/psych/depend
@@ -1,9 +1,48 @@
$(OBJS): $(YAML_H)
# AUTOGENERATED DEPENDENCIES START
+api.o: $(RUBY_EXTCONF_H)
+api.o: yaml/api.c
+api.o: yaml/config.h
+api.o: yaml/yaml.h
+api.o: yaml/yaml_private.h
+dumper.o: $(RUBY_EXTCONF_H)
+dumper.o: yaml/config.h
+dumper.o: yaml/dumper.c
+dumper.o: yaml/yaml.h
+dumper.o: yaml/yaml_private.h
+emitter.o: $(RUBY_EXTCONF_H)
+emitter.o: yaml/config.h
+emitter.o: yaml/emitter.c
+emitter.o: yaml/yaml.h
+emitter.o: yaml/yaml_private.h
+loader.o: $(RUBY_EXTCONF_H)
+loader.o: yaml/config.h
+loader.o: yaml/loader.c
+loader.o: yaml/yaml.h
+loader.o: yaml/yaml_private.h
+parser.o: $(RUBY_EXTCONF_H)
+parser.o: yaml/config.h
+parser.o: yaml/parser.c
+parser.o: yaml/yaml.h
+parser.o: yaml/yaml_private.h
psych.o: $(RUBY_EXTCONF_H)
psych.o: $(arch_hdrdir)/ruby/config.h
psych.o: $(hdrdir)/ruby.h
+psych.o: $(hdrdir)/ruby/assert.h
+psych.o: $(hdrdir)/ruby/backward.h
+psych.o: $(hdrdir)/ruby/backward/2/assume.h
+psych.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych.o: $(hdrdir)/ruby/backward/2/bool.h
+psych.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych.o: $(hdrdir)/ruby/backward/2/limits.h
+psych.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych.o: $(hdrdir)/ruby/backward/2/stdarg.h
+psych.o: $(hdrdir)/ruby/defines.h
+psych.o: $(hdrdir)/ruby/encoding.h
+psych.o: $(hdrdir)/ruby/intern.h
psych.o: $(hdrdir)/ruby/internal/anyargs.h
psych.o: $(hdrdir)/ruby/internal/arithmetic.h
psych.o: $(hdrdir)/ruby/internal/arithmetic/char.h
@@ -144,20 +183,6 @@ psych.o: $(hdrdir)/ruby/internal/value_type.h
psych.o: $(hdrdir)/ruby/internal/variable.h
psych.o: $(hdrdir)/ruby/internal/warning_push.h
psych.o: $(hdrdir)/ruby/internal/xmalloc.h
-psych.o: $(hdrdir)/ruby/assert.h
-psych.o: $(hdrdir)/ruby/backward.h
-psych.o: $(hdrdir)/ruby/backward/2/assume.h
-psych.o: $(hdrdir)/ruby/backward/2/attributes.h
-psych.o: $(hdrdir)/ruby/backward/2/bool.h
-psych.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-psych.o: $(hdrdir)/ruby/backward/2/inttypes.h
-psych.o: $(hdrdir)/ruby/backward/2/limits.h
-psych.o: $(hdrdir)/ruby/backward/2/long_long.h
-psych.o: $(hdrdir)/ruby/backward/2/stdalign.h
-psych.o: $(hdrdir)/ruby/backward/2/stdarg.h
-psych.o: $(hdrdir)/ruby/defines.h
-psych.o: $(hdrdir)/ruby/encoding.h
-psych.o: $(hdrdir)/ruby/intern.h
psych.o: $(hdrdir)/ruby/missing.h
psych.o: $(hdrdir)/ruby/onigmo.h
psych.o: $(hdrdir)/ruby/oniguruma.h
@@ -170,9 +195,24 @@ psych.o: psych_emitter.h
psych.o: psych_parser.h
psych.o: psych_to_ruby.h
psych.o: psych_yaml_tree.h
+psych.o: yaml/yaml.h
psych_emitter.o: $(RUBY_EXTCONF_H)
psych_emitter.o: $(arch_hdrdir)/ruby/config.h
psych_emitter.o: $(hdrdir)/ruby.h
+psych_emitter.o: $(hdrdir)/ruby/assert.h
+psych_emitter.o: $(hdrdir)/ruby/backward.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/assume.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/bool.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/limits.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/stdarg.h
+psych_emitter.o: $(hdrdir)/ruby/defines.h
+psych_emitter.o: $(hdrdir)/ruby/encoding.h
+psych_emitter.o: $(hdrdir)/ruby/intern.h
psych_emitter.o: $(hdrdir)/ruby/internal/anyargs.h
psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic.h
psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/char.h
@@ -313,20 +353,6 @@ psych_emitter.o: $(hdrdir)/ruby/internal/value_type.h
psych_emitter.o: $(hdrdir)/ruby/internal/variable.h
psych_emitter.o: $(hdrdir)/ruby/internal/warning_push.h
psych_emitter.o: $(hdrdir)/ruby/internal/xmalloc.h
-psych_emitter.o: $(hdrdir)/ruby/assert.h
-psych_emitter.o: $(hdrdir)/ruby/backward.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/assume.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/attributes.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/bool.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/inttypes.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/limits.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/long_long.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/stdalign.h
-psych_emitter.o: $(hdrdir)/ruby/backward/2/stdarg.h
-psych_emitter.o: $(hdrdir)/ruby/defines.h
-psych_emitter.o: $(hdrdir)/ruby/encoding.h
-psych_emitter.o: $(hdrdir)/ruby/intern.h
psych_emitter.o: $(hdrdir)/ruby/missing.h
psych_emitter.o: $(hdrdir)/ruby/onigmo.h
psych_emitter.o: $(hdrdir)/ruby/oniguruma.h
@@ -339,9 +365,24 @@ psych_emitter.o: psych_emitter.h
psych_emitter.o: psych_parser.h
psych_emitter.o: psych_to_ruby.h
psych_emitter.o: psych_yaml_tree.h
+psych_emitter.o: yaml/yaml.h
psych_parser.o: $(RUBY_EXTCONF_H)
psych_parser.o: $(arch_hdrdir)/ruby/config.h
psych_parser.o: $(hdrdir)/ruby.h
+psych_parser.o: $(hdrdir)/ruby/assert.h
+psych_parser.o: $(hdrdir)/ruby/backward.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/assume.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/bool.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/limits.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/stdarg.h
+psych_parser.o: $(hdrdir)/ruby/defines.h
+psych_parser.o: $(hdrdir)/ruby/encoding.h
+psych_parser.o: $(hdrdir)/ruby/intern.h
psych_parser.o: $(hdrdir)/ruby/internal/anyargs.h
psych_parser.o: $(hdrdir)/ruby/internal/arithmetic.h
psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/char.h
@@ -482,20 +523,6 @@ psych_parser.o: $(hdrdir)/ruby/internal/value_type.h
psych_parser.o: $(hdrdir)/ruby/internal/variable.h
psych_parser.o: $(hdrdir)/ruby/internal/warning_push.h
psych_parser.o: $(hdrdir)/ruby/internal/xmalloc.h
-psych_parser.o: $(hdrdir)/ruby/assert.h
-psych_parser.o: $(hdrdir)/ruby/backward.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/assume.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/attributes.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/bool.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/inttypes.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/limits.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/long_long.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/stdalign.h
-psych_parser.o: $(hdrdir)/ruby/backward/2/stdarg.h
-psych_parser.o: $(hdrdir)/ruby/defines.h
-psych_parser.o: $(hdrdir)/ruby/encoding.h
-psych_parser.o: $(hdrdir)/ruby/intern.h
psych_parser.o: $(hdrdir)/ruby/missing.h
psych_parser.o: $(hdrdir)/ruby/onigmo.h
psych_parser.o: $(hdrdir)/ruby/oniguruma.h
@@ -508,9 +535,24 @@ psych_parser.o: psych_parser.c
psych_parser.o: psych_parser.h
psych_parser.o: psych_to_ruby.h
psych_parser.o: psych_yaml_tree.h
+psych_parser.o: yaml/yaml.h
psych_to_ruby.o: $(RUBY_EXTCONF_H)
psych_to_ruby.o: $(arch_hdrdir)/ruby/config.h
psych_to_ruby.o: $(hdrdir)/ruby.h
+psych_to_ruby.o: $(hdrdir)/ruby/assert.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/assume.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/bool.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/limits.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/stdarg.h
+psych_to_ruby.o: $(hdrdir)/ruby/defines.h
+psych_to_ruby.o: $(hdrdir)/ruby/encoding.h
+psych_to_ruby.o: $(hdrdir)/ruby/intern.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/anyargs.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/char.h
@@ -651,20 +693,6 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/value_type.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/variable.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/warning_push.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/xmalloc.h
-psych_to_ruby.o: $(hdrdir)/ruby/assert.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/assume.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/attributes.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/bool.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/inttypes.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/limits.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/long_long.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/stdalign.h
-psych_to_ruby.o: $(hdrdir)/ruby/backward/2/stdarg.h
-psych_to_ruby.o: $(hdrdir)/ruby/defines.h
-psych_to_ruby.o: $(hdrdir)/ruby/encoding.h
-psych_to_ruby.o: $(hdrdir)/ruby/intern.h
psych_to_ruby.o: $(hdrdir)/ruby/missing.h
psych_to_ruby.o: $(hdrdir)/ruby/onigmo.h
psych_to_ruby.o: $(hdrdir)/ruby/oniguruma.h
@@ -677,9 +705,24 @@ psych_to_ruby.o: psych_parser.h
psych_to_ruby.o: psych_to_ruby.c
psych_to_ruby.o: psych_to_ruby.h
psych_to_ruby.o: psych_yaml_tree.h
+psych_to_ruby.o: yaml/yaml.h
psych_yaml_tree.o: $(RUBY_EXTCONF_H)
psych_yaml_tree.o: $(arch_hdrdir)/ruby/config.h
psych_yaml_tree.o: $(hdrdir)/ruby.h
+psych_yaml_tree.o: $(hdrdir)/ruby/assert.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/assume.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/bool.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/limits.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/stdarg.h
+psych_yaml_tree.o: $(hdrdir)/ruby/defines.h
+psych_yaml_tree.o: $(hdrdir)/ruby/encoding.h
+psych_yaml_tree.o: $(hdrdir)/ruby/intern.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/anyargs.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/char.h
@@ -820,20 +863,6 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/value_type.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/variable.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/warning_push.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/xmalloc.h
-psych_yaml_tree.o: $(hdrdir)/ruby/assert.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/assume.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/attributes.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/bool.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/inttypes.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/limits.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/long_long.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/stdalign.h
-psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/stdarg.h
-psych_yaml_tree.o: $(hdrdir)/ruby/defines.h
-psych_yaml_tree.o: $(hdrdir)/ruby/encoding.h
-psych_yaml_tree.o: $(hdrdir)/ruby/intern.h
psych_yaml_tree.o: $(hdrdir)/ruby/missing.h
psych_yaml_tree.o: $(hdrdir)/ruby/onigmo.h
psych_yaml_tree.o: $(hdrdir)/ruby/oniguruma.h
@@ -846,4 +875,20 @@ psych_yaml_tree.o: psych_parser.h
psych_yaml_tree.o: psych_to_ruby.h
psych_yaml_tree.o: psych_yaml_tree.c
psych_yaml_tree.o: psych_yaml_tree.h
+psych_yaml_tree.o: yaml/yaml.h
+reader.o: $(RUBY_EXTCONF_H)
+reader.o: yaml/config.h
+reader.o: yaml/reader.c
+reader.o: yaml/yaml.h
+reader.o: yaml/yaml_private.h
+scanner.o: $(RUBY_EXTCONF_H)
+scanner.o: yaml/config.h
+scanner.o: yaml/scanner.c
+scanner.o: yaml/yaml.h
+scanner.o: yaml/yaml_private.h
+writer.o: $(RUBY_EXTCONF_H)
+writer.o: yaml/config.h
+writer.o: yaml/writer.c
+writer.o: yaml/yaml.h
+writer.o: yaml/yaml_private.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/include/ruby/fiber/scheduler.h b/include/ruby/fiber/scheduler.h
new file mode 100644
index 0000000..741cc24
--- /dev/null
+++ b/include/ruby/fiber/scheduler.h
@@ -0,0 +1,40 @@
+#ifndef RUBY_FIBER_SCHEDULER_H /*-*-C-*-vi:se ft=c:*/
+#define RUBY_FIBER_SCHEDULER_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Scheduler.
+ */
+#include "ruby/ruby.h"
+#include "ruby/intern.h"
+
+VALUE rb_fiber_scheduler_get();
+VALUE rb_fiber_scheduler_set(VALUE scheduler);
+
+VALUE rb_fiber_scheduler_current();
+VALUE rb_fiber_scheduler_current_for_thread(VALUE thread);
+
+VALUE rb_fiber_scheduler_make_timeout(struct timeval *timeout);
+
+VALUE rb_fiber_scheduler_close(VALUE scheduler);
+
+VALUE rb_fiber_scheduler_kernel_sleep(VALUE scheduler, VALUE duration);
+VALUE rb_fiber_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv);
+
+int rb_fiber_scheduler_supports_process_wait(VALUE scheduler);
+VALUE rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags);
+
+VALUE rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout);
+VALUE rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber);
+
+VALUE rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout);
+VALUE rb_fiber_scheduler_io_wait_readable(VALUE scheduler, VALUE io);
+VALUE rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io);
+VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length);
+VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length);
+
+#endif /* RUBY_FIBER_SCHEDULER_H */
diff --git a/inits.c b/inits.c
index d2c99ed..185f14b 100644
--- a/inits.c
+++ b/inits.c
@@ -65,7 +65,7 @@ rb_call_inits(void)
CALL(VM);
CALL(ISeq);
CALL(Thread);
- CALL(Scheduler);
+ CALL(Fiber_Scheduler);
CALL(process);
CALL(Cont);
CALL(Rational);
diff --git a/internal/cont.h b/internal/cont.h
index a365cbe..9e49dd3 100644
--- a/internal/cont.h
+++ b/internal/cont.h
@@ -21,5 +21,6 @@ void ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(VALUE), VALUE (
void rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber);
VALUE rb_fiberptr_self(struct rb_fiber_struct *fiber);
+unsigned int rb_fiberptr_blocking(struct rb_fiber_struct *fiber);
#endif /* INTERNAL_CONT_H */
diff --git a/internal/scheduler.h b/internal/scheduler.h
deleted file mode 100644
index 8314020..0000000
--- a/internal/scheduler.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef RUBY_SCHEDULER_H /*-*-C-*-vi:se ft=c:*/
-#define RUBY_SCHEDULER_H
-/**
- * @file
- * @author Ruby developers <ruby-core@ruby-lang.org>
- * @copyright This file is a part of the programming language Ruby.
- * Permission is hereby granted, to either redistribute and/or
- * modify this file, provided that the conditions mentioned in the
- * file COPYING are met. Consult the file for details.
- * @brief Internal header for Scheduler.
- */
-#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);
-
-VALUE rb_scheduler_kernel_sleep(VALUE scheduler, VALUE duration);
-VALUE rb_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv);
-
-int rb_scheduler_supports_process_wait(VALUE scheduler);
-VALUE rb_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags);
-
-VALUE rb_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout);
-VALUE rb_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber);
-
-VALUE rb_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout);
-VALUE rb_scheduler_io_wait_readable(VALUE scheduler, VALUE io);
-VALUE rb_scheduler_io_wait_writable(VALUE scheduler, VALUE io);
-
-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 056bf16..b4d477c 100644
--- a/io.c
+++ b/io.c
@@ -13,7 +13,7 @@
#include "ruby/internal/config.h"
-#include "internal/scheduler.h"
+#include "ruby/fiber/scheduler.h"
#ifdef _WIN32
# include "ruby/ruby.h"
@@ -1264,10 +1264,10 @@ io_fflush(rb_io_t *fptr)
VALUE
rb_io_wait(VALUE io, VALUE events, VALUE timeout)
{
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
- return rb_scheduler_io_wait(scheduler, io, events, timeout);
+ return rb_fiber_scheduler_io_wait(scheduler, io, events, timeout);
}
rb_io_t * fptr = NULL;
@@ -1306,10 +1306,10 @@ rb_io_from_fd(int fd)
int
rb_io_wait_readable(int f)
{
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
return RTEST(
- rb_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
+ rb_fiber_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
);
}
@@ -1337,10 +1337,10 @@ rb_io_wait_readable(int f)
int
rb_io_wait_writable(int f)
{
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
return RTEST(
- rb_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
+ rb_fiber_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
);
}
@@ -1377,11 +1377,11 @@ rb_io_wait_writable(int f)
int
rb_wait_for_single_fd(int fd, int events, struct timeval *timeout)
{
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
return RTEST(
- rb_scheduler_io_wait(scheduler, rb_io_from_fd(fd), RB_INT2NUM(events), rb_scheduler_timeout(timeout))
+ rb_fiber_scheduler_io_wait(scheduler, rb_io_from_fd(fd), RB_INT2NUM(events), rb_fiber_scheduler_make_timeout(timeout))
);
}
@@ -1538,15 +1538,17 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
if ((n = len) <= 0) return n;
- 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)
- );
+ VALUE scheduler = rb_fiber_scheduler_current();
+ if (scheduler != Qnil) {
+ VALUE result = rb_fiber_scheduler_io_write(scheduler, fptr->self, str, offset, len);
- if (length < 0) rb_sys_fail_path(fptr->pathv);
+ if (result != Qundef) {
+ ssize_t length = RB_NUM2SSIZE(result);
- return length;
+ if (length < 0) rb_sys_fail_path(fptr->pathv);
+
+ return length;
+ }
}
if (fptr->wbuf.ptr == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) {
@@ -2623,15 +2625,17 @@ bufread_call(VALUE arg)
static long
io_fread(VALUE str, long offset, long size, rb_io_t *fptr)
{
- 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)
- );
+ VALUE scheduler = rb_fiber_scheduler_current();
+ if (scheduler != Qnil) {
+ VALUE result = rb_fiber_scheduler_io_read(scheduler, fptr->self, str, offset, size);
- if (length < 0) rb_sys_fail_path(fptr->pathv);
+ if (result != Qundef) {
+ ssize_t length = RB_NUM2SSIZE(result);
- return length;
+ if (length < 0) rb_sys_fail_path(fptr->pathv);
+
+ return length;
+ }
}
long len;
@@ -11024,11 +11028,11 @@ struct wait_for_single_fd {
};
static void *
-rb_thread_scheduler_wait_for_single_fd(void * _args)
+rb_thread_fiber_scheduler_wait_for_single_fd(void * _args)
{
struct wait_for_single_fd *args = (struct wait_for_single_fd *)_args;
- args->result = rb_scheduler_io_wait(args->scheduler, rb_io_from_fd(args->fd), INT2NUM(args->events), Qnil);
+ args->result = rb_fiber_scheduler_io_wait(args->scheduler, rb_io_from_fd(args->fd), INT2NUM(args->events), Qnil);
return NULL;
}
@@ -11040,10 +11044,10 @@ STATIC_ASSERT(pollout_expected, POLLOUT == RB_WAITFD_OUT);
static int
nogvl_wait_for_single_fd(VALUE th, int fd, short events)
{
- VALUE scheduler = rb_thread_scheduler_current(th);
+ VALUE scheduler = rb_fiber_scheduler_current_for_thread(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);
+ rb_thread_call_with_gvl(rb_thread_fiber_scheduler_wait_for_single_fd, &args);
return RTEST(args.result);
}
@@ -11059,10 +11063,10 @@ nogvl_wait_for_single_fd(VALUE th, int fd, short events)
static int
nogvl_wait_for_single_fd(VALUE th, int fd, short events)
{
- VALUE scheduler = rb_thread_scheduler_current(th);
+ VALUE scheduler = rb_fiber_scheduler_current_for_thread(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);
+ rb_thread_call_with_gvl(rb_thread_fiber_scheduler_wait_for_single_fd, &args);
return RTEST(args.result);
}
diff --git a/process.c b/process.c
index 674f05d..0f29a6d 100644
--- a/process.c
+++ b/process.c
@@ -13,7 +13,7 @@
#include "ruby/internal/config.h"
-#include "internal/scheduler.h"
+#include "ruby/fiber/scheduler.h"
#include "coroutine/Stack.h"
#include <ctype.h>
@@ -1345,10 +1345,9 @@ rb_process_status_wait(rb_pid_t pid, int flags)
{
// We only enter the scheduler if we are "blocking":
if (!(flags & WNOHANG)) {
- VALUE scheduler = rb_scheduler_current();
- if (rb_scheduler_supports_process_wait(scheduler)) {
- return rb_scheduler_process_wait(scheduler, pid, flags);
- }
+ VALUE scheduler = rb_fiber_scheduler_current();
+ VALUE result = rb_fiber_scheduler_process_wait(scheduler, pid, flags);
+ if (result != Qundef) return result;
}
COROUTINE_STACK_LOCAL(struct waitpid_state, w);
@@ -5104,10 +5103,10 @@ static VALUE
rb_f_sleep(int argc, VALUE *argv, VALUE _)
{
time_t beg = time(0);
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
- rb_scheduler_kernel_sleepv(scheduler, argc, argv);
+ rb_fiber_scheduler_kernel_sleepv(scheduler, argc, argv);
}
else {
if (argc == 0) {
diff --git a/scheduler.c b/scheduler.c
index 88db433..4687231 100644
--- a/scheduler.c
+++ b/scheduler.c
@@ -9,7 +9,7 @@
**********************************************************************/
#include "vm_core.h"
-#include "internal/scheduler.h"
+#include "ruby/fiber/scheduler.h"
#include "ruby/io.h"
static ID id_close;
@@ -25,7 +25,7 @@ static ID id_io_write;
static ID id_io_wait;
void
-Init_Scheduler(void)
+Init_Fiber_Scheduler(void)
{
id_close = rb_intern_const("close");
@@ -41,7 +41,7 @@ Init_Scheduler(void)
}
VALUE
-rb_scheduler_get(void)
+rb_fiber_scheduler_get(void)
{
rb_thread_t *thread = GET_THREAD();
VM_ASSERT(thread);
@@ -50,14 +50,14 @@ rb_scheduler_get(void)
}
VALUE
-rb_scheduler_set(VALUE scheduler)
+rb_fiber_scheduler_set(VALUE scheduler)
{
rb_thread_t *thread = GET_THREAD();
VM_ASSERT(thread);
// We invoke Scheduler#close when setting it to something else, to ensure the previous scheduler runs to completion before changing the scheduler. That way, we do not need to consider interactions, e.g., of a Fiber from the previous scheduler with the new scheduler.
if (thread->scheduler != Qnil) {
- rb_scheduler_close(thread->scheduler);
+ rb_fiber_scheduler_close(thread->scheduler);
}
thread->scheduler = scheduler;
@@ -66,7 +66,7 @@ rb_scheduler_set(VALUE scheduler)
}
static VALUE
-rb_threadptr_scheduler_current(rb_thread_t *thread)
+rb_fiber_scheduler_current_for_threadptr(rb_thread_t *thread)
{
VM_ASSERT(thread);
@@ -78,18 +78,18 @@ rb_threadptr_scheduler_current(rb_thread_t *thread)
}
VALUE
-rb_scheduler_current(void)
+rb_fiber_scheduler_current(void)
{
- return rb_threadptr_scheduler_current(GET_THREAD());
+ return rb_fiber_scheduler_current_for_threadptr(GET_THREAD());
}
-VALUE rb_thread_scheduler_current(VALUE thread)
+VALUE rb_fiber_scheduler_current_for_thread(VALUE thread)
{
- return rb_threadptr_scheduler_current(rb_thread_ptr(thread));
+ return rb_fiber_scheduler_current_for_threadptr(rb_thread_ptr(thread));
}
VALUE
-rb_scheduler_close(VALUE scheduler)
+rb_fiber_scheduler_close(VALUE scheduler)
{
if (rb_respond_to(scheduler, id_close)) {
return rb_funcall(scheduler, id_close, 0);
@@ -99,7 +99,7 @@ rb_scheduler_close(VALUE scheduler)
}
VALUE
-rb_scheduler_timeout(struct timeval *timeout)
+rb_fiber_scheduler_make_timeout(struct timeval *timeout)
{
if (timeout) {
return rb_float_new((double)timeout->tv_sec + (0.000001f * timeout->tv_usec));
@@ -109,80 +109,74 @@ rb_scheduler_timeout(struct timeval *timeout)
}
VALUE
-rb_scheduler_kernel_sleep(VALUE scheduler, VALUE timeout)
+rb_fiber_scheduler_kernel_sleep(VALUE scheduler, VALUE timeout)
{
return rb_funcall(scheduler, id_kernel_sleep, 1, timeout);
}
VALUE
-rb_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv)
+rb_fiber_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv)
{
return rb_funcallv(scheduler, id_kernel_sleep, argc, argv);
}
-int
-rb_scheduler_supports_process_wait(VALUE scheduler)
-{
- return rb_respond_to(scheduler, id_process_wait);
-}
-
VALUE
-rb_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags)
+rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags)
{
- return rb_funcall(scheduler, id_process_wait, 2, PIDT2NUM(pid), RB_INT2NUM(flags));
+ VALUE arguments[] = {
+ PIDT2NUM(pid), RB_INT2NUM(flags)
+ };
+
+ return rb_check_funcall(scheduler, id_process_wait, 2, arguments);
}
VALUE
-rb_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout)
+rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout)
{
return rb_funcall(scheduler, id_block, 2, blocker, timeout);
}
VALUE
-rb_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
+rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
{
return rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
}
VALUE
-rb_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout)
+rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout)
{
return rb_funcall(scheduler, id_io_wait, 3, io, events, timeout);
}
VALUE
-rb_scheduler_io_wait_readable(VALUE scheduler, VALUE io)
+rb_fiber_scheduler_io_wait_readable(VALUE scheduler, VALUE io)
{
- return rb_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_READABLE), Qnil);
+ return rb_fiber_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_READABLE), Qnil);
}
VALUE
-rb_scheduler_io_wait_writable(VALUE scheduler, VALUE io)
-{
- return rb_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_WRITABLE), Qnil);
-}
-
-int
-rb_scheduler_supports_io_read(VALUE scheduler)
+rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io)
{
- return rb_respond_to(scheduler, id_io_read);
+ return rb_fiber_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_WRITABLE), Qnil);
}
VALUE
-rb_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
+rb_fiber_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 arguments[] = {
+ io, buffer, SIZET2NUM(offset), SIZET2NUM(length)
+ };
+
+ return rb_check_funcall(scheduler, id_io_read, 4, arguments);
}
VALUE
-rb_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
+rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
{
+ VALUE arguments[] = {
+ io, buffer, SIZET2NUM(offset), SIZET2NUM(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, SIZET2NUM(offset), SIZET2NUM(length));
+ return rb_check_funcall(scheduler, id_io_write, 4, arguments);
}
diff --git a/test/fiber/http.rb b/test/fiber/http.rb
index ad51ae3..53a4602 100644
--- a/test/fiber/http.rb
+++ b/test/fiber/http.rb
@@ -15,24 +15,25 @@ def fetch_topics(topics)
topics.each do |topic|
Fiber.new(blocking: Fiber.current.blocking?) do
uri = URI("https://www.google.com/search?q=#{topic}")
- responses[topic] = Net::HTTP.get(uri).scan(topic).size
+ response = Net::HTTP.get(uri)
+ responses[topic] = response.scan(topic).size
end.resume
end
- Thread.fiber_scheduler&.run
+ Fiber.scheduler&.run
return responses
end
def sweep(repeats: 3, **options)
times = (1..8).map do |i|
- $stderr.puts "Measuring #{i} topic(s)..."
+ $stderr.puts "Measuring #{i} topic(s) #{options.inspect}..."
topics = TOPICS[0...i]
Thread.new do
Benchmark.realtime do
scheduler = Scheduler.new
- Fiber.set_scheduler scheduler
+ Fiber.set_scheduler(scheduler)
repeats.times do
Fiber.new(**options) do
@@ -49,5 +50,5 @@ def sweep(repeats: 3, **options)
puts JSON.dump(times.map{|value| value.round(3)})
end
-sweep(blocking: true)
+# sweep(blocking: true)
sweep(blocking: false)
diff --git a/test/fiber/scheduler.rb b/test/fiber/scheduler.rb
index b3c3eaf..f2fb304 100644
--- a/test/fiber/scheduler.rb
+++ b/test/fiber/scheduler.rb
@@ -47,6 +47,8 @@ class Scheduler
end
def run
+ # $stderr.puts [__method__, Fiber.current].inspect
+
while @readable.any? or @writable.any? or @waiting.any? or @blocking.positive?
# Can only handle file descriptors up to 1024...
readable, writable = IO.select(@readable.keys + [@urgent.first], @writable.keys, [], next_timeout)
@@ -54,9 +56,11 @@ class Scheduler
# puts "readable: #{readable}" if readable&.any?
# puts "writable: #{writable}" if writable&.any?
+ selected = {}
+
readable&.each do |io|
if fiber = @readable.delete(io)
- fiber.resume
+ selected[fiber] = IO::READABLE
elsif io == @urgent.first
@urgent.first.read_nonblock(1024)
end
@@ -64,10 +68,14 @@ class Scheduler
writable&.each do |io|
if fiber = @writable.delete(io)
- fiber.resume
+ selected[fiber] |= IO::WRITABLE
end
end
+ selected.each do |fiber, events|
+ fiber.resume(events)
+ end
+
if @waiting.any?
time = current_time
waiting, @waiting = @waiting, {}
@@ -96,6 +104,8 @@ class Scheduler
end
def close
+ # $stderr.puts [__method__, Fiber.current].inspect
+
raise "Scheduler already closed!" if @closed
self.run
@@ -118,6 +128,8 @@ class Scheduler
end
def process_wait(pid, flags)
+ # $stderr.puts [__method__, pid, flags, Fiber.current].inspect
+
# This is a very simple way to implement a non-blocking wait:
Thread.new do
Process::Status.wait(pid, flags)
@@ -125,6 +137,8 @@ class Scheduler
end
def io_wait(io, events, duration)
+ # $stderr.puts [__method__, io, events, duration, Fiber.current].inspect
+
unless (events & IO::READABLE).zero?
@readable[io] = Fiber.current
end
@@ -134,12 +148,12 @@ class Scheduler
end
Fiber.yield
-
- return true
end
# Used for Kernel#sleep and Mutex#sleep
def kernel_sleep(duration = nil)
+ # $stderr.puts [__method__, duration, Fiber.current].inspect
+
self.block(:sleep, duration)
return true
@@ -171,6 +185,8 @@ class Scheduler
# This might be called from another thread.
def unblock(blocker, fiber)
# $stderr.puts [__method__, blocker, fiber].inspect
+ # $stderr.puts blocker.backtrace.inspect
+ # $stderr.puts fiber.backtrace.inspect
@lock.synchronize do
@ready << fiber
diff --git a/test/fiber/test_thread.rb b/test/fiber/test_thread.rb
new file mode 100644
index 0000000..5fc80f0
--- /dev/null
+++ b/test/fiber/test_thread.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+require "test/unit"
+require_relative 'scheduler'
+
+class TestFiberThread < Test::Unit::TestCase
+ def test_thread_join
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ result = nil
+ Fiber.schedule do
+ result = Thread.new{:done}.value
+ end
+
+ scheduler.run
+ result
+ end
+
+ assert_equal :done, thread.value
+ end
+
+ def test_thread_join_blocking
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ result = nil
+ Fiber.schedule do
+ Fiber.new(blocking: true) do
+ # This can deadlock if the blocking state is not taken into account:
+ Thread.new do
+ sleep(0)
+ result = :done
+ end.join
+ end.resume
+ end
+
+ scheduler.run
+ result
+ end
+
+ assert_equal :done, thread.value
+ end
+end
diff --git a/thread.c b/thread.c
index e368948..1e35ad4 100644
--- a/thread.c
+++ b/thread.c
@@ -81,7 +81,7 @@
#include "internal/io.h"
#include "internal/object.h"
#include "internal/proc.h"
-#include "internal/scheduler.h"
+#include "ruby/fiber/scheduler.h"
#include "internal/signal.h"
#include "internal/thread.h"
#include "internal/time.h"
@@ -551,8 +551,8 @@ rb_threadptr_join_list_wakeup(rb_thread_t *thread)
while (join_list) {
rb_thread_t *target_thread = join_list->thread;
- if (target_thread->scheduler != Qnil) {
- rb_scheduler_unblock(target_thread->scheduler, target_thread->self, rb_fiberptr_self(join_list->fiber));
+ if (target_thread->scheduler != Qnil && rb_fiberptr_blocking(join_list->fiber) == 0) {
+ rb_fiber_scheduler_unblock(target_thread->scheduler, target_thread->self, rb_fiberptr_self(join_list->fiber));
} else {
rb_threadptr_interrupt(target_thread);
@@ -772,7 +772,7 @@ thread_do_start(rb_thread_t *th)
rb_bug("unreachable");
}
- rb_scheduler_set(Qnil);
+ rb_fiber_scheduler_set(Qnil);
}
void rb_ec_clear_current_thread_trace_func(const rb_execution_context_t *ec);
@@ -1178,10 +1178,10 @@ thread_join_sleep(VALUE arg)
}
while (target_th->status != THREAD_KILLED) {
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
- rb_scheduler_block(scheduler, target_th->self, p->timeout);
+ rb_fiber_scheduler_block(scheduler, target_th->self, p->timeout);
} else if (!limit) {
th->status = THREAD_STOPPED_FOREVER;
rb_ractor_sleeper_threads_inc(th->ractor);
@@ -1525,9 +1525,9 @@ rb_thread_sleep_interruptible(void)
static void
rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker)
{
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
- rb_scheduler_block(scheduler, blocker, Qnil);
+ rb_fiber_scheduler_block(scheduler, blocker, Qnil);
} else {
thread_debug("rb_thread_sleep_deadly_allow_spurious_wakeup\n");
sleep_forever(GET_THREAD(), SLEEP_DEADLOCKABLE);
diff --git a/thread_sync.c b/thread_sync.c
index 8295b3d..9932abd 100644
--- a/thread_sync.c
+++ b/thread_sync.c
@@ -32,8 +32,8 @@ sync_wakeup(struct list_head *head, long max)
if (cur->th->status != THREAD_KILLED) {
- if (cur->th->scheduler != Qnil) {
- rb_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
+ if (cur->th->scheduler != Qnil && rb_fiberptr_blocking(cur->fiber) == 0) {
+ rb_fiber_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
} else {
rb_threadptr_interrupt(cur->th);
cur->th->status = THREAD_RUNNABLE;
@@ -267,8 +267,8 @@ mutex_owned_p(rb_fiber_t *fiber, rb_mutex_t *mutex)
}
}
-static VALUE call_rb_scheduler_block(VALUE mutex) {
- return rb_scheduler_block(rb_scheduler_current(), mutex, Qnil);
+static VALUE call_rb_fiber_scheduler_block(VALUE mutex) {
+ return rb_fiber_scheduler_block(rb_fiber_scheduler_current(), mutex, Qnil);
}
static VALUE
@@ -302,7 +302,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
}
while (mutex->fiber != fiber) {
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
COROUTINE_STACK_LOCAL(struct sync_waiter, w);
w->self = self;
@@ -311,7 +311,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
list_add_tail(&mutex->waitq, &w->node);
- rb_ensure(call_rb_scheduler_block, self, delete_from_waitq, (VALUE)w);
+ rb_ensure(call_rb_fiber_scheduler_block, self, delete_from_waitq, (VALUE)w);
if (!mutex->fiber) {
mutex->fiber = fiber;
@@ -437,8 +437,8 @@ rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t *th, rb_fiber_t *fiber)
list_for_each_safe(&mutex->waitq, cur, next, node) {
list_del_init(&cur->node);
- if (cur->th->scheduler != Qnil) {
- rb_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
+ if (cur->th->scheduler != Qnil && rb_fiberptr_blocking(cur->fiber) == 0) {
+ rb_fiber_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
goto found;
} else {
switch (cur->th->status) {
@@ -545,9 +545,9 @@ rb_mutex_sleep(VALUE self, VALUE timeout)
rb_mutex_unlock(self);
time_t beg = time(0);
- VALUE scheduler = rb_scheduler_current();
+ VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
- rb_scheduler_kernel_sleep(scheduler, timeout);
+ rb_fiber_scheduler_kernel_sleep(scheduler, timeout);
mutex_lock_uninterruptible(self);
} else {
if (NIL_P(timeout)) {