ractor: don't inherit the default thread group

[Bug #17506]

`Thread.current.group` isn't shareable so it shouldn't be inherited
by the main thread of a new Ractor.

This cause an extra allocation when spawning a ractor, which could
be elided with a bit of extra work, but not sure if it's worth
the effort.
This commit is contained in:
Jean Boussier 2025-03-30 19:18:34 +02:00
parent 2263e26f40
commit 5e421ce8d9
Notes: git 2025-03-31 08:26:10 +00:00
2 changed files with 28 additions and 3 deletions

View File

@ -60,6 +60,17 @@ class TestRactor < Test::Unit::TestCase
assert_unshareable(x, "can not make shareable object for #<Method: String(Kernel)#itself()>", exception: Ractor::Error) assert_unshareable(x, "can not make shareable object for #<Method: String(Kernel)#itself()>", exception: Ractor::Error)
end end
def test_default_thread_group
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
Warning[:experimental] = false
main_ractor_id = Thread.current.group.object_id
ractor_id = Ractor.new { Thread.current.group.object_id }.take
refute_equal main_ractor_id, ractor_id
end;
end
def assert_make_shareable(obj) def assert_make_shareable(obj)
refute Ractor.shareable?(obj), "object was already shareable" refute Ractor.shareable?(obj), "object was already shareable"
Ractor.make_shareable(obj) Ractor.make_shareable(obj)

View File

@ -106,6 +106,7 @@
#endif #endif
static VALUE rb_cThreadShield; static VALUE rb_cThreadShield;
static VALUE cThGroup;
static VALUE sym_immediate; static VALUE sym_immediate;
static VALUE sym_on_blocking; static VALUE sym_on_blocking;
@ -795,6 +796,7 @@ struct thread_create_params {
// for normal proc thread // for normal proc thread
VALUE args; VALUE args;
VALUE proc; VALUE proc;
VALUE group;
// for ractor // for ractor
rb_ractor_t *g; rb_ractor_t *g;
@ -853,7 +855,13 @@ thread_create_core(VALUE thval, struct thread_create_params *params)
} }
th->priority = current_th->priority; th->priority = current_th->priority;
th->thgroup = current_th->thgroup;
if (params->group) {
th->thgroup = params->group;
}
else {
th->thgroup = current_th->thgroup;
}
th->pending_interrupt_queue = rb_ary_hidden_new(0); th->pending_interrupt_queue = rb_ary_hidden_new(0);
th->pending_interrupt_queue_checked = 0; th->pending_interrupt_queue_checked = 0;
@ -993,13 +1001,20 @@ rb_thread_create(VALUE (*fn)(void *), void *arg)
VALUE VALUE
rb_thread_create_ractor(rb_ractor_t *r, VALUE args, VALUE proc) rb_thread_create_ractor(rb_ractor_t *r, VALUE args, VALUE proc)
{ {
VALUE thgroup = r->thgroup_default = rb_obj_alloc(cThGroup);
#if RACTOR_CHECK_MODE > 0
rb_ractor_setup_belonging_to(thgroup, r->pub.id);
#endif
struct thread_create_params params = { struct thread_create_params params = {
.type = thread_invoke_type_ractor_proc, .type = thread_invoke_type_ractor_proc,
.g = r, .g = r,
.group = thgroup,
.args = args, .args = args,
.proc = proc, .proc = proc,
}; };
return thread_create_core(rb_thread_alloc(rb_cThread), &params); RB_GC_GUARD(thgroup);
return thread_create_core(rb_thread_alloc(rb_cThread), &params);;
} }
@ -5427,7 +5442,6 @@ Init_Thread_Mutex(void)
void void
Init_Thread(void) Init_Thread(void)
{ {
VALUE cThGroup;
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
sym_never = ID2SYM(rb_intern_const("never")); sym_never = ID2SYM(rb_intern_const("never"));