futures-core包含future库的核心特征和类型
目录结构如下
├── future.rs
├── lib.rs
├── stream.rs
└── task
├── __internal
│ ├── atomic_waker.rs
│ └── mod.rs
├── mod.rs
└── poll.rs
对外暴露的api
futures-core/src/lib.rs
pub mod future;
pub use self::future::{Future, FusedFuture, TryFuture};
pub mod stream;
pub use self::stream::{Stream, FusedStream, TryStream};
#[macro_use]
pub mod task;
futures-core/src/future.rs
/// 用于动态分发Future
#[cfg(feature = "alloc")]
pub type BoxFuture<'a, T> = Pin + Send + ' a>>;
/// 和`BoxFuture`类似, 只是没有send需求
#[cfg(feature = "alloc")]
pub type LocalBoxFuture<'a, T> = Pin + ' a>>;
pub trait FusedFuture: Future {
/// 如果不再对future轮循,则返回true
fn is_terminated(&self) -> bool;
}
mod private_try_future {
use super::Future;
pub trait Sealed {}
impl<F, T, E> Sealed for F where F: ?Sized + Future<Output = Result<T, E>> {}
}
/// 包含了出错的情况,将返回值封装在Result中
pub trait TryFuture: Future + private_try_future::Sealed {
type Ok;
type Error;
fn try_poll(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Self::Ok, Self::Error>>;
}
futures-core/src/stream.rs
stream即多个future,可以像迭代器那样迭代每个future
/// 用于动态分发Stream
#[cfg(feature = "alloc")]
pub type BoxStream<'a, T> = Pin + Send + ' a>>;
/// 和`BoxStream`类似, 只是没有send需求
#[cfg(feature = "alloc")]
pub type LocalBoxStream<'a, T> = Pin + ' a>>;
pub trait Stream {
/// Values yielded by the stream.
type Item;
/// 尝试提取此流的下一个值,如果当前的值不可用,注册当前任务以唤醒
/// 返回`Poll::Pending`,表示流的下一个值尚未准备好
/// 返回`Poll::Ready(Some(val))`,表示流已经成功产生一个值
/// 返回`Poll::Ready(None)` 表示流已经终止
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>>;
/// 返回流的剩余长度
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
pub trait FusedStream: Stream {
/// 如果不再对stream轮循,则返回true
fn is_terminated(&self) -> bool;
}
mod private_try_future {
use super::Future;
pub trait Sealed {}
impl<F, T, E> Sealed for F where F: ?Sized + Future<Output = Result<T, E>> {}
}
/// 包含了出错的情况,将返回值封装在Result中
pub trait TryFuture: Future + private_try_future::Sealed {
type Ok;
type Error;
fn try_poll(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Self::Ok, Self::Error>>;
}
futures-core/src/task
主要包含AtomicWaker的实现
pub struct AtomicWaker {
state: AtomicUsize,
waker: UnsafeCell<Option<Waker>>,
}
/// Idle state
const WAITING: usize = 0;
/// A new waker value is being registered with the `AtomicWaker` cell.
const REGISTERING: usize = 0b01;
/// The waker currently registered with the `AtomicWaker` cell is being woken.
const WAKING: usize = 0b10;
impl AtomicWaker {
/// Create an `AtomicWaker`.
pub const fn new() -> Self {
// Make sure that task is Sync
trait AssertSync: Sync {}
impl AssertSync for Waker {}
AtomicWaker {
state: AtomicUsize::new(WAITING),
waker: UnsafeCell::new(None),
}
}
/// 注册waker 以便在调用wake时得到通知
///
/// # Examples
///
/// Here is how `register` is used when implementing a flag.
///
/// ```
/// use futures::future::Future;
/// use futures::task::{Context, Poll, AtomicWaker};
/// use std::sync::atomic::AtomicBool;
/// use std::sync::atomic::Ordering::Relaxed;
/// use std::pin::Pin;
///
/// struct Flag {
/// waker: AtomicWaker,
/// set: AtomicBool,
/// }
///
/// impl Future for Flag {
/// type Output = ();
///
/// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
/// // Register **before** checking `set` to avoid a race condition
/// // that would result in lost notifications.
/// self.waker.register(cx.waker());
///
/// if self.set.load(Relaxed) {
/// Poll::Ready(())
/// } else {
/// Poll::Pending
/// }
/// }
/// }
/// ```
pub fn register(&self, waker: &Waker) {
match self.state.compare_and_swap(WAITING, REGISTERING, Acquire) {
WAITING => {
unsafe {
// Locked acquired, update the waker cell
*self.waker.get() = Some(waker.clone());
let res = self.state.compare_exchange(
REGISTERING, WAITING, AcqRel, Acquire);
match res {
Ok(_) => {
}
Err(actual) => {
debug_assert_eq!(actual, REGISTERING | WAKING);
let waker = (*self.waker.get()).take().unwrap();
self.state.swap(WAITING, AcqRel);
waker.wake();
}
}
}
}
WAKING => {
waker.wake_by_ref();
}
state => {
debug_assert!(
state == REGISTERING ||
state == REGISTERING | WAKING);
}
}
}
/// 调用wake
pub fn wake(&self) {
if let Some(waker) = self.take() {
waker.wake();
}
}
/// 返回传递给register的最后一个Waker,以便用户唤醒它
pub fn take(&self) -> Option<Waker> {
match self.state.fetch_or(WAKING, AcqRel) {
WAITING => {
// The waking lock has been acquired.
let waker = unsafe { (*self.waker.get()).take() };
// Release the lock
self.state.fetch_and(!WAKING, Release);
waker
}
state => {
debug_assert!(
state == REGISTERING ||
state == REGISTERING | WAKING ||
state == WAKING);
None
}
}
}
}