Commit 563960d
Drain deferred DoReadPage callbacks before disposing scan iterator
BufferAndLoad defers page reads via BumpCurrentEpoch(() => DoReadPage(...)).
These drain callbacks capture 'this' and access instance state (frame memory,
loadCompletionEvents, etc.). For read-ahead pages, the callback may still be
in the epoch drain list when the scan completes and the iterator is disposed.
The callback then accesses freed native frame memory (AccessViolationException)
or null arrays (NullReferenceException), and the resulting exception from
within a drain callback leaves the epoch in a held state, causing cascading
'Trying to acquire protected epoch' assertion failures.
Fix: add a drain phase at the start of Dispose() that detects pending deferred
reads (nextLoadedPages[i] > loadedPages[i]) and drains them by acquiring the
epoch and calling ProtectAndDrain until the callback executes. This ensures
loadCompletionEvents[i] is set, so the existing Phase 2 wait can then handle
async I/O completion. Only after both phases is it safe to free the frame.
Also reverts the insufficient null-check guard in DoReadPage from the prior
fix, since the drain-before-dispose approach makes it unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent b86f828 commit 563960d
1 file changed
Lines changed: 41 additions & 3 deletions
Lines changed: 41 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
208 | 208 | | |
209 | 209 | | |
210 | 210 | | |
211 | | - | |
212 | | - | |
213 | | - | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
214 | 215 | | |
215 | 216 | | |
216 | 217 | | |
| |||
322 | 323 | | |
323 | 324 | | |
324 | 325 | | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
325 | 363 | | |
326 | 364 | | |
327 | 365 | | |
| |||
0 commit comments