simple_futures/
lib.rs

1//! Simple futures for use in async operations.
2#![cfg_attr(not(any(test, feature = "std")), no_std)]
3#![warn(missing_docs, missing_debug_implementations, unused_import_braces)]
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8pub mod atomic_state;
9#[cfg(feature = "alloc")]
10pub mod complete_future;
11#[cfg(feature = "alloc")]
12pub mod race_future;
13#[cfg(feature = "alloc")]
14pub mod value_future;
15
16trait EnsureSend: Send {}
17trait EnsureSync: Sync {}
18
19#[cfg(test)]
20pub mod test {
21    use std::mem::forget;
22    use std::sync::atomic::{AtomicUsize, Ordering};
23    use std::sync::Arc;
24    use std::task::{RawWaker, RawWakerVTable, Waker};
25
26    #[allow(unsafe_code)]
27    static WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
28        |ptr| {
29            let ptr_val = unsafe { Arc::from_raw(ptr as *const AtomicUsize) };
30            let clone = ptr_val.clone();
31            forget(ptr_val);
32            RawWaker::new(Arc::into_raw(clone) as *const (), &WAKER_VTABLE)
33        },
34        |ptr| {
35            let ptr_val = unsafe { Arc::from_raw(ptr as *const AtomicUsize) };
36            ptr_val.fetch_add(1, Ordering::SeqCst);
37            drop(ptr_val);
38        },
39        |ptr| {
40            unsafe { &*(ptr as *const AtomicUsize) }.fetch_add(1, Ordering::SeqCst);
41        },
42        |ptr| {
43            let ptr_val = unsafe { Arc::from_raw(ptr as *const AtomicUsize) };
44            drop(ptr_val);
45        },
46    );
47
48    #[allow(unsafe_code)]
49    pub fn get_waker(wake_count: Arc<AtomicUsize>) -> Waker {
50        unsafe {
51            Waker::from_raw(RawWaker::new(
52                Arc::into_raw(wake_count) as *const (),
53                &WAKER_VTABLE,
54            ))
55        }
56    }
57}