mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
rb_fiber_terminate
must not return [Bug #18497]
In a forked process from a fiber, the fiber becomes the only fiber, `fiber_switch` does nothing as there is no other fibers, `rb_fiber_terminate` does not terminate the fiber. In that case, reaches the end of `fiber_entry` finaly, which is declared as "COROUTINE" and should never return.
This commit is contained in:
parent
5c7af72304
commit
d650b17686
Notes:
git
2022-01-19 21:54:25 +09:00
4 changed files with 23 additions and 2 deletions
3
cont.c
3
cont.c
|
@ -2039,7 +2039,7 @@ rb_fiber_set_scheduler(VALUE klass, VALUE scheduler)
|
||||||
return rb_fiber_scheduler_set(scheduler);
|
return rb_fiber_scheduler_set(scheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt, VALUE err);
|
NORETURN(static void rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt, VALUE err));
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_fiber_start(rb_fiber_t *fiber)
|
rb_fiber_start(rb_fiber_t *fiber)
|
||||||
|
@ -2408,6 +2408,7 @@ rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt, VALUE error)
|
||||||
fiber_switch(next_fiber, -1, &error, RB_NO_KEYWORDS, NULL, false);
|
fiber_switch(next_fiber, -1, &error, RB_NO_KEYWORDS, NULL, false);
|
||||||
else
|
else
|
||||||
fiber_switch(next_fiber, 1, &value, RB_NO_KEYWORDS, NULL, false);
|
fiber_switch(next_fiber, 1, &value, RB_NO_KEYWORDS, NULL, false);
|
||||||
|
ruby_stop(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
|
|
@ -287,7 +287,7 @@ VALUE rb_make_exception(int argc, const VALUE *argv);
|
||||||
|
|
||||||
NORETURN(void rb_method_name_error(VALUE, VALUE));
|
NORETURN(void rb_method_name_error(VALUE, VALUE));
|
||||||
|
|
||||||
void rb_fiber_start(rb_fiber_t*);
|
NORETURN(void rb_fiber_start(rb_fiber_t*));
|
||||||
|
|
||||||
NORETURN(void rb_print_undef(VALUE, ID, rb_method_visibility_t));
|
NORETURN(void rb_print_undef(VALUE, ID, rb_method_visibility_t));
|
||||||
NORETURN(void rb_print_undef_str(VALUE, VALUE));
|
NORETURN(void rb_print_undef_str(VALUE, VALUE));
|
||||||
|
|
|
@ -33,4 +33,19 @@ class TestFiberProcess < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end.join
|
end.join
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_fork
|
||||||
|
omit 'fork not supported' unless Process.respond_to?(:fork)
|
||||||
|
Thread.new do
|
||||||
|
scheduler = Scheduler.new
|
||||||
|
Fiber.set_scheduler scheduler
|
||||||
|
|
||||||
|
Fiber.schedule do
|
||||||
|
pid = Process.fork {}
|
||||||
|
Process.wait(pid)
|
||||||
|
|
||||||
|
assert_predicate $?, :success?
|
||||||
|
end
|
||||||
|
end.join
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -407,6 +407,11 @@ class TestFiber < Test::Unit::TestCase
|
||||||
pid, status = Process.waitpid2(pid)
|
pid, status = Process.waitpid2(pid)
|
||||||
assert_not_predicate(status, :signaled?, bug5700)
|
assert_not_predicate(status, :signaled?, bug5700)
|
||||||
assert_predicate(status, :success?, bug5700)
|
assert_predicate(status, :success?, bug5700)
|
||||||
|
|
||||||
|
pid = Fiber.new {fork}.resume
|
||||||
|
pid, status = Process.waitpid2(pid)
|
||||||
|
assert_not_predicate(status, :signaled?)
|
||||||
|
assert_predicate(status, :success?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_exit_in_fiber
|
def test_exit_in_fiber
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue