Fix retain/load ordering races in stream_*_windowed setup #1
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two related thread-safety races share one root cause: in the
stream_*_windowedsetup path, a file is loaded into the cachebefore the symbol is protected by a reference count, so a
concurrent eviction can race the load. Both are verified by reading
the source; the concrete interleavings below are flagged as
unverified — no reproducing test exists yet.
Root cause
In
src/lib.rs,stream_m1_windowed(and identicallystream_tick_windowed) loads before it retains:stream_tick_windowedhas the same ordering atsrc/lib.rs:250-255.Between the load and the
retain_symbol, the freshly loaded file iscovered by no reference count, so
release_symbol->evict_symbol(src/cache.rs:158-181) from another thread can dropit.
Race 1 — eviction between load and retain
Claim (unverified, deduced from the ordering above): with thread A
iterating symbol S (
symbol_refs[S] == 1) and thread B enteringstream_m1_windowed(S):Consequence: redundant I/O (the file is reloaded). Delivered records
stay correct, because the iterator holds an
Arcclone of any chunkit already obtained (
current_file_chunks,src/lib.rs:416).Race 2 — prefetch insert outlives an evict
Claim (unverified, deduced from
prefetch_m1atsrc/lib.rs:340-356and
insert_m1atsrc/cache.rs:77-84): a background prefetch threadspawned for symbol S can call
insert_m1afterevict_symbol(S)has run:
Consequence: an entry sits in the cache with no covering reference
count. It is only reclaimed if some later iterator happens to
retain-then-release S again — otherwise it is a leak. This is sharper
than Race 1, whose only cost is redundant I/O.
Direction
stream_m1_windowedandstream_tick_windowedsosymbol_refs[S] >= 1spans the wholesetup, closing the window.
insert_*from inserting a key whose symbol isnot currently retained, or extend the reference count to cover
in-flight prefetches.
shared symbol to ratify the fix.