m: Use a fresh parker on Miri

Miri appears to have issues tracking the unparker when it's stored in a
thread-local variable. For now, we can just create a fresh parker for
every wait when it comes to Miri.

cc #123

Signed-off-by: John Nunley <dev@notgull.net>
This commit is contained in:
John Nunley 2024-03-31 11:14:32 -07:00
parent f402b7e24c
commit 05f67e32c7
No known key found for this signature in database
GPG Key ID: 2FE69973CFD64832
1 changed files with 24 additions and 13 deletions

View File

@ -1101,19 +1101,30 @@ impl<T, B: Borrow<Inner<T>> + Unpin> InnerListener<T, B> {
static PARKER: (Parker, Task) = parker_and_task();
}
// Try to borrow the thread-local parker/unparker pair.
PARKER
.try_with({
let this = self.as_mut();
|(parker, unparker)| this.wait_with_parker(deadline, parker, unparker.as_task_ref())
})
.unwrap_or_else(|_| {
// If the pair isn't accessible, we may be being called in a destructor.
// Just create a new pair.
let (parker, unparker) = parking::pair();
self.as_mut()
.wait_with_parker(deadline, &parker, TaskRef::Unparker(&unparker))
})
if cfg!(miri) {
// Try to borrow the thread-local parker/unparker pair.
PARKER
.try_with({
let this = self.as_mut();
|(parker, unparker)| this.wait_with_parker(deadline, parker, unparker.as_task_ref())
})
.unwrap_or_else(|_| {
// If the pair isn't accessible, we may be being called in a destructor.
// Just create a new pair.
self.as_mut().wait_with_fresh_parker(deadline)
})
} else {
// Miri seems to have issues keeping track of thread-local wakers. Just use a fresh pair.
self.wait_with_fresh_parker(deadline)
}
}
/// Wait with a fresh parker and unparker pair.
#[cfg(all(feature = "std", not(target_family = "wasm")))]
fn wait_with_fresh_parker(mut self: Pin<&mut Self>, deadline: Option<Instant>) -> Option<T> {
let (parker, unparker) = parking::pair();
self.as_mut()
.wait_with_parker(deadline, &parker, TaskRef::Unparker(&unparker))
}
/// Wait until the provided deadline using the specified parker/unparker pair.