-
Notifications
You must be signed in to change notification settings - Fork 667
Closed as not planned
Labels
Description
I just had a bug in some code that looks like this:
use futures::lock::Mutex;
struct MySender {
inner: Arc<Mutex<Inner>>,
}
struct MyReceiver {
inner: Arc<Mutex<Inner>>,
}
impl Future for MyReceiver {
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
if let Poll::Ready(inner) = Pin::new(&mut self.get_mut().inner.lock()).poll(cx) {
// do some stuff
return Poll::Ready(());
}
Poll::Pending
}
}The bug is that the MutexLockFuture returned by Mutex::lock deregisters itself when it gets dropped. So if I poll MyReceiver and the lock is held the task won't get woken up again when the lock is released. AFAICT my options for fixing this are:
- Store the
MutexLockFutureinsideMyReceiver. This is inconvenient and inefficient sinceMutexLockFutureborrows theMutexand so I'd need to userentaland an extra layer of boxing. - Implement
MyReceiverwith anasyncblock/function instead of implementingFuturedirectly. Again this means an extra layer of boxing. Also I'm trying to implement a low-level primitive here and I'd rather just implementFuturedirectly. - Use a
stdnon-asyncMutex. This is obviously less than ideal, though I know in my case the lock won't get held for very long.
At the moment I've gone for option (2) since it's the laziest option, but it would be nice if there was a simple way to do this properly.
Could we add a poll_lock method to Mutex which allows me to use the Mutex in the buggy way I attempted above?
ctiller, Sherlock-Holo, hr567 and mkj