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
|
use std::{
future::Future,
ptr::NonNull,
task::{Poll, Waker},
};
use crate::task::{Cell, Harness, Header, Schedule};
pub(crate) struct RawTask {
ptr: NonNull<Header>, // 非空指向 Header 的裸指针
}
impl Clone for RawTask {
fn clone(&self) -> Self {
*self // 实际上是个裸指针
}
}
impl Copy for RawTask {}
// 函数表
pub(crate) struct Vtable {
/// Poll the future
pub(crate) poll: unsafe fn(NonNull<Header>),
/// Deallocate the memory
/// 释放内存
pub(crate) dealloc: unsafe fn(NonNull<Header>),
/// Read the task output, if complete
/// 读取任务输出,如果完成
pub(crate) try_read_output: unsafe fn(NonNull<Header>, *mut (), &Waker),
/// The join handle has been dropped
/// 缓慢的丢弃 join handle
pub(crate) drop_join_handle_slow: unsafe fn(NonNull<Header>),
/// Set future output
#[cfg(feature = "sync")]
pub(crate) finish: unsafe fn(NonNull<Header>, *mut ()),
}
/// Get the vtable for the requested `T` and `S` generics.
/// 生成 vtable (函数表)
pub(super) fn vtable<T: Future, S: Schedule>() -> &'static Vtable {
&Vtable {
poll: poll::<T, S>, // 调用 poll
dealloc: dealloc::<T, S>, // 释放资源
try_read_output: try_read_output::<T, S>, // 尝试读取输出
drop_join_handle_slow: drop_join_handle_slow::<T, S>,
#[cfg(feature = "sync")]
finish: finish::<T, S>,
}
}
impl RawTask {
pub(crate) fn new<T, S>(owner_id: usize, task: T, scheduler: S) -> RawTask
where
T: Future,
S: Schedule,
{
// 指向 new Cell 的裸指针
let ptr = Box::into_raw(Cell::new(owner_id, task, scheduler));
// 指向 Header 的裸指针 | Header 是 Cell 的第一个字段
let ptr = unsafe { NonNull::new_unchecked(ptr as *mut Header) };
RawTask { ptr }
}
// 由 Header 生成 RawTask
pub(crate) unsafe fn from_raw(ptr: NonNull<Header>) -> RawTask {
RawTask { ptr }
}
// 获取 header 字段的引用
pub(crate) fn header(&self) -> &Header {
unsafe { self.ptr.as_ref() }
}
/// Safety: mutual exclusion is required to call this function.
/// 执行 函数表的 poll 函数
pub(crate) fn poll(self) {
let vtable: &Vtable = self.header().vtable;
unsafe { (vtable.poll)(self.ptr) }
}
// 执行 函数表的 dealloc 函数 | 释放内存
pub(crate) fn dealloc(self) {
let vtable = self.header().vtable;
unsafe {
(vtable.dealloc)(self.ptr);
}
}
/// Safety: `dst` must be a `*mut Poll<super::Result<T::Output>>` where `T`
/// is the future stored by the task.
/// 尝试读取任务输出, 必须确保 dst 是一个 `*mut Poll<super::Result<T::Output>>` 类型
pub(crate) unsafe fn try_read_output(self, dst: *mut (), waker: &Waker) {
let vtable = self.header().vtable;
(vtable.try_read_output)(self.ptr, dst, waker);
}
// 缓慢的丢弃 join handle
pub(crate) fn drop_join_handle_slow(self) {
let vtable = self.header().vtable;
unsafe { (vtable.drop_join_handle_slow)(self.ptr) }
}
#[cfg(feature = "sync")]
pub(crate) unsafe fn finish(self, val_slot: *mut ()) {
let vtable = self.header().vtable;
unsafe { (vtable.finish)(self.ptr, val_slot) }
}
}
// 指向 poll 函数, poll future
unsafe fn poll<T: Future, S: Schedule>(ptr: NonNull<Header>) {
let harness = Harness::<T, S>::from_raw(ptr);
harness.poll();
}
// 指向 dealloc 函数,释放内存
unsafe fn dealloc<T: Future, S: Schedule>(ptr: NonNull<Header>) {
let harness: Harness<T, S> = Harness::<T, S>::from_raw(ptr);
harness.dealloc();
}
#[cfg(feature = "sync")]
unsafe fn finish<T: Future, S: Schedule>(ptr: NonNull<Header>, val: *mut ()) {
let harness = Harness::<T, S>::from_raw(ptr);
let val = &mut *(val as *mut Option<<T as Future>::Output>);
harness.finish(val.take().unwrap());
}
// 尝试读取输出
unsafe fn try_read_output<T: Future, S: Schedule>(
ptr: NonNull<Header>,
dst: *mut (),
waker: &Waker,
) {
let out = &mut *(dst as *mut Poll<T::Output>);
let harness = Harness::<T, S>::from_raw(ptr);
harness.try_read_output(out, waker);
}
// 缓慢丢弃 join handle
unsafe fn drop_join_handle_slow<T: Future, S: Schedule>(ptr: NonNull<Header>) {
let harness = Harness::<T, S>::from_raw(ptr);
harness.drop_join_handle_slow()
}
|