rust异步编程:futures-rs之futures-core

文章目录

    • 概述
    • future
    • stream
    • task

概述

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;

future

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>>;
}

stream

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>>;
}

task

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
            }
        }
    }
}

你可能感兴趣的:(rust)