Skip to content

Commit ce28a0b

Browse files
committed
Fix ML cache race condition
1 parent 139cfd5 commit ce28a0b

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

Sources/FluidAudio/ASR/MLArrayCache.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ actor MLArrayCache {
2727

2828
// Check if we have a cached array
2929
if var arrays = cache[key], !arrays.isEmpty {
30-
return arrays.removeLast()
30+
// Never return the same buffer twice while it is still in use; keep the trimmed bucket so we only
31+
// hand out arrays that callers have explicitly returned to the cache.
32+
let array = arrays.removeLast()
33+
cache[key] = arrays
34+
return array
3135
}
3236

3337
return try ANEOptimizer.createANEAlignedArray(shape: shape, dataType: dataType)

Tests/FluidAudioTests/MLArrayCacheTests.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,18 @@ final class MLArrayCacheTests: XCTestCase {
241241
XCTAssertNotNil(finalArray)
242242
}
243243

244+
func testGetArrayDoesNotReuseActiveBuffer() async throws {
245+
let shape: [NSNumber] = [1, 64]
246+
247+
let array1 = try await cache.getArray(shape: shape, dataType: .float32)
248+
let array2 = try await cache.getArray(shape: shape, dataType: .float32)
249+
250+
XCTAssertFalse(array1 === array2, "Cache should not hand out the same array while it is still borrowed")
251+
252+
await cache.returnArray(array1)
253+
await cache.returnArray(array2)
254+
}
255+
244256
// Removed performance test - can cause timing issues
245257

246258
// MARK: - Global Cache Tests
@@ -255,4 +267,5 @@ final class MLArrayCacheTests: XCTestCase {
255267
// Return to shared cache
256268
await sharedMLArrayCache.returnArray(array)
257269
}
270+
258271
}

0 commit comments

Comments
 (0)