1 use crate::future::Future;
2 use crate::runtime::task::{Cell, Harness, Header, Schedule, State};
3
4 use std::ptr::NonNull;
5 use std::task::{Poll, Waker};
6
7 /// Raw task handle
8 pub(super) struct RawTask {
9 ptr: NonNull<Header>,
10 }
11
12 pub(super) struct Vtable {
13 /// Polls the future.
14 pub(super) poll: unsafe fn(NonNull<Header>),
15
16 /// Deallocates the memory.
17 pub(super) dealloc: unsafe fn(NonNull<Header>),
18
19 /// Reads the task output, if complete.
20 pub(super) try_read_output: unsafe fn(NonNull<Header>, *mut (), &Waker),
21
22 /// The join handle has been dropped.
23 pub(super) drop_join_handle_slow: unsafe fn(NonNull<Header>),
24
25 /// The task is remotely aborted.
26 pub(super) remote_abort: unsafe fn(NonNull<Header>),
27
28 /// Scheduler is being shutdown.
29 pub(super) shutdown: unsafe fn(NonNull<Header>),
30 }
31
32 /// Get the vtable for the requested `T` and `S` generics.
vtable<T: Future, S: Schedule>() -> &'static Vtable33 pub(super) fn vtable<T: Future, S: Schedule>() -> &'static Vtable {
34 &Vtable {
35 poll: poll::<T, S>,
36 dealloc: dealloc::<T, S>,
37 try_read_output: try_read_output::<T, S>,
38 drop_join_handle_slow: drop_join_handle_slow::<T, S>,
39 remote_abort: remote_abort::<T, S>,
40 shutdown: shutdown::<T, S>,
41 }
42 }
43
44 impl RawTask {
new<T, S>(task: T, scheduler: S) -> RawTask where T: Future, S: Schedule,45 pub(super) fn new<T, S>(task: T, scheduler: S) -> RawTask
46 where
47 T: Future,
48 S: Schedule,
49 {
50 let ptr = Box::into_raw(Cell::<_, S>::new(task, scheduler, State::new()));
51 let ptr = unsafe { NonNull::new_unchecked(ptr as *mut Header) };
52
53 RawTask { ptr }
54 }
55
from_raw(ptr: NonNull<Header>) -> RawTask56 pub(super) unsafe fn from_raw(ptr: NonNull<Header>) -> RawTask {
57 RawTask { ptr }
58 }
59
60 /// Returns a reference to the task's meta structure.
61 ///
62 /// Safe as `Header` is `Sync`.
header(&self) -> &Header63 pub(super) fn header(&self) -> &Header {
64 unsafe { self.ptr.as_ref() }
65 }
66
67 /// Safety: mutual exclusion is required to call this function.
poll(self)68 pub(super) fn poll(self) {
69 let vtable = self.header().vtable;
70 unsafe { (vtable.poll)(self.ptr) }
71 }
72
dealloc(self)73 pub(super) fn dealloc(self) {
74 let vtable = self.header().vtable;
75 unsafe {
76 (vtable.dealloc)(self.ptr);
77 }
78 }
79
80 /// Safety: `dst` must be a `*mut Poll<super::Result<T::Output>>` where `T`
81 /// is the future stored by the task.
try_read_output(self, dst: *mut (), waker: &Waker)82 pub(super) unsafe fn try_read_output(self, dst: *mut (), waker: &Waker) {
83 let vtable = self.header().vtable;
84 (vtable.try_read_output)(self.ptr, dst, waker);
85 }
86
drop_join_handle_slow(self)87 pub(super) fn drop_join_handle_slow(self) {
88 let vtable = self.header().vtable;
89 unsafe { (vtable.drop_join_handle_slow)(self.ptr) }
90 }
91
shutdown(self)92 pub(super) fn shutdown(self) {
93 let vtable = self.header().vtable;
94 unsafe { (vtable.shutdown)(self.ptr) }
95 }
96
remote_abort(self)97 pub(super) fn remote_abort(self) {
98 let vtable = self.header().vtable;
99 unsafe { (vtable.remote_abort)(self.ptr) }
100 }
101 }
102
103 impl Clone for RawTask {
clone(&self) -> Self104 fn clone(&self) -> Self {
105 RawTask { ptr: self.ptr }
106 }
107 }
108
109 impl Copy for RawTask {}
110
poll<T: Future, S: Schedule>(ptr: NonNull<Header>)111 unsafe fn poll<T: Future, S: Schedule>(ptr: NonNull<Header>) {
112 let harness = Harness::<T, S>::from_raw(ptr);
113 harness.poll();
114 }
115
dealloc<T: Future, S: Schedule>(ptr: NonNull<Header>)116 unsafe fn dealloc<T: Future, S: Schedule>(ptr: NonNull<Header>) {
117 let harness = Harness::<T, S>::from_raw(ptr);
118 harness.dealloc();
119 }
120
try_read_output<T: Future, S: Schedule>( ptr: NonNull<Header>, dst: *mut (), waker: &Waker, )121 unsafe fn try_read_output<T: Future, S: Schedule>(
122 ptr: NonNull<Header>,
123 dst: *mut (),
124 waker: &Waker,
125 ) {
126 let out = &mut *(dst as *mut Poll<super::Result<T::Output>>);
127
128 let harness = Harness::<T, S>::from_raw(ptr);
129 harness.try_read_output(out, waker);
130 }
131
drop_join_handle_slow<T: Future, S: Schedule>(ptr: NonNull<Header>)132 unsafe fn drop_join_handle_slow<T: Future, S: Schedule>(ptr: NonNull<Header>) {
133 let harness = Harness::<T, S>::from_raw(ptr);
134 harness.drop_join_handle_slow()
135 }
136
remote_abort<T: Future, S: Schedule>(ptr: NonNull<Header>)137 unsafe fn remote_abort<T: Future, S: Schedule>(ptr: NonNull<Header>) {
138 let harness = Harness::<T, S>::from_raw(ptr);
139 harness.remote_abort()
140 }
141
shutdown<T: Future, S: Schedule>(ptr: NonNull<Header>)142 unsafe fn shutdown<T: Future, S: Schedule>(ptr: NonNull<Header>) {
143 let harness = Harness::<T, S>::from_raw(ptr);
144 harness.shutdown()
145 }
146