blob: 2a84bcd6f3991e59cd61d19ee95655505152cd61 [file] [log] [blame]
Jason Macnakea22e812020-03-18 01:29:19 +00001//! Utilities for creating zero-cost wakers that don't do anything.
2
3use core::task::{RawWaker, RawWakerVTable, Waker};
4use core::ptr::null;
5#[cfg(feature = "std")]
Haibo Huang66a594d2020-05-08 19:26:03 -07006use once_cell::sync::Lazy;
Jason Macnakea22e812020-03-18 01:29:19 +00007
8unsafe fn noop_clone(_data: *const ()) -> RawWaker {
9 noop_raw_waker()
10}
11
12unsafe fn noop(_data: *const ()) {}
13
14const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
15
16fn noop_raw_waker() -> RawWaker {
17 RawWaker::new(null(), &NOOP_WAKER_VTABLE)
18}
19
20/// Create a new [`Waker`] which does
21/// nothing when `wake()` is called on it.
22///
23/// # Examples
24///
25/// ```
26/// use futures::task::noop_waker;
27/// let waker = noop_waker();
28/// waker.wake();
29/// ```
30#[inline]
31pub fn noop_waker() -> Waker {
32 unsafe {
33 Waker::from_raw(noop_raw_waker())
34 }
35}
36
37/// Get a static reference to a [`Waker`] which
38/// does nothing when `wake()` is called on it.
39///
40/// # Examples
41///
42/// ```
43/// use futures::task::noop_waker_ref;
44/// let waker = noop_waker_ref();
45/// waker.wake_by_ref();
46/// ```
47#[inline]
48#[cfg(feature = "std")]
49pub fn noop_waker_ref() -> &'static Waker {
Haibo Huang66a594d2020-05-08 19:26:03 -070050 static NOOP_WAKER_INSTANCE: Lazy<Waker> = Lazy::new(noop_waker);
51 &*NOOP_WAKER_INSTANCE
52}
53
54#[cfg(test)]
55mod tests {
56 #[test]
57 #[cfg(feature = "std")]
58 fn issue_2091_cross_thread_segfault() {
59 let waker = std::thread::spawn(super::noop_waker_ref).join().unwrap();
60 waker.wake_by_ref();
Jason Macnakea22e812020-03-18 01:29:19 +000061 }
Jason Macnakea22e812020-03-18 01:29:19 +000062}