Don't try to move objects with finalizer attached

This commit is contained in:
zzak 2025-05-27 23:58:50 +09:00
parent 326c120aa7
commit fe803d4dee
No known key found for this signature in database
GPG key ID: 12F68DC863673D82
2 changed files with 24 additions and 0 deletions

View file

@ -3645,6 +3645,10 @@ move_enter(VALUE obj, struct obj_traverse_replace_data *data)
return traverse_skip;
}
else {
if (FL_TEST_RAW(obj, FL_FINALIZE)) {
rb_raise(rb_eRactorError, "can not move an object with finalizer");
}
VALUE type = RB_BUILTIN_TYPE(obj);
type |= wb_protected_types[type] ? FL_WB_PROTECTED : 0;
NEWOBJ_OF(moved, struct RBasic, 0, type, rb_gc_obj_slot_size(obj), 0);
@ -3680,6 +3684,7 @@ move_leave(VALUE obj, struct obj_traverse_replace_data *data)
MEMZERO((char *)obj, char, sizeof(struct RBasic));
RBASIC(obj)->flags = flags;
RBASIC_SET_CLASS_RAW(obj, rb_cRactorMovedObject);
return traverse_cont;
}

View file

@ -54,4 +54,23 @@ class TestObjSpaceRactor < Test::Unit::TestCase
ractors.each(&:take)
RUBY
end
def test_move_finalizer
assert_ractor(<<~'RUBY', require: 'objspace')
r = Ractor.new do
Ractor.receive
end
1_000.times do
o = Object.new
ObjectSpace.define_finalizer(o, proc { })
begin
r.send(o, move: true)
rescue Ractor::Error => e
raise unless e.message.include?("finalizer")
break
end
end
RUBY
end
end