Skip to content

Commit c224ca4

Browse files
committed
Fix a race condition with interned strings sweeping.
[Bug #21172] This fixes a rare CI failure. The timeline of the race condition is: - A `"foo" oid=1` string is interned. - `"foo" oid=1` is no longer referenced and will be swept in the future. - Another `"foo" oid=2` string is interned. - `register_fstring` finds `"foo" oid=1`, but since it is about to be swept, removes it from `fstring_table` and insert `"foo" oid=2` instead. - `"foo" oid=1` is swept, since it has the `RSTRING_FSTR` flag, a `st_delete` is issued in `fstring_table` which removes `"foo" oid=2`. I don't know how to reproduce this bug consistently in a single test case.
1 parent 53579e5 commit c224ca4

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

string.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,10 @@ fstr_update_callback(st_data_t *key, st_data_t *value, st_data_t data, int exist
433433

434434
if (rb_objspace_garbage_object_p(str)) {
435435
arg->fstr = Qundef;
436+
// When RSTRING_FSTR strings are swept, they call `st_delete`.
437+
// To avoid a race condition if an equivalent string was inserted
438+
// we must remove the flag immediately.
439+
FL_UNSET_RAW(str, RSTRING_FSTR);
436440
return ST_DELETE;
437441
}
438442

0 commit comments

Comments
 (0)