Merge pull request #1598 from Pauan/fix-futures

Fixing panic if the Future wakes up after returning Poll::Ready
This commit is contained in:
Alex Crichton 2019-06-17 09:36:24 -05:00 committed by GitHub
commit b5da08c6a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -233,12 +233,11 @@ where
match lock.pop_front() { match lock.pop_front() {
Some(task) => { Some(task) => {
let mut future = task.future.borrow_mut(); let mut borrow = task.future.borrow_mut();
// This will only be None if the Future wakes up the Waker after returning Poll::Ready
if let Some(future) = borrow.as_mut() {
let poll = { let poll = {
// This will only panic if the Future wakes up the Waker after returning Poll::Ready
let mut future = future.as_mut().unwrap_throw();
// Clear `is_queued` flag so that it will re-queue if poll calls waker.wake() // Clear `is_queued` flag so that it will re-queue if poll calls waker.wake()
task.is_queued.set(false); task.is_queued.set(false);
@ -248,12 +247,13 @@ where
// TODO is there some way of saving these so they don't need to be recreated all the time ? // TODO is there some way of saving these so they don't need to be recreated all the time ?
let waker = ArcWake::into_waker(task.clone()); let waker = ArcWake::into_waker(task.clone());
let cx = &mut Context::from_waker(&waker); let cx = &mut Context::from_waker(&waker);
Pin::new(&mut future).poll(cx) Pin::new(future).poll(cx)
}; };
if let Poll::Ready(_) = poll { if let Poll::Ready(_) = poll {
// Cleanup the Future immediately // Cleanup the Future immediately
*future = None; *borrow = None;
}
} }
}, },
None => { None => {