diff options
author | Koichi Sasada <[email protected]> | 2020-11-10 18:21:11 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2020-11-11 15:49:02 +0900 |
commit | db31ace934e8b900e90853bd875f23195837b398 (patch) | |
tree | f9e1e0999b574c0adf974e885420781b2dbd5a15 | |
parent | 1e8abe5d03ae386af82e2c95ef05170cd9791889 (diff) |
Threads in a ractor will be killed with the ractor
If a terminating ractor has child threads, then kill all child
threads.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/3754
-rw-r--r-- | bootstraptest/test_ractor.rb | 34 | ||||
-rw-r--r-- | eval_intern.h | 1 | ||||
-rw-r--r-- | ractor.c | 4 | ||||
-rw-r--r-- | thread.c | 14 |
4 files changed, 42 insertions, 11 deletions
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index 527059d97b..86a033cba8 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -396,6 +396,39 @@ assert_equal '[RuntimeError, "ok", true]', %q{ end } +# threads in a ractor will killed +assert_equal '{:ok=>3}', %q{ + Ractor.new Ractor.current do |main| + q = Queue.new + Thread.new do + q << true + loop{} + ensure + main << :ok + end + + Thread.new do + q << true + while true + end + ensure + main << :ok + end + + Thread.new do + q << true + sleep 1 + ensure + main << :ok + end + + # wait for the start of all threads + 3.times{q.pop} + end + + 3.times.map{Ractor.receive}.tally +} + # unshareable object are copied assert_equal 'false', %q{ obj = 'str'.dup @@ -516,7 +549,6 @@ assert_equal [false, true, false].inspect, %q{ results << check(C.new(false).freeze) # false } - # move example2: String # touching moved object causes an error assert_equal 'hello world', %q{ diff --git a/eval_intern.h b/eval_intern.h index 83d7056234..34489777a2 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -293,7 +293,6 @@ rb_cref_t *rb_vm_cref(void); rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void); VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename); void rb_vm_set_progname(VALUE filename); -void rb_thread_terminate_all(void); VALUE rb_vm_cbase(void); /* vm_backtrace.c */ @@ -1591,7 +1591,7 @@ rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r) } } -void rb_thread_terminate_all(void); // thread.c +void rb_thread_terminate_all(rb_thread_t *th); // thread.c static void ractor_terminal_interrupt_all(rb_vm_t *vm) @@ -1620,7 +1620,7 @@ rb_ractor_terminate_all(void) ractor_terminal_interrupt_all(vm); // kill all ractors RB_VM_UNLOCK(); } - rb_thread_terminate_all(); // kill other threads in main-ractor and wait + rb_thread_terminate_all(GET_THREAD()); // kill other threads in main-ractor and wait RB_VM_LOCK(); { @@ -587,16 +587,15 @@ rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th) } void -rb_thread_terminate_all(void) +rb_thread_terminate_all(rb_thread_t *th) { - rb_thread_t *volatile th = GET_THREAD(); /* main thread */ + rb_ractor_t *cr = th->ractor; rb_execution_context_t * volatile ec = th->ec; - rb_ractor_t *r = th->ractor; volatile int sleeping = 0; - if (r->threads.main != th) { + if (cr->threads.main != th) { rb_bug("rb_thread_terminate_all: called by child thread (%p, %p)", - (void *)r->threads.main, (void *)th); + (void *)cr->threads.main, (void *)th); } /* unlock all locking mutexes */ @@ -606,9 +605,9 @@ rb_thread_terminate_all(void) if (EC_EXEC_TAG() == TAG_NONE) { retry: thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th); - terminate_all(th->ractor, th); + terminate_all(cr, th); - while (rb_ractor_living_thread_num(th->ractor) > 1) { + while (rb_ractor_living_thread_num(cr) > 1) { rb_hrtime_t rel = RB_HRTIME_PER_SEC; /*q * Thread exiting routine in thread_start_func_2 notify @@ -854,6 +853,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start) } if (th->invoke_type == thread_invoke_type_ractor_proc) { + rb_thread_terminate_all(th); rb_ractor_teardown(th->ec); } |