[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]