taskette_utils/
futures.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Support for asynchronous (`async`/`await`) code
6
7use core::{
8    pin::pin,
9    task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
10};
11
12use taskette::task::{self, TaskHandle};
13
14const RAW_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
15    raw_waker_clone,
16    raw_waker_wake,
17    raw_waker_wake_by_ref,
18    raw_waker_drop,
19);
20
21/// Executes a `Future` and blocks the current task until it completes.
22///
23/// It yields CPU to other tasks while blocking and does not involve busy loop.
24pub fn block_on<F: Future>(fut: F) -> F::Output {
25    let current_task = task::current().expect("Failed to get the current task");
26
27    // SAFETY: `current_task` will live during the execution of the future (i.e. within this function)
28    let waker = unsafe {
29        Waker::from_raw(RawWaker::new(
30            &current_task as *const TaskHandle as *const (),
31            &RAW_WAKER_VTABLE,
32        ))
33    };
34    let mut context = Context::from_waker(&waker);
35
36    let mut fut = pin!(fut);
37
38    loop {
39        match fut.as_mut().poll(&mut context) {
40            Poll::Ready(ret) => break ret,
41            Poll::Pending => task::park().expect("Failed to park the task"),
42        }
43    }
44}
45
46unsafe fn raw_waker_clone(data: *const ()) -> RawWaker {
47    RawWaker::new(data, &RAW_WAKER_VTABLE)
48}
49
50unsafe fn raw_waker_wake(data: *const ()) {
51    let task_handle = unsafe { &*(data as *const TaskHandle) };
52    task_handle.unpark().expect("Failed to unpark the task");
53}
54
55unsafe fn raw_waker_wake_by_ref(data: *const ()) {
56    let task_handle = unsafe { &*(data as *const TaskHandle) };
57    task_handle.unpark().expect("Failed to unpark the task");
58}
59
60unsafe fn raw_waker_drop(_data: *const ()) {
61    // Do nothing
62}