Commit b86f828
Fix deferred DoReadPage drain callback accessing disposed ScanIteratorBase (#1718)
BufferAndLoad registers DoReadPage as a deferred drain callback via
BumpCurrentEpoch. This callback captures instance state including
loadCompletionEvents. When the callback is for a read-ahead page and
SafeToReclaimEpoch hasn't advanced yet, the callback remains in the
drain list. If the scan completes and the iterator is disposed before
the callback executes, loadCompletionEvents is set to null. When the
callback later runs (during another thread's Drain), it accesses the
null array, throwing NullReferenceException.
This exception from a drain callback leaves the epoch in a held state
(SuspendDrain's Resume/Release is not exception-safe), causing the
cascading 'Trying to acquire protected epoch' assertion failure seen
in ObjectIterationPushLockTest(4,4,Iterate,False).
Fix: capture loadCompletionEvents into a local before accessing it in
DoReadPage, and return early if the iterator has been disposed.
Co-authored-by: badrishc <badrishc@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 19e7f82 commit b86f828
1 file changed
Lines changed: 7 additions & 1 deletion
Lines changed: 7 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
208 | 208 | | |
209 | 209 | | |
210 | 210 | | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
211 | 217 | | |
212 | | - | |
| 218 | + | |
213 | 219 | | |
214 | 220 | | |
215 | 221 | | |
| |||
0 commit comments