зеркало из https://github.com/github/ruby.git
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.
This commit is contained in:
Родитель
3c593f28ed
Коммит
5f69a7f604
20
common.mk
20
common.mk
|
@ -3196,13 +3196,13 @@ cont.$(OBJEXT): $(CCAN_DIR)/list/list.h
|
||||||
cont.$(OBJEXT): $(CCAN_DIR)/str/str.h
|
cont.$(OBJEXT): $(CCAN_DIR)/str/str.h
|
||||||
cont.$(OBJEXT): $(hdrdir)/ruby.h
|
cont.$(OBJEXT): $(hdrdir)/ruby.h
|
||||||
cont.$(OBJEXT): $(hdrdir)/ruby/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/array.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/cont.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/cont.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/proc.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/serial.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/vm.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)}debug_counter.h
|
||||||
cont.$(OBJEXT): {$(VPATH)}defines.h
|
cont.$(OBJEXT): {$(VPATH)}defines.h
|
||||||
cont.$(OBJEXT): {$(VPATH)}eval_intern.h
|
cont.$(OBJEXT): {$(VPATH)}eval_intern.h
|
||||||
|
cont.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
|
||||||
cont.$(OBJEXT): {$(VPATH)}gc.h
|
cont.$(OBJEXT): {$(VPATH)}gc.h
|
||||||
cont.$(OBJEXT): {$(VPATH)}id.h
|
cont.$(OBJEXT): {$(VPATH)}id.h
|
||||||
cont.$(OBJEXT): {$(VPATH)}id_table.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): $(CCAN_DIR)/str/str.h
|
||||||
eval.$(OBJEXT): $(hdrdir)/ruby.h
|
eval.$(OBJEXT): $(hdrdir)/ruby.h
|
||||||
eval.$(OBJEXT): $(hdrdir)/ruby/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/array.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/class.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/class.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/compilers.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/inits.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/io.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/object.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/serial.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/string.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_error.c
|
||||||
eval.$(OBJEXT): {$(VPATH)}eval_intern.h
|
eval.$(OBJEXT): {$(VPATH)}eval_intern.h
|
||||||
eval.$(OBJEXT): {$(VPATH)}eval_jump.c
|
eval.$(OBJEXT): {$(VPATH)}eval_jump.c
|
||||||
|
eval.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
|
||||||
eval.$(OBJEXT): {$(VPATH)}gc.h
|
eval.$(OBJEXT): {$(VPATH)}gc.h
|
||||||
eval.$(OBJEXT): {$(VPATH)}id.h
|
eval.$(OBJEXT): {$(VPATH)}id.h
|
||||||
eval.$(OBJEXT): {$(VPATH)}id_table.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): $(CCAN_DIR)/str/str.h
|
||||||
io.$(OBJEXT): $(hdrdir)/ruby.h
|
io.$(OBJEXT): $(hdrdir)/ruby.h
|
||||||
io.$(OBJEXT): $(hdrdir)/ruby/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/array.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/bignum.h
|
io.$(OBJEXT): $(top_srcdir)/internal/bignum.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/bits.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/numeric.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/object.h
|
io.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/process.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/serial.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
io.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/string.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)}dln.h
|
||||||
io.$(OBJEXT): {$(VPATH)}encindex.h
|
io.$(OBJEXT): {$(VPATH)}encindex.h
|
||||||
io.$(OBJEXT): {$(VPATH)}encoding.h
|
io.$(OBJEXT): {$(VPATH)}encoding.h
|
||||||
|
io.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
|
||||||
io.$(OBJEXT): {$(VPATH)}id.h
|
io.$(OBJEXT): {$(VPATH)}id.h
|
||||||
io.$(OBJEXT): {$(VPATH)}id_table.h
|
io.$(OBJEXT): {$(VPATH)}id_table.h
|
||||||
io.$(OBJEXT): {$(VPATH)}intern.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): $(CCAN_DIR)/str/str.h
|
||||||
process.$(OBJEXT): $(hdrdir)/ruby.h
|
process.$(OBJEXT): $(hdrdir)/ruby.h
|
||||||
process.$(OBJEXT): $(hdrdir)/ruby/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/array.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/bits.h
|
process.$(OBJEXT): $(top_srcdir)/internal/bits.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/class.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/imemo.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/object.h
|
process.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/process.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/serial.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
process.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/string.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)}defines.h
|
||||||
process.$(OBJEXT): {$(VPATH)}dln.h
|
process.$(OBJEXT): {$(VPATH)}dln.h
|
||||||
process.$(OBJEXT): {$(VPATH)}encoding.h
|
process.$(OBJEXT): {$(VPATH)}encoding.h
|
||||||
|
process.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
|
||||||
process.$(OBJEXT): {$(VPATH)}hrtime.h
|
process.$(OBJEXT): {$(VPATH)}hrtime.h
|
||||||
process.$(OBJEXT): {$(VPATH)}id.h
|
process.$(OBJEXT): {$(VPATH)}id.h
|
||||||
process.$(OBJEXT): {$(VPATH)}id_table.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)/list/list.h
|
||||||
scheduler.$(OBJEXT): $(CCAN_DIR)/str/str.h
|
scheduler.$(OBJEXT): $(CCAN_DIR)/str/str.h
|
||||||
scheduler.$(OBJEXT): $(hdrdir)/ruby/ruby.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/array.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.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/serial.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/vm.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)}config.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}defines.h
|
scheduler.$(OBJEXT): {$(VPATH)}defines.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}encoding.h
|
scheduler.$(OBJEXT): {$(VPATH)}encoding.h
|
||||||
|
scheduler.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}id.h
|
scheduler.$(OBJEXT): {$(VPATH)}id.h
|
||||||
|
scheduler.$(OBJEXT): {$(VPATH)}include/ruby/fiber/scheduler.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}intern.h
|
scheduler.$(OBJEXT): {$(VPATH)}intern.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}internal.h
|
scheduler.$(OBJEXT): {$(VPATH)}internal.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}internal/anyargs.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/newobj.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}internal/rgengc.h
|
scheduler.$(OBJEXT): {$(VPATH)}internal/rgengc.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}internal/scan_args.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/special_consts.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}internal/static_assert.h
|
scheduler.$(OBJEXT): {$(VPATH)}internal/static_assert.h
|
||||||
scheduler.$(OBJEXT): {$(VPATH)}internal/stdalign.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): $(CCAN_DIR)/str/str.h
|
||||||
thread.$(OBJEXT): $(hdrdir)/ruby.h
|
thread.$(OBJEXT): $(hdrdir)/ruby.h
|
||||||
thread.$(OBJEXT): $(hdrdir)/ruby/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/array.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/bits.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/bits.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/class.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/io.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/object.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/proc.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/serial.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/signal.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/signal.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/static_assert.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)}defines.h
|
||||||
thread.$(OBJEXT): {$(VPATH)}encoding.h
|
thread.$(OBJEXT): {$(VPATH)}encoding.h
|
||||||
thread.$(OBJEXT): {$(VPATH)}eval_intern.h
|
thread.$(OBJEXT): {$(VPATH)}eval_intern.h
|
||||||
|
thread.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
|
||||||
thread.$(OBJEXT): {$(VPATH)}gc.h
|
thread.$(OBJEXT): {$(VPATH)}gc.h
|
||||||
thread.$(OBJEXT): {$(VPATH)}hrtime.h
|
thread.$(OBJEXT): {$(VPATH)}hrtime.h
|
||||||
thread.$(OBJEXT): {$(VPATH)}id.h
|
thread.$(OBJEXT): {$(VPATH)}id.h
|
||||||
|
|
15
cont.c
15
cont.c
|
@ -24,7 +24,7 @@
|
||||||
#include "internal/cont.h"
|
#include "internal/cont.h"
|
||||||
#include "internal/proc.h"
|
#include "internal/proc.h"
|
||||||
#include "internal/warnings.h"
|
#include "internal/warnings.h"
|
||||||
#include "internal/scheduler.h"
|
#include "ruby/fiber/scheduler.h"
|
||||||
#include "mjit.h"
|
#include "mjit.h"
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
#include "id_table.h"
|
#include "id_table.h"
|
||||||
|
@ -1156,6 +1156,11 @@ VALUE rb_fiberptr_self(struct rb_fiber_struct *fiber)
|
||||||
return fiber->cont.self;
|
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.
|
// This is used for root_fiber because other fibers call cont_init_mjit_cont through cont_new.
|
||||||
void
|
void
|
||||||
rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber)
|
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
|
static VALUE
|
||||||
rb_fiber_scheduler(VALUE klass)
|
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
|
static VALUE
|
||||||
rb_fiber_set_scheduler(VALUE klass, VALUE scheduler)
|
rb_fiber_set_scheduler(VALUE klass, VALUE scheduler)
|
||||||
{
|
{
|
||||||
// if (rb_scheduler_get() != Qnil) {
|
return rb_fiber_scheduler_set(scheduler);
|
||||||
// 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);
|
static void rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt);
|
||||||
|
|
8
eval.c
8
eval.c
|
@ -29,7 +29,7 @@
|
||||||
#include "internal/object.h"
|
#include "internal/object.h"
|
||||||
#include "internal/thread.h"
|
#include "internal/thread.h"
|
||||||
#include "internal/variable.h"
|
#include "internal/variable.h"
|
||||||
#include "internal/scheduler.h"
|
#include "ruby/fiber/scheduler.h"
|
||||||
#include "iseq.h"
|
#include "iseq.h"
|
||||||
#include "mjit.h"
|
#include "mjit.h"
|
||||||
#include "probes.h"
|
#include "probes.h"
|
||||||
|
@ -147,13 +147,13 @@ ruby_options(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
enum ruby_tag_type state;
|
||||||
|
|
||||||
EC_PUSH_TAG(ec);
|
EC_PUSH_TAG(ec);
|
||||||
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
|
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
|
||||||
rb_scheduler_set(Qnil);
|
rb_fiber_scheduler_set(Qnil);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
state = error_handle(ec, state);
|
state = error_handle(ec, state);
|
||||||
|
@ -165,7 +165,7 @@ static void
|
||||||
rb_ec_teardown(rb_execution_context_t *ec)
|
rb_ec_teardown(rb_execution_context_t *ec)
|
||||||
{
|
{
|
||||||
// If the user code defined a scheduler for the top level thread, run it:
|
// 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);
|
EC_PUSH_TAG(ec);
|
||||||
if (EC_EXEC_TAG() == TAG_NONE) {
|
if (EC_EXEC_TAG() == TAG_NONE) {
|
||||||
|
|
|
@ -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;
|
static ID id_gets, id_chomp_bang;
|
||||||
#endif
|
#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);
|
extern VALUE rb_scheduler_timeout(struct timeval *timeout);
|
||||||
|
# define rb_fiber_scheduler_timeout rb_scheduler_timeout
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define sys_fail_fptr(fptr) rb_sys_fail_str((fptr)->pathv)
|
#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_sec = optp->vtime / 10;
|
||||||
tv.tv_usec = (optp->vtime % 10) * 100000;
|
tv.tv_usec = (optp->vtime % 10) * 100000;
|
||||||
# ifdef HAVE_RB_IO_WAIT
|
# ifdef HAVE_RB_IO_WAIT
|
||||||
timeout = rb_scheduler_timeout(&tv);
|
timeout = rb_fiber_scheduler_make_timeout(&tv);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
switch (optp->vmin) {
|
switch (optp->vmin) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ when true
|
||||||
# rb_funcallv: 2.1.0
|
# rb_funcallv: 2.1.0
|
||||||
# RARRAY_CONST_PTR: 2.1.0
|
# RARRAY_CONST_PTR: 2.1.0
|
||||||
# rb_sym2str: 2.2.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")
|
have_func("rb_io_wait")
|
||||||
end
|
end
|
||||||
$defs << "-D""ENABLE_IO_GETPASS=1"
|
$defs << "-D""ENABLE_IO_GETPASS=1"
|
||||||
|
|
185
ext/psych/depend
185
ext/psych/depend
|
@ -1,9 +1,48 @@
|
||||||
$(OBJS): $(YAML_H)
|
$(OBJS): $(YAML_H)
|
||||||
|
|
||||||
# AUTOGENERATED DEPENDENCIES START
|
# 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: $(RUBY_EXTCONF_H)
|
||||||
psych.o: $(arch_hdrdir)/ruby/config.h
|
psych.o: $(arch_hdrdir)/ruby/config.h
|
||||||
psych.o: $(hdrdir)/ruby.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/anyargs.h
|
||||||
psych.o: $(hdrdir)/ruby/internal/arithmetic.h
|
psych.o: $(hdrdir)/ruby/internal/arithmetic.h
|
||||||
psych.o: $(hdrdir)/ruby/internal/arithmetic/char.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/variable.h
|
||||||
psych.o: $(hdrdir)/ruby/internal/warning_push.h
|
psych.o: $(hdrdir)/ruby/internal/warning_push.h
|
||||||
psych.o: $(hdrdir)/ruby/internal/xmalloc.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/missing.h
|
||||||
psych.o: $(hdrdir)/ruby/onigmo.h
|
psych.o: $(hdrdir)/ruby/onigmo.h
|
||||||
psych.o: $(hdrdir)/ruby/oniguruma.h
|
psych.o: $(hdrdir)/ruby/oniguruma.h
|
||||||
|
@ -170,9 +195,24 @@ psych.o: psych_emitter.h
|
||||||
psych.o: psych_parser.h
|
psych.o: psych_parser.h
|
||||||
psych.o: psych_to_ruby.h
|
psych.o: psych_to_ruby.h
|
||||||
psych.o: psych_yaml_tree.h
|
psych.o: psych_yaml_tree.h
|
||||||
|
psych.o: yaml/yaml.h
|
||||||
psych_emitter.o: $(RUBY_EXTCONF_H)
|
psych_emitter.o: $(RUBY_EXTCONF_H)
|
||||||
psych_emitter.o: $(arch_hdrdir)/ruby/config.h
|
psych_emitter.o: $(arch_hdrdir)/ruby/config.h
|
||||||
psych_emitter.o: $(hdrdir)/ruby.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/anyargs.h
|
||||||
psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic.h
|
psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic.h
|
||||||
psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/char.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/variable.h
|
||||||
psych_emitter.o: $(hdrdir)/ruby/internal/warning_push.h
|
psych_emitter.o: $(hdrdir)/ruby/internal/warning_push.h
|
||||||
psych_emitter.o: $(hdrdir)/ruby/internal/xmalloc.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/missing.h
|
||||||
psych_emitter.o: $(hdrdir)/ruby/onigmo.h
|
psych_emitter.o: $(hdrdir)/ruby/onigmo.h
|
||||||
psych_emitter.o: $(hdrdir)/ruby/oniguruma.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_parser.h
|
||||||
psych_emitter.o: psych_to_ruby.h
|
psych_emitter.o: psych_to_ruby.h
|
||||||
psych_emitter.o: psych_yaml_tree.h
|
psych_emitter.o: psych_yaml_tree.h
|
||||||
|
psych_emitter.o: yaml/yaml.h
|
||||||
psych_parser.o: $(RUBY_EXTCONF_H)
|
psych_parser.o: $(RUBY_EXTCONF_H)
|
||||||
psych_parser.o: $(arch_hdrdir)/ruby/config.h
|
psych_parser.o: $(arch_hdrdir)/ruby/config.h
|
||||||
psych_parser.o: $(hdrdir)/ruby.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/anyargs.h
|
||||||
psych_parser.o: $(hdrdir)/ruby/internal/arithmetic.h
|
psych_parser.o: $(hdrdir)/ruby/internal/arithmetic.h
|
||||||
psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/char.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/variable.h
|
||||||
psych_parser.o: $(hdrdir)/ruby/internal/warning_push.h
|
psych_parser.o: $(hdrdir)/ruby/internal/warning_push.h
|
||||||
psych_parser.o: $(hdrdir)/ruby/internal/xmalloc.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/missing.h
|
||||||
psych_parser.o: $(hdrdir)/ruby/onigmo.h
|
psych_parser.o: $(hdrdir)/ruby/onigmo.h
|
||||||
psych_parser.o: $(hdrdir)/ruby/oniguruma.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_parser.h
|
||||||
psych_parser.o: psych_to_ruby.h
|
psych_parser.o: psych_to_ruby.h
|
||||||
psych_parser.o: psych_yaml_tree.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: $(RUBY_EXTCONF_H)
|
||||||
psych_to_ruby.o: $(arch_hdrdir)/ruby/config.h
|
psych_to_ruby.o: $(arch_hdrdir)/ruby/config.h
|
||||||
psych_to_ruby.o: $(hdrdir)/ruby.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/anyargs.h
|
||||||
psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic.h
|
psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic.h
|
||||||
psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/char.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/variable.h
|
||||||
psych_to_ruby.o: $(hdrdir)/ruby/internal/warning_push.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/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/missing.h
|
||||||
psych_to_ruby.o: $(hdrdir)/ruby/onigmo.h
|
psych_to_ruby.o: $(hdrdir)/ruby/onigmo.h
|
||||||
psych_to_ruby.o: $(hdrdir)/ruby/oniguruma.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.c
|
||||||
psych_to_ruby.o: psych_to_ruby.h
|
psych_to_ruby.o: psych_to_ruby.h
|
||||||
psych_to_ruby.o: psych_yaml_tree.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: $(RUBY_EXTCONF_H)
|
||||||
psych_yaml_tree.o: $(arch_hdrdir)/ruby/config.h
|
psych_yaml_tree.o: $(arch_hdrdir)/ruby/config.h
|
||||||
psych_yaml_tree.o: $(hdrdir)/ruby.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/anyargs.h
|
||||||
psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic.h
|
psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic.h
|
||||||
psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/char.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/variable.h
|
||||||
psych_yaml_tree.o: $(hdrdir)/ruby/internal/warning_push.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/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/missing.h
|
||||||
psych_yaml_tree.o: $(hdrdir)/ruby/onigmo.h
|
psych_yaml_tree.o: $(hdrdir)/ruby/onigmo.h
|
||||||
psych_yaml_tree.o: $(hdrdir)/ruby/oniguruma.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_to_ruby.h
|
||||||
psych_yaml_tree.o: psych_yaml_tree.c
|
psych_yaml_tree.o: psych_yaml_tree.c
|
||||||
psych_yaml_tree.o: psych_yaml_tree.h
|
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
|
# AUTOGENERATED DEPENDENCIES END
|
||||||
|
|
|
@ -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 */
|
2
inits.c
2
inits.c
|
@ -65,7 +65,7 @@ rb_call_inits(void)
|
||||||
CALL(VM);
|
CALL(VM);
|
||||||
CALL(ISeq);
|
CALL(ISeq);
|
||||||
CALL(Thread);
|
CALL(Thread);
|
||||||
CALL(Scheduler);
|
CALL(Fiber_Scheduler);
|
||||||
CALL(process);
|
CALL(process);
|
||||||
CALL(Cont);
|
CALL(Cont);
|
||||||
CALL(Rational);
|
CALL(Rational);
|
||||||
|
|
|
@ -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);
|
void rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber);
|
||||||
|
|
||||||
VALUE rb_fiberptr_self(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 */
|
#endif /* INTERNAL_CONT_H */
|
||||||
|
|
|
@ -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 */
|
|
54
io.c
54
io.c
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include "ruby/internal/config.h"
|
#include "ruby/internal/config.h"
|
||||||
|
|
||||||
#include "internal/scheduler.h"
|
#include "ruby/fiber/scheduler.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include "ruby/ruby.h"
|
# include "ruby/ruby.h"
|
||||||
|
@ -1264,10 +1264,10 @@ io_fflush(rb_io_t *fptr)
|
||||||
VALUE
|
VALUE
|
||||||
rb_io_wait(VALUE io, VALUE events, VALUE timeout)
|
rb_io_wait(VALUE io, VALUE events, VALUE timeout)
|
||||||
{
|
{
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
|
|
||||||
if (scheduler != Qnil) {
|
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;
|
rb_io_t * fptr = NULL;
|
||||||
|
@ -1306,10 +1306,10 @@ rb_io_from_fd(int fd)
|
||||||
int
|
int
|
||||||
rb_io_wait_readable(int f)
|
rb_io_wait_readable(int f)
|
||||||
{
|
{
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
if (scheduler != Qnil) {
|
if (scheduler != Qnil) {
|
||||||
return RTEST(
|
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
|
int
|
||||||
rb_io_wait_writable(int f)
|
rb_io_wait_writable(int f)
|
||||||
{
|
{
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
if (scheduler != Qnil) {
|
if (scheduler != Qnil) {
|
||||||
return RTEST(
|
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
|
int
|
||||||
rb_wait_for_single_fd(int fd, int events, struct timeval *timeout)
|
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) {
|
if (scheduler != Qnil) {
|
||||||
return RTEST(
|
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,16 +1538,18 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
|
||||||
|
|
||||||
if ((n = len) <= 0) return n;
|
if ((n = len) <= 0) return n;
|
||||||
|
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
if (scheduler != Qnil && rb_scheduler_supports_io_write(scheduler)) {
|
if (scheduler != Qnil) {
|
||||||
ssize_t length = RB_NUM2SSIZE(
|
VALUE result = rb_fiber_scheduler_io_write(scheduler, fptr->self, str, offset, len);
|
||||||
rb_scheduler_io_write(scheduler, fptr->self, str, offset, len)
|
|
||||||
);
|
if (result != Qundef) {
|
||||||
|
ssize_t length = RB_NUM2SSIZE(result);
|
||||||
|
|
||||||
if (length < 0) rb_sys_fail_path(fptr->pathv);
|
if (length < 0) rb_sys_fail_path(fptr->pathv);
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fptr->wbuf.ptr == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) {
|
if (fptr->wbuf.ptr == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) {
|
||||||
fptr->wbuf.off = 0;
|
fptr->wbuf.off = 0;
|
||||||
|
@ -2623,16 +2625,18 @@ bufread_call(VALUE arg)
|
||||||
static long
|
static long
|
||||||
io_fread(VALUE str, long offset, long size, rb_io_t *fptr)
|
io_fread(VALUE str, long offset, long size, rb_io_t *fptr)
|
||||||
{
|
{
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
if (scheduler != Qnil && rb_scheduler_supports_io_read(scheduler)) {
|
if (scheduler != Qnil) {
|
||||||
ssize_t length = RB_NUM2SSIZE(
|
VALUE result = rb_fiber_scheduler_io_read(scheduler, fptr->self, str, offset, size);
|
||||||
rb_scheduler_io_read(scheduler, fptr->self, str, offset, size)
|
|
||||||
);
|
if (result != Qundef) {
|
||||||
|
ssize_t length = RB_NUM2SSIZE(result);
|
||||||
|
|
||||||
if (length < 0) rb_sys_fail_path(fptr->pathv);
|
if (length < 0) rb_sys_fail_path(fptr->pathv);
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long len;
|
long len;
|
||||||
struct bufread_arg arg;
|
struct bufread_arg arg;
|
||||||
|
@ -11024,11 +11028,11 @@ struct wait_for_single_fd {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *
|
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;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -11040,10 +11044,10 @@ STATIC_ASSERT(pollout_expected, POLLOUT == RB_WAITFD_OUT);
|
||||||
static int
|
static int
|
||||||
nogvl_wait_for_single_fd(VALUE th, int fd, short events)
|
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) {
|
if (scheduler != Qnil) {
|
||||||
struct wait_for_single_fd args = {.scheduler = scheduler, .fd = fd, .events = events};
|
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);
|
return RTEST(args.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11059,10 +11063,10 @@ nogvl_wait_for_single_fd(VALUE th, int fd, short events)
|
||||||
static int
|
static int
|
||||||
nogvl_wait_for_single_fd(VALUE th, int fd, short events)
|
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) {
|
if (scheduler != Qnil) {
|
||||||
struct wait_for_single_fd args = {.scheduler = scheduler, .fd = fd, .events = events};
|
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);
|
return RTEST(args.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
process.c
13
process.c
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include "ruby/internal/config.h"
|
#include "ruby/internal/config.h"
|
||||||
|
|
||||||
#include "internal/scheduler.h"
|
#include "ruby/fiber/scheduler.h"
|
||||||
#include "coroutine/Stack.h"
|
#include "coroutine/Stack.h"
|
||||||
|
|
||||||
#include <ctype.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":
|
// We only enter the scheduler if we are "blocking":
|
||||||
if (!(flags & WNOHANG)) {
|
if (!(flags & WNOHANG)) {
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
if (rb_scheduler_supports_process_wait(scheduler)) {
|
VALUE result = rb_fiber_scheduler_process_wait(scheduler, pid, flags);
|
||||||
return rb_scheduler_process_wait(scheduler, pid, flags);
|
if (result != Qundef) return result;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COROUTINE_STACK_LOCAL(struct waitpid_state, w);
|
COROUTINE_STACK_LOCAL(struct waitpid_state, w);
|
||||||
|
@ -5104,10 +5103,10 @@ static VALUE
|
||||||
rb_f_sleep(int argc, VALUE *argv, VALUE _)
|
rb_f_sleep(int argc, VALUE *argv, VALUE _)
|
||||||
{
|
{
|
||||||
time_t beg = time(0);
|
time_t beg = time(0);
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
|
|
||||||
if (scheduler != Qnil) {
|
if (scheduler != Qnil) {
|
||||||
rb_scheduler_kernel_sleepv(scheduler, argc, argv);
|
rb_fiber_scheduler_kernel_sleepv(scheduler, argc, argv);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
|
|
84
scheduler.c
84
scheduler.c
|
@ -9,7 +9,7 @@
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
#include "internal/scheduler.h"
|
#include "ruby/fiber/scheduler.h"
|
||||||
#include "ruby/io.h"
|
#include "ruby/io.h"
|
||||||
|
|
||||||
static ID id_close;
|
static ID id_close;
|
||||||
|
@ -25,7 +25,7 @@ static ID id_io_write;
|
||||||
static ID id_io_wait;
|
static ID id_io_wait;
|
||||||
|
|
||||||
void
|
void
|
||||||
Init_Scheduler(void)
|
Init_Fiber_Scheduler(void)
|
||||||
{
|
{
|
||||||
id_close = rb_intern_const("close");
|
id_close = rb_intern_const("close");
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ Init_Scheduler(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_scheduler_get(void)
|
rb_fiber_scheduler_get(void)
|
||||||
{
|
{
|
||||||
rb_thread_t *thread = GET_THREAD();
|
rb_thread_t *thread = GET_THREAD();
|
||||||
VM_ASSERT(thread);
|
VM_ASSERT(thread);
|
||||||
|
@ -50,14 +50,14 @@ rb_scheduler_get(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_scheduler_set(VALUE scheduler)
|
rb_fiber_scheduler_set(VALUE scheduler)
|
||||||
{
|
{
|
||||||
rb_thread_t *thread = GET_THREAD();
|
rb_thread_t *thread = GET_THREAD();
|
||||||
VM_ASSERT(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.
|
// 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) {
|
if (thread->scheduler != Qnil) {
|
||||||
rb_scheduler_close(thread->scheduler);
|
rb_fiber_scheduler_close(thread->scheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->scheduler = scheduler;
|
thread->scheduler = scheduler;
|
||||||
|
@ -66,7 +66,7 @@ rb_scheduler_set(VALUE scheduler)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_threadptr_scheduler_current(rb_thread_t *thread)
|
rb_fiber_scheduler_current_for_threadptr(rb_thread_t *thread)
|
||||||
{
|
{
|
||||||
VM_ASSERT(thread);
|
VM_ASSERT(thread);
|
||||||
|
|
||||||
|
@ -78,18 +78,18 @@ rb_threadptr_scheduler_current(rb_thread_t *thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
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
|
VALUE
|
||||||
rb_scheduler_close(VALUE scheduler)
|
rb_fiber_scheduler_close(VALUE scheduler)
|
||||||
{
|
{
|
||||||
if (rb_respond_to(scheduler, id_close)) {
|
if (rb_respond_to(scheduler, id_close)) {
|
||||||
return rb_funcall(scheduler, id_close, 0);
|
return rb_funcall(scheduler, id_close, 0);
|
||||||
|
@ -99,7 +99,7 @@ rb_scheduler_close(VALUE scheduler)
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_scheduler_timeout(struct timeval *timeout)
|
rb_fiber_scheduler_make_timeout(struct timeval *timeout)
|
||||||
{
|
{
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
return rb_float_new((double)timeout->tv_sec + (0.000001f * timeout->tv_usec));
|
return rb_float_new((double)timeout->tv_sec + (0.000001f * timeout->tv_usec));
|
||||||
|
@ -109,80 +109,74 @@ rb_scheduler_timeout(struct timeval *timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
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);
|
return rb_funcall(scheduler, id_kernel_sleep, 1, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
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);
|
return rb_funcallv(scheduler, id_kernel_sleep, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
VALUE
|
||||||
rb_scheduler_supports_process_wait(VALUE scheduler)
|
rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags)
|
||||||
{
|
{
|
||||||
return rb_respond_to(scheduler, id_process_wait);
|
VALUE arguments[] = {
|
||||||
|
PIDT2NUM(pid), RB_INT2NUM(flags)
|
||||||
|
};
|
||||||
|
|
||||||
|
return rb_check_funcall(scheduler, id_process_wait, 2, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags)
|
rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout)
|
||||||
{
|
|
||||||
return rb_funcall(scheduler, id_process_wait, 2, PIDT2NUM(pid), RB_INT2NUM(flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
VALUE
|
|
||||||
rb_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout)
|
|
||||||
{
|
{
|
||||||
return rb_funcall(scheduler, id_block, 2, blocker, timeout);
|
return rb_funcall(scheduler, id_block, 2, blocker, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
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);
|
return rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
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);
|
return rb_funcall(scheduler, id_io_wait, 3, io, events, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
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
|
VALUE
|
||||||
rb_scheduler_io_wait_writable(VALUE scheduler, VALUE io)
|
rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io)
|
||||||
{
|
{
|
||||||
return rb_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_WRITABLE), Qnil);
|
return rb_fiber_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_WRITABLE), Qnil);
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
rb_scheduler_supports_io_read(VALUE scheduler)
|
|
||||||
{
|
|
||||||
return rb_respond_to(scheduler, id_io_read);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
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));
|
VALUE arguments[] = {
|
||||||
}
|
io, buffer, SIZET2NUM(offset), SIZET2NUM(length)
|
||||||
|
};
|
||||||
|
|
||||||
int
|
return rb_check_funcall(scheduler, id_io_read, 4, arguments);
|
||||||
rb_scheduler_supports_io_write(VALUE scheduler)
|
|
||||||
{
|
|
||||||
return rb_respond_to(scheduler, id_io_write);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
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.
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,24 +15,25 @@ def fetch_topics(topics)
|
||||||
topics.each do |topic|
|
topics.each do |topic|
|
||||||
Fiber.new(blocking: Fiber.current.blocking?) do
|
Fiber.new(blocking: Fiber.current.blocking?) do
|
||||||
uri = URI("https://www.google.com/search?q=#{topic}")
|
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.resume
|
||||||
end
|
end
|
||||||
|
|
||||||
Thread.fiber_scheduler&.run
|
Fiber.scheduler&.run
|
||||||
|
|
||||||
return responses
|
return responses
|
||||||
end
|
end
|
||||||
|
|
||||||
def sweep(repeats: 3, **options)
|
def sweep(repeats: 3, **options)
|
||||||
times = (1..8).map do |i|
|
times = (1..8).map do |i|
|
||||||
$stderr.puts "Measuring #{i} topic(s)..."
|
$stderr.puts "Measuring #{i} topic(s) #{options.inspect}..."
|
||||||
topics = TOPICS[0...i]
|
topics = TOPICS[0...i]
|
||||||
|
|
||||||
Thread.new do
|
Thread.new do
|
||||||
Benchmark.realtime do
|
Benchmark.realtime do
|
||||||
scheduler = Scheduler.new
|
scheduler = Scheduler.new
|
||||||
Fiber.set_scheduler scheduler
|
Fiber.set_scheduler(scheduler)
|
||||||
|
|
||||||
repeats.times do
|
repeats.times do
|
||||||
Fiber.new(**options) do
|
Fiber.new(**options) do
|
||||||
|
@ -49,5 +50,5 @@ def sweep(repeats: 3, **options)
|
||||||
puts JSON.dump(times.map{|value| value.round(3)})
|
puts JSON.dump(times.map{|value| value.round(3)})
|
||||||
end
|
end
|
||||||
|
|
||||||
sweep(blocking: true)
|
# sweep(blocking: true)
|
||||||
sweep(blocking: false)
|
sweep(blocking: false)
|
||||||
|
|
|
@ -47,6 +47,8 @@ class Scheduler
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
# $stderr.puts [__method__, Fiber.current].inspect
|
||||||
|
|
||||||
while @readable.any? or @writable.any? or @waiting.any? or @blocking.positive?
|
while @readable.any? or @writable.any? or @waiting.any? or @blocking.positive?
|
||||||
# Can only handle file descriptors up to 1024...
|
# Can only handle file descriptors up to 1024...
|
||||||
readable, writable = IO.select(@readable.keys + [@urgent.first], @writable.keys, [], next_timeout)
|
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 "readable: #{readable}" if readable&.any?
|
||||||
# puts "writable: #{writable}" if writable&.any?
|
# puts "writable: #{writable}" if writable&.any?
|
||||||
|
|
||||||
|
selected = {}
|
||||||
|
|
||||||
readable&.each do |io|
|
readable&.each do |io|
|
||||||
if fiber = @readable.delete(io)
|
if fiber = @readable.delete(io)
|
||||||
fiber.resume
|
selected[fiber] = IO::READABLE
|
||||||
elsif io == @urgent.first
|
elsif io == @urgent.first
|
||||||
@urgent.first.read_nonblock(1024)
|
@urgent.first.read_nonblock(1024)
|
||||||
end
|
end
|
||||||
|
@ -64,10 +68,14 @@ class Scheduler
|
||||||
|
|
||||||
writable&.each do |io|
|
writable&.each do |io|
|
||||||
if fiber = @writable.delete(io)
|
if fiber = @writable.delete(io)
|
||||||
fiber.resume
|
selected[fiber] |= IO::WRITABLE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
selected.each do |fiber, events|
|
||||||
|
fiber.resume(events)
|
||||||
|
end
|
||||||
|
|
||||||
if @waiting.any?
|
if @waiting.any?
|
||||||
time = current_time
|
time = current_time
|
||||||
waiting, @waiting = @waiting, {}
|
waiting, @waiting = @waiting, {}
|
||||||
|
@ -96,6 +104,8 @@ class Scheduler
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
|
# $stderr.puts [__method__, Fiber.current].inspect
|
||||||
|
|
||||||
raise "Scheduler already closed!" if @closed
|
raise "Scheduler already closed!" if @closed
|
||||||
|
|
||||||
self.run
|
self.run
|
||||||
|
@ -118,6 +128,8 @@ class Scheduler
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_wait(pid, flags)
|
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:
|
# This is a very simple way to implement a non-blocking wait:
|
||||||
Thread.new do
|
Thread.new do
|
||||||
Process::Status.wait(pid, flags)
|
Process::Status.wait(pid, flags)
|
||||||
|
@ -125,6 +137,8 @@ class Scheduler
|
||||||
end
|
end
|
||||||
|
|
||||||
def io_wait(io, events, duration)
|
def io_wait(io, events, duration)
|
||||||
|
# $stderr.puts [__method__, io, events, duration, Fiber.current].inspect
|
||||||
|
|
||||||
unless (events & IO::READABLE).zero?
|
unless (events & IO::READABLE).zero?
|
||||||
@readable[io] = Fiber.current
|
@readable[io] = Fiber.current
|
||||||
end
|
end
|
||||||
|
@ -134,12 +148,12 @@ class Scheduler
|
||||||
end
|
end
|
||||||
|
|
||||||
Fiber.yield
|
Fiber.yield
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Used for Kernel#sleep and Mutex#sleep
|
# Used for Kernel#sleep and Mutex#sleep
|
||||||
def kernel_sleep(duration = nil)
|
def kernel_sleep(duration = nil)
|
||||||
|
# $stderr.puts [__method__, duration, Fiber.current].inspect
|
||||||
|
|
||||||
self.block(:sleep, duration)
|
self.block(:sleep, duration)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -171,6 +185,8 @@ class Scheduler
|
||||||
# This might be called from another thread.
|
# This might be called from another thread.
|
||||||
def unblock(blocker, fiber)
|
def unblock(blocker, fiber)
|
||||||
# $stderr.puts [__method__, blocker, fiber].inspect
|
# $stderr.puts [__method__, blocker, fiber].inspect
|
||||||
|
# $stderr.puts blocker.backtrace.inspect
|
||||||
|
# $stderr.puts fiber.backtrace.inspect
|
||||||
|
|
||||||
@lock.synchronize do
|
@lock.synchronize do
|
||||||
@ready << fiber
|
@ready << fiber
|
||||||
|
|
|
@ -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
|
16
thread.c
16
thread.c
|
@ -81,7 +81,7 @@
|
||||||
#include "internal/io.h"
|
#include "internal/io.h"
|
||||||
#include "internal/object.h"
|
#include "internal/object.h"
|
||||||
#include "internal/proc.h"
|
#include "internal/proc.h"
|
||||||
#include "internal/scheduler.h"
|
#include "ruby/fiber/scheduler.h"
|
||||||
#include "internal/signal.h"
|
#include "internal/signal.h"
|
||||||
#include "internal/thread.h"
|
#include "internal/thread.h"
|
||||||
#include "internal/time.h"
|
#include "internal/time.h"
|
||||||
|
@ -551,8 +551,8 @@ rb_threadptr_join_list_wakeup(rb_thread_t *thread)
|
||||||
while (join_list) {
|
while (join_list) {
|
||||||
rb_thread_t *target_thread = join_list->thread;
|
rb_thread_t *target_thread = join_list->thread;
|
||||||
|
|
||||||
if (target_thread->scheduler != Qnil) {
|
if (target_thread->scheduler != Qnil && rb_fiberptr_blocking(join_list->fiber) == 0) {
|
||||||
rb_scheduler_unblock(target_thread->scheduler, target_thread->self, rb_fiberptr_self(join_list->fiber));
|
rb_fiber_scheduler_unblock(target_thread->scheduler, target_thread->self, rb_fiberptr_self(join_list->fiber));
|
||||||
} else {
|
} else {
|
||||||
rb_threadptr_interrupt(target_thread);
|
rb_threadptr_interrupt(target_thread);
|
||||||
|
|
||||||
|
@ -772,7 +772,7 @@ thread_do_start(rb_thread_t *th)
|
||||||
rb_bug("unreachable");
|
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);
|
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) {
|
while (target_th->status != THREAD_KILLED) {
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
|
|
||||||
if (scheduler != Qnil) {
|
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) {
|
} else if (!limit) {
|
||||||
th->status = THREAD_STOPPED_FOREVER;
|
th->status = THREAD_STOPPED_FOREVER;
|
||||||
rb_ractor_sleeper_threads_inc(th->ractor);
|
rb_ractor_sleeper_threads_inc(th->ractor);
|
||||||
|
@ -1525,9 +1525,9 @@ rb_thread_sleep_interruptible(void)
|
||||||
static void
|
static void
|
||||||
rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker)
|
rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker)
|
||||||
{
|
{
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
if (scheduler != Qnil) {
|
if (scheduler != Qnil) {
|
||||||
rb_scheduler_block(scheduler, blocker, Qnil);
|
rb_fiber_scheduler_block(scheduler, blocker, Qnil);
|
||||||
} else {
|
} else {
|
||||||
thread_debug("rb_thread_sleep_deadly_allow_spurious_wakeup\n");
|
thread_debug("rb_thread_sleep_deadly_allow_spurious_wakeup\n");
|
||||||
sleep_forever(GET_THREAD(), SLEEP_DEADLOCKABLE);
|
sleep_forever(GET_THREAD(), SLEEP_DEADLOCKABLE);
|
||||||
|
|
|
@ -32,8 +32,8 @@ sync_wakeup(struct list_head *head, long max)
|
||||||
|
|
||||||
if (cur->th->status != THREAD_KILLED) {
|
if (cur->th->status != THREAD_KILLED) {
|
||||||
|
|
||||||
if (cur->th->scheduler != Qnil) {
|
if (cur->th->scheduler != Qnil && rb_fiberptr_blocking(cur->fiber) == 0) {
|
||||||
rb_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
|
rb_fiber_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
|
||||||
} else {
|
} else {
|
||||||
rb_threadptr_interrupt(cur->th);
|
rb_threadptr_interrupt(cur->th);
|
||||||
cur->th->status = THREAD_RUNNABLE;
|
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) {
|
static VALUE call_rb_fiber_scheduler_block(VALUE mutex) {
|
||||||
return rb_scheduler_block(rb_scheduler_current(), mutex, Qnil);
|
return rb_fiber_scheduler_block(rb_fiber_scheduler_current(), mutex, Qnil);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -302,7 +302,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (mutex->fiber != fiber) {
|
while (mutex->fiber != fiber) {
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
if (scheduler != Qnil) {
|
if (scheduler != Qnil) {
|
||||||
COROUTINE_STACK_LOCAL(struct sync_waiter, w);
|
COROUTINE_STACK_LOCAL(struct sync_waiter, w);
|
||||||
w->self = self;
|
w->self = self;
|
||||||
|
@ -311,7 +311,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
|
||||||
|
|
||||||
list_add_tail(&mutex->waitq, &w->node);
|
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) {
|
if (!mutex->fiber) {
|
||||||
mutex->fiber = 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_for_each_safe(&mutex->waitq, cur, next, node) {
|
||||||
list_del_init(&cur->node);
|
list_del_init(&cur->node);
|
||||||
|
|
||||||
if (cur->th->scheduler != Qnil) {
|
if (cur->th->scheduler != Qnil && rb_fiberptr_blocking(cur->fiber) == 0) {
|
||||||
rb_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
|
rb_fiber_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
|
||||||
goto found;
|
goto found;
|
||||||
} else {
|
} else {
|
||||||
switch (cur->th->status) {
|
switch (cur->th->status) {
|
||||||
|
@ -545,9 +545,9 @@ rb_mutex_sleep(VALUE self, VALUE timeout)
|
||||||
rb_mutex_unlock(self);
|
rb_mutex_unlock(self);
|
||||||
time_t beg = time(0);
|
time_t beg = time(0);
|
||||||
|
|
||||||
VALUE scheduler = rb_scheduler_current();
|
VALUE scheduler = rb_fiber_scheduler_current();
|
||||||
if (scheduler != Qnil) {
|
if (scheduler != Qnil) {
|
||||||
rb_scheduler_kernel_sleep(scheduler, timeout);
|
rb_fiber_scheduler_kernel_sleep(scheduler, timeout);
|
||||||
mutex_lock_uninterruptible(self);
|
mutex_lock_uninterruptible(self);
|
||||||
} else {
|
} else {
|
||||||
if (NIL_P(timeout)) {
|
if (NIL_P(timeout)) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче