Threads in a ractor will be killed with the ractor
If a terminating ractor has child threads, then kill all child threads.
This commit is contained in:
parent
1e8abe5d03
commit
db31ace934
Notes:
git
2020-11-11 15:49:27 +09:00
@ -396,6 +396,39 @@ assert_equal '[RuntimeError, "ok", true]', %q{
|
|||||||
end
|
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
|
# unshareable object are copied
|
||||||
assert_equal 'false', %q{
|
assert_equal 'false', %q{
|
||||||
obj = 'str'.dup
|
obj = 'str'.dup
|
||||||
@ -516,7 +549,6 @@ assert_equal [false, true, false].inspect, %q{
|
|||||||
results << check(C.new(false).freeze) # false
|
results << check(C.new(false).freeze) # false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# move example2: String
|
# move example2: String
|
||||||
# touching moved object causes an error
|
# touching moved object causes an error
|
||||||
assert_equal 'hello world', %q{
|
assert_equal 'hello world', %q{
|
||||||
|
@ -293,7 +293,6 @@ rb_cref_t *rb_vm_cref(void);
|
|||||||
rb_cref_t *rb_vm_cref_replace_with_duplicated_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);
|
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_vm_set_progname(VALUE filename);
|
||||||
void rb_thread_terminate_all(void);
|
|
||||||
VALUE rb_vm_cbase(void);
|
VALUE rb_vm_cbase(void);
|
||||||
|
|
||||||
/* vm_backtrace.c */
|
/* vm_backtrace.c */
|
||||||
|
4
ractor.c
4
ractor.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
|
static void
|
||||||
ractor_terminal_interrupt_all(rb_vm_t *vm)
|
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
|
ractor_terminal_interrupt_all(vm); // kill all ractors
|
||||||
RB_VM_UNLOCK();
|
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();
|
RB_VM_LOCK();
|
||||||
{
|
{
|
||||||
|
14
thread.c
14
thread.c
@ -587,16 +587,15 @@ rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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_execution_context_t * volatile ec = th->ec;
|
||||||
rb_ractor_t *r = th->ractor;
|
|
||||||
volatile int sleeping = 0;
|
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)",
|
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 */
|
/* unlock all locking mutexes */
|
||||||
@ -606,9 +605,9 @@ rb_thread_terminate_all(void)
|
|||||||
if (EC_EXEC_TAG() == TAG_NONE) {
|
if (EC_EXEC_TAG() == TAG_NONE) {
|
||||||
retry:
|
retry:
|
||||||
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
|
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;
|
rb_hrtime_t rel = RB_HRTIME_PER_SEC;
|
||||||
/*q
|
/*q
|
||||||
* Thread exiting routine in thread_start_func_2 notify
|
* 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) {
|
if (th->invoke_type == thread_invoke_type_ractor_proc) {
|
||||||
|
rb_thread_terminate_all(th);
|
||||||
rb_ractor_teardown(th->ec);
|
rb_ractor_teardown(th->ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user