tokio/runtime/time_alt/
entry.rs1use super::cancellation_queue::Sender;
2use crate::loom::sync::{Arc, Mutex};
3use crate::util::linked_list;
4
5use std::marker::PhantomPinned;
6use std::ptr::NonNull;
7use std::task::Waker;
8
9pub(super) type EntryList = linked_list::LinkedList<Entry, Entry>;
10
11#[derive(Debug)]
12struct State {
13 cancelled: bool,
14 woken_up: bool,
15 waker: Option<Waker>,
16 cancel_tx: Option<Sender>,
17}
18
19#[derive(Debug)]
20pub(crate) struct Entry {
21 cancel_pointers: linked_list::Pointers<Entry>,
23
24 extra_pointers: linked_list::Pointers<Entry>,
46
47 deadline: u64,
49
50 state: Mutex<State>,
51
52 _pin: PhantomPinned,
57}
58
59unsafe impl linked_list::Link for Entry {
61 type Handle = Handle;
62 type Target = Entry;
63
64 fn as_raw(hdl: &Self::Handle) -> NonNull<Self::Target> {
65 unsafe { NonNull::new_unchecked(Arc::as_ptr(&hdl.entry).cast_mut()) }
66 }
67
68 unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self::Handle {
69 Handle {
70 entry: unsafe { Arc::from_raw(ptr.as_ptr()) },
71 }
72 }
73
74 unsafe fn pointers(
75 target: NonNull<Self::Target>,
76 ) -> NonNull<linked_list::Pointers<Self::Target>> {
77 let this = target.as_ptr();
78 let field = unsafe { std::ptr::addr_of_mut!((*this).extra_pointers) };
79 unsafe { NonNull::new_unchecked(field) }
80 }
81}
82
83pub(super) struct RegistrationQueueEntry;
89
90unsafe impl linked_list::Link for RegistrationQueueEntry {
92 type Handle = Handle;
93 type Target = Entry;
94
95 fn as_raw(hdl: &Self::Handle) -> NonNull<Self::Target> {
96 unsafe { NonNull::new_unchecked(Arc::as_ptr(&hdl.entry).cast_mut()) }
97 }
98
99 unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self::Handle {
100 Handle {
101 entry: unsafe { Arc::from_raw(ptr.as_ptr()) },
102 }
103 }
104
105 unsafe fn pointers(
106 target: NonNull<Self::Target>,
107 ) -> NonNull<linked_list::Pointers<Self::Target>> {
108 let this = target.as_ptr();
109 let field = unsafe { std::ptr::addr_of_mut!((*this).extra_pointers) };
110 unsafe { NonNull::new_unchecked(field) }
111 }
112}
113
114pub(super) struct CancellationQueueEntry;
120
121unsafe impl linked_list::Link for CancellationQueueEntry {
123 type Handle = Handle;
124 type Target = Entry;
125
126 fn as_raw(hdl: &Self::Handle) -> NonNull<Self::Target> {
127 unsafe { NonNull::new_unchecked(Arc::as_ptr(&hdl.entry).cast_mut()) }
128 }
129
130 unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self::Handle {
131 Handle {
132 entry: unsafe { Arc::from_raw(ptr.as_ptr()) },
133 }
134 }
135
136 unsafe fn pointers(
137 target: NonNull<Self::Target>,
138 ) -> NonNull<linked_list::Pointers<Self::Target>> {
139 let this = target.as_ptr();
140 let field = unsafe { std::ptr::addr_of_mut!((*this).cancel_pointers) };
141 unsafe { NonNull::new_unchecked(field) }
142 }
143}
144
145pub(super) struct WakeQueueEntry;
151
152unsafe impl linked_list::Link for WakeQueueEntry {
154 type Handle = Handle;
155 type Target = Entry;
156
157 fn as_raw(hdl: &Self::Handle) -> NonNull<Self::Target> {
158 unsafe { NonNull::new_unchecked(Arc::as_ptr(&hdl.entry).cast_mut()) }
159 }
160
161 unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self::Handle {
162 Handle {
163 entry: unsafe { Arc::from_raw(ptr.as_ptr()) },
164 }
165 }
166
167 unsafe fn pointers(
168 target: NonNull<Self::Target>,
169 ) -> NonNull<linked_list::Pointers<Self::Target>> {
170 let this = target.as_ptr();
171 let field = unsafe { std::ptr::addr_of_mut!((*this).extra_pointers) };
172 unsafe { NonNull::new_unchecked(field) }
173 }
174}
175
176#[derive(Debug, Clone)]
177pub(crate) struct Handle {
178 pub(crate) entry: Arc<Entry>,
179}
180
181impl From<&Handle> for NonNull<Entry> {
182 fn from(hdl: &Handle) -> Self {
183 unsafe { NonNull::new_unchecked(Arc::as_ptr(&hdl.entry) as *mut Entry) }
185 }
186}
187
188impl Handle {
189 pub(crate) fn new(deadline: u64, waker: Waker) -> Self {
190 let state = State {
191 cancelled: false,
192 woken_up: false,
193 waker: Some(waker),
194 cancel_tx: None,
195 };
196
197 let entry = Arc::new(Entry {
198 cancel_pointers: linked_list::Pointers::new(),
199 extra_pointers: linked_list::Pointers::new(),
200 deadline,
201 state: Mutex::new(state),
202 _pin: PhantomPinned,
203 });
204
205 Handle { entry }
206 }
207
208 pub(crate) fn wake(&self) {
210 let mut lock = self.entry.state.lock();
211
212 if !lock.cancelled {
213 lock.woken_up = true;
214 if let Some(waker) = lock.waker.take() {
215 drop(lock);
217 waker.wake();
218 }
219 }
220 }
221
222 pub(crate) fn register_cancel_tx(&self, cancel_tx: Sender) {
223 let mut lock = self.entry.state.lock();
224 if !lock.cancelled && !lock.woken_up {
225 let old_tx = lock.cancel_tx.replace(cancel_tx);
226 assert!(old_tx.is_none(), "cancel_tx is already registered");
228 }
229 }
230
231 pub(crate) fn register_waker(&self, waker: Waker) {
232 let mut lock = self.entry.state.lock();
233 if !lock.cancelled && !lock.woken_up {
234 let maybe_old_waker = lock.waker.replace(waker);
235 drop(lock);
237 drop(maybe_old_waker);
238 }
239 }
240
241 pub(crate) fn cancel(&self) {
242 let mut lock = self.entry.state.lock();
243 if !lock.cancelled {
244 lock.cancelled = true;
245 if let Some(cancel_tx) = lock.cancel_tx.take() {
246 drop(lock);
247
248 unsafe {
251 cancel_tx.send(self.clone());
252 }
253 }
254 }
255 }
256
257 pub(crate) fn deadline(&self) -> u64 {
258 self.entry.deadline
259 }
260
261 pub(crate) fn is_woken_up(&self) -> bool {
262 let lock = self.entry.state.lock();
263 lock.woken_up
264 }
265
266 pub(crate) fn is_cancelled(&self) -> bool {
267 let lock = self.entry.state.lock();
268 lock.cancelled
269 }
270
271 #[cfg(test)]
272 pub(crate) fn inner_strong_count(&self) -> usize {
274 Arc::strong_count(&self.entry)
275 }
276}