Skip to content

Commit 694904a

Browse files
committed
handle race
1 parent 8b94419 commit 694904a

File tree

1 file changed

+18
-22
lines changed

1 file changed

+18
-22
lines changed

src/Compiler/Utilities/Caches.fs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,10 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (totalC
215215
async {
216216
match! mb.Receive() with
217217
| EvictionQueueMessage.Add entity ->
218-
219-
assert entity.Node.IsSome
220-
221-
evictionQueue.AddLast(entity.Node.Value)
218+
evictionQueue.AddLast(entity.Node)
222219

223220
// Evict one immediately if necessary.
224-
while evictionQueue.Count > capacity do
221+
if evictionQueue.Count > capacity then
225222
let first = nonNull evictionQueue.First
226223

227224
match store.TryRemove(first.Value.Key) with
@@ -232,16 +229,13 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (totalC
232229
evicted.Trigger()
233230
| _ -> evictionFails.Add 1L
234231

235-
| EvictionQueueMessage.Update entity ->
236-
entity.AccessCount <- entity.AccessCount + 1L
232+
// Store updates are not synchronized. It is possible the entity is no longer in the queue.
233+
| EvictionQueueMessage.Update entity when isNull entity.Node.List -> ()
237234

238-
assert entity.Node.IsSome
239-
240-
let node = entity.Node.Value
241-
assert (node.List = evictionQueue)
235+
| EvictionQueueMessage.Update entity ->
242236
// Just move this node to the end of the list.
243-
evictionQueue.Remove(node)
244-
evictionQueue.AddLast(node)
237+
evictionQueue.Remove(entity.Node)
238+
evictionQueue.AddLast(entity.Node)
245239

246240
return! processNext ()
247241
}
@@ -256,25 +250,27 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (totalC
256250

257251
member _.TryGetValue(key: 'Key, value: outref<'Value>) =
258252
match store.TryGetValue(key) with
259-
| true, cachedEntity ->
253+
| true, entity ->
260254
hits.Add 1L
261-
evictionProcessor.Post(EvictionQueueMessage.Update cachedEntity)
262-
value <- cachedEntity.Value
255+
evictionProcessor.Post(EvictionQueueMessage.Update entity)
256+
value <- entity.Value
263257
true
264258
| _ ->
265259
misses.Add 1L
266260
value <- Unchecked.defaultof<'Value>
267261
false
268262

269263
member _.TryAdd(key: 'Key, value: 'Value) =
270-
let cachedEntity = pool.Acquire(key, value)
264+
let entity = pool.Acquire(key, value)
271265

272-
if store.TryAdd(key, cachedEntity) then
273-
evictionProcessor.Post(EvictionQueueMessage.Add cachedEntity)
274-
true
266+
let added = store.TryAdd(key, entity)
267+
268+
if added then
269+
evictionProcessor.Post(EvictionQueueMessage.Add entity)
275270
else
276-
pool.Reclaim(cachedEntity)
277-
false
271+
pool.Reclaim(entity)
272+
273+
added
278274

279275
interface IDisposable with
280276
member this.Dispose() =

0 commit comments

Comments
 (0)