mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 22:42:48 +03:00
potentially make our promise/future crate await compatible
This commit is contained in:
parent
6d23be0164
commit
6047229bf2
@ -1,6 +1,8 @@
|
||||
use failure::{Error, Fallible};
|
||||
use failure_derive::*;
|
||||
use std::pin::Pin;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
type NextFunc<T> = Box<dyn FnOnce(Fallible<T>) + Send>;
|
||||
pub type SpawnFunc = Box<dyn FnOnce() + Send>;
|
||||
@ -59,6 +61,7 @@ enum PromiseState<T> {
|
||||
enum FutureState<T> {
|
||||
Waiting(Arc<Core<T>>),
|
||||
Ready(Result<T, Error>),
|
||||
Resolved,
|
||||
}
|
||||
|
||||
struct CoreData<T> {
|
||||
@ -208,6 +211,7 @@ impl<T: Send + 'static> Future<T> {
|
||||
locked.propagate = Some(f);
|
||||
}
|
||||
}
|
||||
FutureState::Resolved => panic!("cannot chain a Resolved future"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,6 +228,7 @@ impl<T: Send + 'static> Future<T> {
|
||||
}
|
||||
}
|
||||
FutureState::Ready(result) => result,
|
||||
FutureState::Resolved => failure::bail!("Future is already Resolved"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +238,7 @@ impl<T: Send + 'static> Future<T> {
|
||||
let locked = core.data.lock().unwrap();
|
||||
locked.result.is_some()
|
||||
}
|
||||
FutureState::Ready(_) => true,
|
||||
FutureState::Ready(_) | FutureState::Resolved => true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,6 +324,32 @@ impl<T: Send + 'static> Future<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Send + 'static> std::future::Future for Future<T> {
|
||||
type Output = Result<T, Error>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, _ctx: &mut Context) -> Poll<Self::Output> {
|
||||
// This should be safe because we're not moving the Future,
|
||||
// but instead replacing a field, and since no one is able to
|
||||
// reference the state field, we should be ok with moving that.
|
||||
let myself = unsafe { Pin::get_unchecked_mut(self) };
|
||||
|
||||
let state = std::mem::replace(&mut myself.state, FutureState::Resolved);
|
||||
match state {
|
||||
FutureState::Waiting(core) => {
|
||||
let mut locked = core.data.lock().unwrap();
|
||||
if let Some(result) = locked.result.take() {
|
||||
return Poll::Ready(result);
|
||||
}
|
||||
drop(locked);
|
||||
myself.state = FutureState::Waiting(core);
|
||||
Poll::Pending
|
||||
}
|
||||
FutureState::Ready(result) => Poll::Ready(result),
|
||||
FutureState::Resolved => panic!("polling a Resolved Future"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
Loading…
Reference in New Issue
Block a user