1#![warn(missing_docs)]
30#![allow(clippy::style)]
31#![allow(clippy::missing_transmute_annotations)]
33
34use core::{task, mem};
35use core::future::Future;
36use std::thread::{self, Thread};
37
38const VTABLE: task::RawWakerVTable = task::RawWakerVTable::new(clone, wake, wake_by_ref, on_drop);
39
40unsafe fn on_drop(thread: *const ()) {
41 let thread = Box::from_raw(thread as *mut Thread);
42 drop(thread);
43}
44
45unsafe fn clone(thread: *const()) -> task::RawWaker {
46 let thread = Box::from_raw(thread as *mut Thread);
50 let new_ptr = thread.clone();
51 mem::forget(thread);
52 task::RawWaker::new(Box::into_raw(new_ptr) as _, &VTABLE)
53}
54
55unsafe fn wake(thread: *const ()) {
56 let thread = Box::from_raw(thread as *mut () as *mut Thread);
57 thread.unpark();
58}
59
60unsafe fn wake_by_ref(thread: *const ()) {
61 let thread = &*(thread as *const Thread);
63 thread.unpark();
64}
65
66#[inline(always)]
67pub fn waker(thread: Thread) -> task::Waker {
69 let thread = Box::new(thread);
70 unsafe {
71 task::Waker::from_raw(task::RawWaker::new(Box::into_raw(thread) as _, &VTABLE))
72 }
73}
74
75
76pub fn block_on<F: Future>(fut: F) -> F::Output {
80 let waker = waker(thread::current());
81 let mut fut = core::pin::pin!(fut);
82 loop {
83 let mut context = task::Context::from_waker(&waker);
84 match Future::poll(fut.as_mut(), &mut context) {
85 task::Poll::Pending => thread::park(),
86 task::Poll::Ready(result) => break result,
87 }
88 }
89}