Clean up Ractor cache after fork
Ractors created in a parent process should be properly shut down in the child process. They need their cache cleared and status set to "terminated" Co-authored-by: John Hawthorn <john@hawthorn.email>
This commit is contained in:
parent
d7ad53f249
commit
f7ff380998
Notes:
git
2025-05-08 17:53:42 +00:00
@ -2210,3 +2210,10 @@ assert_equal 'ok', %q{
|
|||||||
end
|
end
|
||||||
'ok'
|
'ok'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# fork after creating Ractor
|
||||||
|
assert_equal 'ok', %q{
|
||||||
|
Ractor.new { Ractor.receive }
|
||||||
|
_, status = Process.waitpid2 fork { }
|
||||||
|
status.success? ? "ok" : status
|
||||||
|
}
|
||||||
|
10
ractor.c
10
ractor.c
@ -2072,6 +2072,8 @@ rb_ractor_main_alloc(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_WORKING_FORK)
|
#if defined(HAVE_WORKING_FORK)
|
||||||
|
// Set up the main Ractor for the VM after fork.
|
||||||
|
// Puts us in "single Ractor mode"
|
||||||
void
|
void
|
||||||
rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th)
|
rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th)
|
||||||
{
|
{
|
||||||
@ -2087,6 +2089,14 @@ rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th)
|
|||||||
VM_ASSERT(vm->ractor.blocking_cnt == 0);
|
VM_ASSERT(vm->ractor.blocking_cnt == 0);
|
||||||
VM_ASSERT(vm->ractor.cnt == 1);
|
VM_ASSERT(vm->ractor.cnt == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_ractor_terminate_atfork(rb_vm_t *vm, rb_ractor_t *r)
|
||||||
|
{
|
||||||
|
rb_gc_ractor_cache_free(r->newobj_cache);
|
||||||
|
r->newobj_cache = NULL;
|
||||||
|
r->status_ = ractor_terminated;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void rb_thread_sched_init(struct rb_thread_sched *, bool atfork);
|
void rb_thread_sched_init(struct rb_thread_sched *, bool atfork);
|
||||||
|
@ -223,6 +223,7 @@ void rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r);
|
|||||||
void rb_ractor_terminate_all(void);
|
void rb_ractor_terminate_all(void);
|
||||||
bool rb_ractor_main_p_(void);
|
bool rb_ractor_main_p_(void);
|
||||||
void rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th);
|
void rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th);
|
||||||
|
void rb_ractor_terminate_atfork(rb_vm_t *vm, rb_ractor_t *th);
|
||||||
VALUE rb_ractor_require(VALUE feature);
|
VALUE rb_ractor_require(VALUE feature);
|
||||||
VALUE rb_ractor_autoload_load(VALUE space, ID id);
|
VALUE rb_ractor_autoload_load(VALUE space, ID id);
|
||||||
|
|
||||||
|
3
thread.c
3
thread.c
@ -4740,6 +4740,9 @@ rb_thread_atfork_internal(rb_thread_t *th, void (*atfork)(rb_thread_t *, const r
|
|||||||
|
|
||||||
// OK. Only this thread accesses:
|
// OK. Only this thread accesses:
|
||||||
ccan_list_for_each(&vm->ractor.set, r, vmlr_node) {
|
ccan_list_for_each(&vm->ractor.set, r, vmlr_node) {
|
||||||
|
if (r != vm->ractor.main_ractor) {
|
||||||
|
rb_ractor_terminate_atfork(vm, r);
|
||||||
|
}
|
||||||
ccan_list_for_each(&r->threads.set, i, lt_node) {
|
ccan_list_for_each(&r->threads.set, i, lt_node) {
|
||||||
atfork(i, th);
|
atfork(i, th);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user