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

ruby-changes:63077

From: Koichi <ko1@a...>
Date: Fri, 25 Sep 2020 00:26:01 +0900 (JST)
Subject: [ruby-changes:63077] 7ad3aff48d (master): Ractor#close_outgoping cancel Ractor.yield

https://git.ruby-lang.org/ruby.git/commit/?id=7ad3aff48d

From 7ad3aff48dc8309542704b2212b3c3d1df8155d0 Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Thu, 24 Sep 2020 17:41:10 +0900
Subject: Ractor#close_outgoping cancel Ractor.yield

Ractor#close_outgoing should cancel waiting Ractor.yield. However,
yield a value by the Ractor's block should not cancel (to recognize
terminating Ractor, introduce rb_ractor_t::yield_atexit flag).

diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index 86325f0..b6f00de 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -257,6 +257,7 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L257
     Ractor.recv
   end
 
+  sleep 0.01 # wait for Ractor.yield in r
   r.close_outgoing
   begin
     r.take
diff --git a/ractor.c b/ractor.c
index 3c87802..a7e588a 100644
--- a/ractor.c
+++ b/ractor.c
@@ -1138,6 +1138,7 @@ ractor_close_incoming(rb_execution_context_t *ec, rb_ractor_t *r) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1138
             r->incoming_port_closed = true;
             if (ractor_wakeup(r, wait_recving, wakeup_by_close)) {
                 VM_ASSERT(r->incoming_queue.cnt == 0);
+                RUBY_DEBUG_LOG("cancel receiving", 0);
             }
         }
         else {
@@ -1149,15 +1150,15 @@ ractor_close_incoming(rb_execution_context_t *ec, rb_ractor_t *r) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1150
 }
 
 static VALUE
-ractor_close_outgoing(rb_execution_context_t *ec, rb_ractor_t *cr)
+ractor_close_outgoing(rb_execution_context_t *ec, rb_ractor_t *r)
 {
     VALUE prev;
 
-    RACTOR_LOCK(cr);
+    RACTOR_LOCK(r);
     {
-        if (!cr->outgoing_port_closed) {
+        if (!r->outgoing_port_closed) {
             prev = Qfalse;
-            cr->outgoing_port_closed = true;
+            r->outgoing_port_closed = true;
         }
         else {
             prev = Qtrue;
@@ -1165,13 +1166,21 @@ ractor_close_outgoing(rb_execution_context_t *ec, rb_ractor_t *cr) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1166
 
         // wakeup all taking ractors
         rb_ractor_t *taking_ractor;
-        while ((taking_ractor = ractor_waiting_list_shift(cr, &cr->taking_ractors)) != NULL) {
+        bp();
+        while ((taking_ractor = ractor_waiting_list_shift(r, &r->taking_ractors)) != NULL) {
+            rp(taking_ractor->self);
             RACTOR_LOCK(taking_ractor);
             ractor_wakeup(taking_ractor, wait_taking, wakeup_by_close);
             RACTOR_UNLOCK(taking_ractor);
         }
+
+        // raising yielding Ractor
+        if (!r->yield_atexit &&
+            ractor_wakeup(r, wait_yielding, wakeup_by_close)) {
+            RUBY_DEBUG_LOG("cancel yielding", 0);
+        }
     }
-    RACTOR_UNLOCK(cr);
+    RACTOR_UNLOCK(r);
     return prev;
 }
 
@@ -1362,7 +1371,7 @@ ractor_create(rb_execution_context_t *ec, VALUE self, VALUE loc, VALUE name, VAL https://github.com/ruby/ruby/blob/trunk/ractor.c#L1371
 }
 
 static void
-ractor_atexit_yield(rb_execution_context_t *ec, rb_ractor_t *cr, VALUE v, bool exc)
+ractor_yield_atexit(rb_execution_context_t *ec, rb_ractor_t *cr, VALUE v, bool exc)
 {
     ASSERT_ractor_unlocking(cr);
 
@@ -1382,6 +1391,8 @@ ractor_atexit_yield(rb_execution_context_t *ec, rb_ractor_t *cr, VALUE v, bool e https://github.com/ruby/ruby/blob/trunk/ractor.c#L1391
 
                 VM_ASSERT(cr->wait.status == wait_none);
                 cr->wait.status = wait_yielding;
+                VM_ASSERT(cr->yield_atexit == false);
+                cr->yield_atexit = true;
             }
             else {
                 retry = true; // another ractor is waiting for the yield.
@@ -1413,14 +1424,14 @@ void https://github.com/ruby/ruby/blob/trunk/ractor.c#L1424
 rb_ractor_atexit(rb_execution_context_t *ec, VALUE result)
 {
     rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
-    ractor_atexit_yield(ec, cr, result, false);
+    ractor_yield_atexit(ec, cr, result, false);
 }
 
 void
 rb_ractor_atexit_exception(rb_execution_context_t *ec)
 {
     rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
-    ractor_atexit_yield(ec, cr, ec->errinfo, true);
+    ractor_yield_atexit(ec, cr, ec->errinfo, true);
 }
 
 void
diff --git a/ractor.h b/ractor.h
index 640fc62..10d7ba8 100644
--- a/ractor.h
+++ b/ractor.h
@@ -47,6 +47,7 @@ struct rb_ractor_struct { https://github.com/ruby/ruby/blob/trunk/ractor.h#L47
 
     bool incoming_port_closed;
     bool outgoing_port_closed;
+    bool yield_atexit;
 
     struct rb_ractor_waiting_list taking_ractors;
 
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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