ruby-changes:63991
From: Koichi <ko1@a...>
Date: Mon, 7 Dec 2020 16:04:08 +0900 (JST)
Subject: [ruby-changes:63991] c2fa024e02 (master): fix Thread's interrupt and Ractor#take issue
https://git.ruby-lang.org/ruby.git/commit/?id=c2fa024e02 From c2fa024e0220aca6e2437e56df2abf1a2368cbdf Mon Sep 17 00:00:00 2001 From: Koichi Sasada <ko1@a...> Date: Mon, 7 Dec 2020 16:01:35 +0900 Subject: fix Thread's interrupt and Ractor#take issue Thread's interrupt set Ractor's wakeup_status as interrupted, but the status remains next Ractor communication API. This patch makes to ignore the previous interrupt state. [Bug #17366] Also this patch solves the Thread#kill and Ractor#take issues. diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index a960d9d..d3ff65a 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -229,6 +229,26 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L229 end } +# Can mix with Thread#interrupt and Ractor#take [Bug #17366] +assert_equal 'err', %q{ + Ractor.new{ + t = Thread.current + begin + Thread.new{ t.raise "err" }.join + rescue => e + e.message + end + }.take +} + +# Killed Ractor's thread yields nil +assert_equal 'nil', %q{ + Ractor.new{ + t = Thread.current + Thread.new{ t.kill }.join + }.take.inspect #=> nil +} + # Ractor.yield raises Ractor::ClosedError when outgoing port is closed. assert_equal 'ok', %q{ r = Ractor.new Ractor.current do |main| diff --git a/ractor.c b/ractor.c index 72e1e09..7d4404c 100644 --- a/ractor.c +++ b/ractor.c @@ -627,8 +627,8 @@ ractor_receive(rb_execution_context_t *ec, rb_ractor_t *r) https://github.com/ruby/ruby/blob/trunk/ractor.c#L627 { if (ractor_queue_empty_p(r, &r->incoming_queue)) { VM_ASSERT(r->wait.status == wait_none); - VM_ASSERT(r->wait.wakeup_status == wakeup_none); r->wait.status = wait_receiving; + r->wait.wakeup_status = wakeup_none; ractor_sleep(ec, r); @@ -887,8 +887,8 @@ ractor_select(rb_execution_context_t *ec, const VALUE *rs, int alen, VALUE yield https://github.com/ruby/ruby/blob/trunk/ractor.c#L887 RACTOR_LOCK(cr); { VM_ASSERT(cr->wait.status == wait_none); - VM_ASSERT(cr->wait.wakeup_status == wakeup_none); cr->wait.status = wait_status; + cr->wait.wakeup_status == wakeup_none; } RACTOR_UNLOCK(cr); @@ -1331,6 +1331,8 @@ ractor_yield_atexit(rb_execution_context_t *ec, rb_ractor_t *cr, VALUE v, bool e https://github.com/ruby/ruby/blob/trunk/ractor.c#L1331 VM_ASSERT(cr->wait.status == wait_none); cr->wait.status = wait_yielding; + cr->wait.wakeup_status = wakeup_none; + VM_ASSERT(cr->yield_atexit == false); cr->yield_atexit = true; } diff --git a/thread.c b/thread.c index 7fcbf9d..e910615 100644 --- a/thread.c +++ b/thread.c @@ -825,6 +825,9 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start) https://github.com/ruby/ruby/blob/trunk/thread.c#L825 errinfo = th->ec->errinfo; if (state == TAG_FATAL) { + if (th->invoke_type == thread_invoke_type_ractor_proc) { + rb_ractor_atexit(th->ec, Qnil); + } /* fatal error within this thread, need to stop whole script */ } else if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) { -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/