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

partially merge revision(s) 5f69a7f604: [Backport #17666]

Co-authored-by: Samuel Williams <@ioquatix>
2cee515f02
This commit is contained in:
nagachika 2021-07-25 13:38:05 +09:00
parent dc7ad0287e
commit 95dc88c888
6 changed files with 55 additions and 4 deletions

5
cont.c
View file

@ -1155,6 +1155,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)

View file

@ -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 */

45
test/fiber/test_thread.rb Normal file
View file

@ -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

View file

@ -544,7 +544,7 @@ 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) {
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));
} else {
rb_threadptr_interrupt(target_thread);

View file

@ -32,7 +32,7 @@ sync_wakeup(struct list_head *head, long max)
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));
} else {
rb_threadptr_interrupt(cur->th);
@ -437,7 +437,7 @@ 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) {
if (cur->th->scheduler != Qnil && rb_fiberptr_blocking(cur->fiber) == 0) {
rb_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
goto found;
} else {

View file

@ -12,7 +12,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 3
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 113
#define RUBY_PATCHLEVEL 114
#define RUBY_RELEASE_YEAR 2021
#define RUBY_RELEASE_MONTH 7