• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::sync::Notify;
2 
3 use loom::future::block_on;
4 use loom::sync::Arc;
5 use loom::thread;
6 
7 #[test]
notify_one()8 fn notify_one() {
9     loom::model(|| {
10         let tx = Arc::new(Notify::new());
11         let rx = tx.clone();
12 
13         let th = thread::spawn(move || {
14             block_on(async {
15                 rx.notified().await;
16             });
17         });
18 
19         tx.notify_one();
20         th.join().unwrap();
21     });
22 }
23 
24 #[test]
notify_waiters()25 fn notify_waiters() {
26     loom::model(|| {
27         let notify = Arc::new(Notify::new());
28         let tx = notify.clone();
29         let notified1 = notify.notified();
30         let notified2 = notify.notified();
31 
32         let th = thread::spawn(move || {
33             tx.notify_waiters();
34         });
35 
36         block_on(async {
37             notified1.await;
38             notified2.await;
39         });
40 
41         th.join().unwrap();
42     });
43 }
44 
45 #[test]
notify_waiters_and_one()46 fn notify_waiters_and_one() {
47     loom::model(|| {
48         let notify = Arc::new(Notify::new());
49         let tx1 = notify.clone();
50         let tx2 = notify.clone();
51 
52         let th1 = thread::spawn(move || {
53             tx1.notify_waiters();
54         });
55 
56         let th2 = thread::spawn(move || {
57             tx2.notify_one();
58         });
59 
60         let th3 = thread::spawn(move || {
61             let notified = notify.notified();
62 
63             block_on(async {
64                 notified.await;
65             });
66         });
67 
68         th1.join().unwrap();
69         th2.join().unwrap();
70         th3.join().unwrap();
71     });
72 }
73 
74 #[test]
notify_multi()75 fn notify_multi() {
76     loom::model(|| {
77         let notify = Arc::new(Notify::new());
78 
79         let mut ths = vec![];
80 
81         for _ in 0..2 {
82             let notify = notify.clone();
83 
84             ths.push(thread::spawn(move || {
85                 block_on(async {
86                     notify.notified().await;
87                     notify.notify_one();
88                 })
89             }));
90         }
91 
92         notify.notify_one();
93 
94         for th in ths.drain(..) {
95             th.join().unwrap();
96         }
97 
98         block_on(async {
99             notify.notified().await;
100         });
101     });
102 }
103 
104 #[test]
notify_drop()105 fn notify_drop() {
106     use crate::future::poll_fn;
107     use std::future::Future;
108     use std::task::Poll;
109 
110     loom::model(|| {
111         let notify = Arc::new(Notify::new());
112         let rx1 = notify.clone();
113         let rx2 = notify.clone();
114 
115         let th1 = thread::spawn(move || {
116             let mut recv = Box::pin(rx1.notified());
117 
118             block_on(poll_fn(|cx| {
119                 if recv.as_mut().poll(cx).is_ready() {
120                     rx1.notify_one();
121                 }
122                 Poll::Ready(())
123             }));
124         });
125 
126         let th2 = thread::spawn(move || {
127             block_on(async {
128                 rx2.notified().await;
129                 // Trigger second notification
130                 rx2.notify_one();
131                 rx2.notified().await;
132             });
133         });
134 
135         notify.notify_one();
136 
137         th1.join().unwrap();
138         th2.join().unwrap();
139     });
140 }
141