1use crate::sync::AtomicWaker;
2use tokio_test::task;
3
4use std::task::Waker;
5
6trait AssertSend: Send {}
7trait AssertSync: Sync {}
8
9impl AssertSend for AtomicWaker {}
10impl AssertSync for AtomicWaker {}
11
12impl AssertSend for Waker {}
13impl AssertSync for Waker {}
14
15#[cfg(all(target_family = "wasm", not(target_os = "wasi")))]
16use wasm_bindgen_test::wasm_bindgen_test as test;
17
18#[test]
19fn basic_usage() {
20 let mut waker = task::spawn(AtomicWaker::new());
21
22 waker.enter(|cx, waker| waker.register_by_ref(cx.waker()));
23 waker.wake();
24
25 assert!(waker.is_woken());
26}
27
28#[test]
29fn wake_without_register() {
30 let mut waker = task::spawn(AtomicWaker::new());
31 waker.wake();
32
33 // Registering should not result in a notification
34 waker.enter(|cx, waker| waker.register_by_ref(cx.waker()));
35
36 assert!(!waker.is_woken());
37}
38
39#[cfg(panic = "unwind")]
40#[test]
41#[cfg(not(target_family = "wasm"))] // wasm currently doesn't support unwinding
42fn atomic_waker_panic_safe() {
43 use std::panic;
44 use std::ptr;
45 use std::task::{RawWaker, RawWakerVTable, Waker};
46
47 static PANICKING_VTABLE: RawWakerVTable = RawWakerVTable::new(
48 |_| panic!("clone"),
49 |_| unimplemented!("wake"),
50 |_| unimplemented!("wake_by_ref"),
51 |_| (),
52 );
53
54 static NONPANICKING_VTABLE: RawWakerVTable = RawWakerVTable::new(
55 |_| RawWaker::new(ptr::null(), &NONPANICKING_VTABLE),
56 |_| unimplemented!("wake"),
57 |_| unimplemented!("wake_by_ref"),
58 |_| (),
59 );
60
61 let panicking = unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &PANICKING_VTABLE)) };
62 let nonpanicking = unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &NONPANICKING_VTABLE)) };
63
64 let atomic_waker = AtomicWaker::new();
65
66 let panicking = panic::AssertUnwindSafe(&panicking);
67
68 let result = panic::catch_unwind(|| {
69 let panic::AssertUnwindSafe(panicking) = panicking;
70 atomic_waker.register_by_ref(panicking);
71 });
72
73 assert!(result.is_err());
74 assert!(atomic_waker.take_waker().is_none());
75
76 atomic_waker.register_by_ref(&nonpanicking);
77 assert!(atomic_waker.take_waker().is_some());
78}
79