1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#![stable(feature = "wake_trait", since = "1.51.0")]

//! 类型和 Traits 用于处理异步任务。
//!
//! **Note**: 该模块仅在支持原子加载和指针存储的平台上可用。
//! 这可以在编译时使用 `#[cfg(target_has_atomic = "ptr")]` 检测到。
//!

use core::mem::ManuallyDrop;
use core::task::{RawWaker, RawWakerVTable, Waker};

use crate::sync::Arc;

/// 在执行程序上唤醒任务的实现。
///
/// 一个可以用于创建 [`Waker`] 的 trait。
/// 执行者可以定义此 trait 的实现,并使用它来构造一个 Waker 以传递给在该执行者上执行的任务。
///
/// 这个 trait 是构建 [`RawWaker`] 的一种内存安全且符合人体工程学的替代方案。
/// 它支持通用执行程序设计,其中用于唤醒任务的数据存储在 [`Arc`] 中。
/// 某些执行程序 (尤其是嵌入式系统的执行程序) 无法使用此 API,这就是为什么存在 [`RawWaker`] 来替代这些系统的原因。
///
/// [arc]: ../../std/sync/struct.Arc.html
///
/// # Examples
///
/// 一个基本的 `block_on` 函数,它采用 future 并在当前线程上运行该函数以使其完成。
///
/// **Note:** 本示例以正确性为代价。
/// 为了防止死锁,生产级实现也将需要处理对 `thread::unpark` 的中间调用以及嵌套调用。
///
///
/// ```rust
/// use std::future::Future;
/// use std::sync::Arc;
/// use std::task::{Context, Poll, Wake};
/// use std::thread::{self, Thread};
/// use core::pin::pin;
///
/// /// 一个在调用时唤醒当前线程的唤醒器。
/// struct ThreadWaker(Thread);
///
/// impl Wake for ThreadWaker {
///     fn wake(self: Arc<Self>) {
///         self.0.unpark();
///     }
/// }
///
/// /// 在当前线程上运行 future 以完成操作。
/// fn block_on<T>(fut: impl Future<Output = T>) -> T {
///     // 固定 future,以便可以对其进行轮询。
///     let mut fut = pin!(fut);
///
///     // 创建一个要传递给 future 的新上下文。
///     let t = thread::current();
///     let waker = Arc::new(ThreadWaker(t)).into();
///     let mut cx = Context::from_waker(&waker);
///
///     // 运行 future 直到完成操作。
///     loop {
///         match fut.as_mut().poll(&mut cx) {
///             Poll::Ready(res) => return res,
///             Poll::Pending => thread::park(),
///         }
///     }
/// }
///
/// block_on(async {
///     println!("Hi from inside a future!");
/// });
/// ```
///
///
///
///
#[stable(feature = "wake_trait", since = "1.51.0")]
pub trait Wake {
    /// 唤醒此任务。
    #[stable(feature = "wake_trait", since = "1.51.0")]
    fn wake(self: Arc<Self>);

    /// 在不消耗唤醒程序的情况下唤醒此任务。
    ///
    /// 如果执行程序支持一种更便宜的唤醒方式而不消耗唤醒程序,则它应该重写此方法。
    /// 默认情况下,它将克隆 [`Arc`] 并在克隆上调用 [`wake`]。
    ///
    /// [`wake`]: Wake::wake
    ///
    #[stable(feature = "wake_trait", since = "1.51.0")]
    fn wake_by_ref(self: &Arc<Self>) {
        self.clone().wake();
    }
}

#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
    /// 使用 `Wake` 类型作为 `Waker`。
    ///
    /// 此转换不使用堆分配或原子操作。
    fn from(waker: Arc<W>) -> Waker {
        // SAFETY: 这是安全的,因为 raw_waker 从 Arc<W> 安全地构造了 RawWaker。
        //
        unsafe { Waker::from_raw(raw_waker(waker)) }
    }
}

#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
    /// 使用 `Wake` 类型作为 `RawWaker`。
    ///
    /// 此转换不使用堆分配或原子操作。
    fn from(waker: Arc<W>) -> RawWaker {
        raw_waker(waker)
    }
}

// NB: 使用此私有函数来构造 RawWaker,而不是将其内联到 `From<Arc<W>> for RawWaker` impl 中,以确保 `From<Arc<W>> for Waker` 的安全性不依赖于正确的 trait 调度 - 而是都直接或显式地调用此函数。
//
//
//
//
#[inline(always)]
fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
    // 增加 Arc 的引用计数以克隆它。
    unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
        unsafe { Arc::increment_strong_count(waker as *const W) };
        RawWaker::new(
            waker as *const (),
            &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
        )
    }

    // 按值唤醒,将 Arc 移到 Wake::wake 函数中
    unsafe fn wake<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        let waker = unsafe { Arc::from_raw(waker as *const W) };
        <W as Wake>::wake(waker);
    }

    // 通过引用唤醒,将唤醒器包裹在 ManuallyDrop 中,以避免被丢弃
    unsafe fn wake_by_ref<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        let waker = unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) };
        <W as Wake>::wake_by_ref(&waker);
    }

    // 丢弃时减少 Arc 的引用计数
    unsafe fn drop_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        unsafe { Arc::decrement_strong_count(waker as *const W) };
    }

    RawWaker::new(
        Arc::into_raw(waker) as *const (),
        &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
    )
}