Skip to content

Commit a6d94bf

Browse files
luke-gruberparacycle
authored andcommitted
Take VM Lock during rb_gc_{un}register_address (ruby#16097)
The `Rice` C++ library uses an Anchor class that uses RAII to call `rb_gc_register_address`, `rb_gc_unregister_address` during init+destruct. It's unclear if this API is meant to be used at runtime like this, but we can at least lock the VM so it works safely across Ractors and doesn't mangle the `global_object_list` table.
1 parent ec337a8 commit a6d94bf

1 file changed

Lines changed: 22 additions & 17 deletions

File tree

gc.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3633,9 +3633,11 @@ rb_gc_register_address(VALUE *addr)
36333633
VALUE obj = *addr;
36343634

36353635
struct global_object_list *tmp = ALLOC(struct global_object_list);
3636-
tmp->next = vm->global_object_list;
3637-
tmp->varptr = addr;
3638-
vm->global_object_list = tmp;
3636+
RB_VM_LOCKING() {
3637+
tmp->next = vm->global_object_list;
3638+
tmp->varptr = addr;
3639+
vm->global_object_list = tmp;
3640+
}
36393641

36403642
/*
36413643
* Because some C extensions have assignment-then-register bugs,
@@ -3653,22 +3655,25 @@ void
36533655
rb_gc_unregister_address(VALUE *addr)
36543656
{
36553657
rb_vm_t *vm = GET_VM();
3656-
struct global_object_list *tmp = vm->global_object_list;
3657-
3658-
if (tmp->varptr == addr) {
3659-
vm->global_object_list = tmp->next;
3660-
SIZED_FREE(tmp);
3661-
return;
3662-
}
3663-
while (tmp->next) {
3664-
if (tmp->next->varptr == addr) {
3665-
struct global_object_list *t = tmp->next;
3658+
struct global_object_list *tmp;
3659+
RB_VM_LOCKING() {
3660+
tmp = vm->global_object_list;
3661+
if (tmp->varptr == addr) {
3662+
vm->global_object_list = tmp->next;
3663+
SIZED_FREE(tmp);
3664+
}
3665+
else {
3666+
while (tmp->next) {
3667+
if (tmp->next->varptr == addr) {
3668+
struct global_object_list *t = tmp->next;
36663669

3667-
tmp->next = tmp->next->next;
3668-
SIZED_FREE(t);
3669-
break;
3670+
tmp->next = tmp->next->next;
3671+
SIZED_FREE(t);
3672+
break;
3673+
}
3674+
tmp = tmp->next;
3675+
}
36703676
}
3671-
tmp = tmp->next;
36723677
}
36733678
}
36743679

0 commit comments

Comments
 (0)