1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

merge revision(s) 5c7af72304d0ad33cd3f21b24a4bc44e8acd5b2c,d650b17686d49c2ce8e6a87039861154e93d4621: [Backport #18497]

Assuming EXIT_SUCCESS equals 0 is not portable

	---
	 test/ruby/test_fiber.rb | 6 +++---
	 1 file changed, 3 insertions(+), 3 deletions(-)

	`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.
	---
	 cont.c                     |  3 ++-
	 eval_intern.h              |  2 +-
	 test/fiber/test_process.rb | 15 +++++++++++++++
	 test/ruby/test_fiber.rb    |  5 +++++
	 4 files changed, 23 insertions(+), 2 deletions(-)
This commit is contained in:
NARUSE, Yui 2022-01-31 19:22:28 +09:00
parent 629b9da7db
commit 1c426ddb25
5 changed files with 27 additions and 6 deletions

3
cont.c
View file

@ -2039,7 +2039,7 @@ rb_fiber_set_scheduler(VALUE klass, VALUE 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
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);
else
fiber_switch(next_fiber, 1, &value, RB_NO_KEYWORDS, NULL, false);
ruby_stop(0);
}
static VALUE

View file

@ -283,7 +283,7 @@ VALUE rb_make_exception(int argc, const VALUE *argv);
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_str(VALUE, VALUE));

View file

@ -33,4 +33,19 @@ class TestFiberProcess < Test::Unit::TestCase
end
end.join
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

View file

@ -396,7 +396,7 @@ class TestFiber < Test::Unit::TestCase
Fiber.new {}.transfer
Fiber.new { Fiber.yield }
end
exit!(0)
exit!(true)
end
}.transfer
_, status = Process.waitpid2(xpid)
@ -405,8 +405,13 @@ class TestFiber < Test::Unit::TestCase
end.resume
end
pid, status = Process.waitpid2(pid)
assert_equal(0, status.exitstatus, bug5700)
assert_equal(false, status.signaled?, bug5700)
assert_not_predicate(status, :signaled?, 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
def test_exit_in_fiber

View file

@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 9
#define RUBY_PATCHLEVEL 10
#define RUBY_RELEASE_YEAR 2022
#define RUBY_RELEASE_MONTH 1