1 #![warn(rust_2018_idioms)] 2 #![cfg(feature = "sync")] 3 4 #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] 5 use wasm_bindgen_test::wasm_bindgen_test as test; 6 7 use tokio::sync::Notify; 8 use tokio_test::task::spawn; 9 use tokio_test::*; 10 11 #[allow(unused)] 12 trait AssertSend: Send + Sync {} 13 impl AssertSend for Notify {} 14 15 #[test] notify_notified_one()16fn notify_notified_one() { 17 let notify = Notify::new(); 18 let mut notified = spawn(async { notify.notified().await }); 19 20 notify.notify_one(); 21 assert_ready!(notified.poll()); 22 } 23 24 #[test] notify_multi_notified_one()25fn notify_multi_notified_one() { 26 let notify = Notify::new(); 27 let mut notified1 = spawn(async { notify.notified().await }); 28 let mut notified2 = spawn(async { notify.notified().await }); 29 30 // add two waiters into the queue 31 assert_pending!(notified1.poll()); 32 assert_pending!(notified2.poll()); 33 34 // should wakeup the first one 35 notify.notify_one(); 36 assert_ready!(notified1.poll()); 37 assert_pending!(notified2.poll()); 38 } 39 40 #[test] notify_multi_notified_last()41fn notify_multi_notified_last() { 42 let notify = Notify::new(); 43 let mut notified1 = spawn(async { notify.notified().await }); 44 let mut notified2 = spawn(async { notify.notified().await }); 45 46 // add two waiters into the queue 47 assert_pending!(notified1.poll()); 48 assert_pending!(notified2.poll()); 49 50 // should wakeup the last one 51 notify.notify_last(); 52 assert_pending!(notified1.poll()); 53 assert_ready!(notified2.poll()); 54 } 55 56 #[test] notified_one_notify()57fn notified_one_notify() { 58 let notify = Notify::new(); 59 let mut notified = spawn(async { notify.notified().await }); 60 61 assert_pending!(notified.poll()); 62 63 notify.notify_one(); 64 assert!(notified.is_woken()); 65 assert_ready!(notified.poll()); 66 } 67 68 #[test] notified_multi_notify()69fn notified_multi_notify() { 70 let notify = Notify::new(); 71 let mut notified1 = spawn(async { notify.notified().await }); 72 let mut notified2 = spawn(async { notify.notified().await }); 73 74 assert_pending!(notified1.poll()); 75 assert_pending!(notified2.poll()); 76 77 notify.notify_one(); 78 assert!(notified1.is_woken()); 79 assert!(!notified2.is_woken()); 80 81 assert_ready!(notified1.poll()); 82 assert_pending!(notified2.poll()); 83 } 84 85 #[test] notify_notified_multi()86fn notify_notified_multi() { 87 let notify = Notify::new(); 88 89 notify.notify_one(); 90 91 let mut notified1 = spawn(async { notify.notified().await }); 92 let mut notified2 = spawn(async { notify.notified().await }); 93 94 assert_ready!(notified1.poll()); 95 assert_pending!(notified2.poll()); 96 97 notify.notify_one(); 98 99 assert!(notified2.is_woken()); 100 assert_ready!(notified2.poll()); 101 } 102 103 #[test] notified_drop_notified_notify()104fn notified_drop_notified_notify() { 105 let notify = Notify::new(); 106 let mut notified1 = spawn(async { notify.notified().await }); 107 let mut notified2 = spawn(async { notify.notified().await }); 108 109 assert_pending!(notified1.poll()); 110 111 drop(notified1); 112 113 assert_pending!(notified2.poll()); 114 115 notify.notify_one(); 116 assert!(notified2.is_woken()); 117 assert_ready!(notified2.poll()); 118 } 119 120 #[test] notified_multi_notify_drop_one()121fn notified_multi_notify_drop_one() { 122 let notify = Notify::new(); 123 let mut notified1 = spawn(async { notify.notified().await }); 124 let mut notified2 = spawn(async { notify.notified().await }); 125 126 assert_pending!(notified1.poll()); 127 assert_pending!(notified2.poll()); 128 129 notify.notify_one(); 130 131 assert!(notified1.is_woken()); 132 assert!(!notified2.is_woken()); 133 134 drop(notified1); 135 136 assert!(notified2.is_woken()); 137 assert_ready!(notified2.poll()); 138 } 139 140 #[test] notified_multi_notify_one_drop()141fn notified_multi_notify_one_drop() { 142 let notify = Notify::new(); 143 let mut notified1 = spawn(async { notify.notified().await }); 144 let mut notified2 = spawn(async { notify.notified().await }); 145 let mut notified3 = spawn(async { notify.notified().await }); 146 147 // add waiters by order of poll execution 148 assert_pending!(notified1.poll()); 149 assert_pending!(notified2.poll()); 150 assert_pending!(notified3.poll()); 151 152 // by default fifo 153 notify.notify_one(); 154 155 drop(notified1); 156 157 // next waiter should be the one to be to woken up 158 assert_ready!(notified2.poll()); 159 assert_pending!(notified3.poll()); 160 } 161 162 #[test] notified_multi_notify_last_drop()163fn notified_multi_notify_last_drop() { 164 let notify = Notify::new(); 165 let mut notified1 = spawn(async { notify.notified().await }); 166 let mut notified2 = spawn(async { notify.notified().await }); 167 let mut notified3 = spawn(async { notify.notified().await }); 168 169 // add waiters by order of poll execution 170 assert_pending!(notified1.poll()); 171 assert_pending!(notified2.poll()); 172 assert_pending!(notified3.poll()); 173 174 notify.notify_last(); 175 176 drop(notified3); 177 178 // latest waiter added should be the one to woken up 179 assert_ready!(notified2.poll()); 180 assert_pending!(notified1.poll()); 181 } 182 183 #[test] notify_in_drop_after_wake()184fn notify_in_drop_after_wake() { 185 use futures::task::ArcWake; 186 use std::future::Future; 187 use std::sync::Arc; 188 189 let notify = Arc::new(Notify::new()); 190 191 struct NotifyOnDrop(Arc<Notify>); 192 193 impl ArcWake for NotifyOnDrop { 194 fn wake_by_ref(_arc_self: &Arc<Self>) {} 195 } 196 197 impl Drop for NotifyOnDrop { 198 fn drop(&mut self) { 199 self.0.notify_waiters(); 200 } 201 } 202 203 let mut fut = Box::pin(async { 204 notify.notified().await; 205 }); 206 207 { 208 let waker = futures::task::waker(Arc::new(NotifyOnDrop(notify.clone()))); 209 let mut cx = std::task::Context::from_waker(&waker); 210 assert!(fut.as_mut().poll(&mut cx).is_pending()); 211 } 212 213 // Now, notifying **should not** deadlock 214 notify.notify_waiters(); 215 } 216 217 #[test] notify_one_after_dropped_all()218fn notify_one_after_dropped_all() { 219 let notify = Notify::new(); 220 let mut notified1 = spawn(async { notify.notified().await }); 221 222 assert_pending!(notified1.poll()); 223 224 notify.notify_waiters(); 225 notify.notify_one(); 226 227 drop(notified1); 228 229 let mut notified2 = spawn(async { notify.notified().await }); 230 231 assert_ready!(notified2.poll()); 232 } 233 234 #[test] test_notify_one_not_enabled()235fn test_notify_one_not_enabled() { 236 let notify = Notify::new(); 237 let mut future = spawn(notify.notified()); 238 239 notify.notify_one(); 240 assert_ready!(future.poll()); 241 } 242 243 #[test] test_notify_one_after_enable()244fn test_notify_one_after_enable() { 245 let notify = Notify::new(); 246 let mut future = spawn(notify.notified()); 247 248 future.enter(|_, fut| assert!(!fut.enable())); 249 250 notify.notify_one(); 251 assert_ready!(future.poll()); 252 future.enter(|_, fut| assert!(fut.enable())); 253 } 254 255 #[test] test_poll_after_enable()256fn test_poll_after_enable() { 257 let notify = Notify::new(); 258 let mut future = spawn(notify.notified()); 259 260 future.enter(|_, fut| assert!(!fut.enable())); 261 assert_pending!(future.poll()); 262 } 263 264 #[test] test_enable_after_poll()265fn test_enable_after_poll() { 266 let notify = Notify::new(); 267 let mut future = spawn(notify.notified()); 268 269 assert_pending!(future.poll()); 270 future.enter(|_, fut| assert!(!fut.enable())); 271 } 272 273 #[test] test_enable_consumes_permit()274fn test_enable_consumes_permit() { 275 let notify = Notify::new(); 276 277 // Add a permit. 278 notify.notify_one(); 279 280 let mut future1 = spawn(notify.notified()); 281 future1.enter(|_, fut| assert!(fut.enable())); 282 283 let mut future2 = spawn(notify.notified()); 284 future2.enter(|_, fut| assert!(!fut.enable())); 285 } 286 287 #[test] test_waker_update()288fn test_waker_update() { 289 use futures::task::noop_waker; 290 use std::future::Future; 291 use std::task::Context; 292 293 let notify = Notify::new(); 294 let mut future = spawn(notify.notified()); 295 296 let noop = noop_waker(); 297 future.enter(|_, fut| assert_pending!(fut.poll(&mut Context::from_waker(&noop)))); 298 299 assert_pending!(future.poll()); 300 notify.notify_one(); 301 302 assert!(future.is_woken()); 303 } 304