Skip to content

Commit 0ecb8a0

Browse files
author
Ethan Crawford
committed
Fix race condition in FeatureReferences<T>.Fetch
`Fetch` writes `cached = null!` to a ref field on line 103 when it detects a revision change. This null is visible to concurrent readers before `UpdateCached` repopulates the field, causing NRE in `DefaultHttpRequest.set_RouteValues`. Replace `cached = null!` + `cached ?? UpdateCached(...)` with `(flush ? null : cached) ?? UpdateCached(...)`. When flush is true, the ternary evaluates to `null` (a local, not a write to the ref field), so `UpdateCached` is always called. When flush is false, the original fast path is preserved. No null is written to the shared ref field. Fixes #42040
1 parent fe653b1 commit 0ecb8a0

1 file changed

Lines changed: 1 addition & 3 deletions

File tree

src/Extensions/Features/src/FeatureReferences.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,11 @@ public void Initalize(IFeatureCollection collection, int revision)
9999
var revision = Collection?.Revision ?? ContextDisposed();
100100
if (Revision != revision)
101101
{
102-
// Clear cached value to force call to UpdateCached
103-
cached = null!;
104102
// Collection changed, clear whole feature cache
105103
flush = true;
106104
}
107105

108-
return cached ?? UpdateCached(ref cached!, state, factory, revision, flush);
106+
return (flush ? null : cached) ?? UpdateCached(ref cached!, state, factory, revision, flush);
109107
}
110108

111109
// Update and cache clearing logic, when the fast-path in Fetch isn't applicable

0 commit comments

Comments
 (0)