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 trait AssertSend: Send + Sync {} 12 impl AssertSend for Notify {} 13 14 #[test] notify_notified_one()15fn notify_notified_one() { 16 let notify = Notify::new(); 17 let mut notified = spawn(async { notify.notified().await }); 18 19 notify.notify_one(); 20 assert_ready!(notified.poll()); 21 } 22 23 #[test] notified_one_notify()24fn notified_one_notify() { 25 let notify = Notify::new(); 26 let mut notified = spawn(async { notify.notified().await }); 27 28 assert_pending!(notified.poll()); 29 30 notify.notify_one(); 31 assert!(notified.is_woken()); 32 assert_ready!(notified.poll()); 33 } 34 35 #[test] notified_multi_notify()36fn notified_multi_notify() { 37 let notify = Notify::new(); 38 let mut notified1 = spawn(async { notify.notified().await }); 39 let mut notified2 = spawn(async { notify.notified().await }); 40 41 assert_pending!(notified1.poll()); 42 assert_pending!(notified2.poll()); 43 44 notify.notify_one(); 45 assert!(notified1.is_woken()); 46 assert!(!notified2.is_woken()); 47 48 assert_ready!(notified1.poll()); 49 assert_pending!(notified2.poll()); 50 } 51 52 #[test] notify_notified_multi()53fn notify_notified_multi() { 54 let notify = Notify::new(); 55 56 notify.notify_one(); 57 58 let mut notified1 = spawn(async { notify.notified().await }); 59 let mut notified2 = spawn(async { notify.notified().await }); 60 61 assert_ready!(notified1.poll()); 62 assert_pending!(notified2.poll()); 63 64 notify.notify_one(); 65 66 assert!(notified2.is_woken()); 67 assert_ready!(notified2.poll()); 68 } 69 70 #[test] notified_drop_notified_notify()71fn notified_drop_notified_notify() { 72 let notify = Notify::new(); 73 let mut notified1 = spawn(async { notify.notified().await }); 74 let mut notified2 = spawn(async { notify.notified().await }); 75 76 assert_pending!(notified1.poll()); 77 78 drop(notified1); 79 80 assert_pending!(notified2.poll()); 81 82 notify.notify_one(); 83 assert!(notified2.is_woken()); 84 assert_ready!(notified2.poll()); 85 } 86 87 #[test] notified_multi_notify_drop_one()88fn notified_multi_notify_drop_one() { 89 let notify = Notify::new(); 90 let mut notified1 = spawn(async { notify.notified().await }); 91 let mut notified2 = spawn(async { notify.notified().await }); 92 93 assert_pending!(notified1.poll()); 94 assert_pending!(notified2.poll()); 95 96 notify.notify_one(); 97 98 assert!(notified1.is_woken()); 99 assert!(!notified2.is_woken()); 100 101 drop(notified1); 102 103 assert!(notified2.is_woken()); 104 assert_ready!(notified2.poll()); 105 } 106 107 #[test] notify_in_drop_after_wake()108fn notify_in_drop_after_wake() { 109 use futures::task::ArcWake; 110 use std::future::Future; 111 use std::sync::Arc; 112 113 let notify = Arc::new(Notify::new()); 114 115 struct NotifyOnDrop(Arc<Notify>); 116 117 impl ArcWake for NotifyOnDrop { 118 fn wake_by_ref(_arc_self: &Arc<Self>) {} 119 } 120 121 impl Drop for NotifyOnDrop { 122 fn drop(&mut self) { 123 self.0.notify_waiters(); 124 } 125 } 126 127 let mut fut = Box::pin(async { 128 notify.notified().await; 129 }); 130 131 { 132 let waker = futures::task::waker(Arc::new(NotifyOnDrop(notify.clone()))); 133 let mut cx = std::task::Context::from_waker(&waker); 134 assert!(fut.as_mut().poll(&mut cx).is_pending()); 135 } 136 137 // Now, notifying **should not** deadlock 138 notify.notify_waiters(); 139 } 140 141 #[test] notify_one_after_dropped_all()142fn notify_one_after_dropped_all() { 143 let notify = Notify::new(); 144 let mut notified1 = spawn(async { notify.notified().await }); 145 146 assert_pending!(notified1.poll()); 147 148 notify.notify_waiters(); 149 notify.notify_one(); 150 151 drop(notified1); 152 153 let mut notified2 = spawn(async { notify.notified().await }); 154 155 assert_ready!(notified2.poll()); 156 } 157 158 #[test] test_notify_one_not_enabled()159fn test_notify_one_not_enabled() { 160 let notify = Notify::new(); 161 let mut future = spawn(notify.notified()); 162 163 notify.notify_one(); 164 assert_ready!(future.poll()); 165 } 166 167 #[test] test_notify_one_after_enable()168fn test_notify_one_after_enable() { 169 let notify = Notify::new(); 170 let mut future = spawn(notify.notified()); 171 172 future.enter(|_, fut| assert!(!fut.enable())); 173 174 notify.notify_one(); 175 assert_ready!(future.poll()); 176 future.enter(|_, fut| assert!(fut.enable())); 177 } 178 179 #[test] test_poll_after_enable()180fn test_poll_after_enable() { 181 let notify = Notify::new(); 182 let mut future = spawn(notify.notified()); 183 184 future.enter(|_, fut| assert!(!fut.enable())); 185 assert_pending!(future.poll()); 186 } 187 188 #[test] test_enable_after_poll()189fn test_enable_after_poll() { 190 let notify = Notify::new(); 191 let mut future = spawn(notify.notified()); 192 193 assert_pending!(future.poll()); 194 future.enter(|_, fut| assert!(!fut.enable())); 195 } 196 197 #[test] test_enable_consumes_permit()198fn test_enable_consumes_permit() { 199 let notify = Notify::new(); 200 201 // Add a permit. 202 notify.notify_one(); 203 204 let mut future1 = spawn(notify.notified()); 205 future1.enter(|_, fut| assert!(fut.enable())); 206 207 let mut future2 = spawn(notify.notified()); 208 future2.enter(|_, fut| assert!(!fut.enable())); 209 } 210 211 #[test] test_waker_update()212fn test_waker_update() { 213 use futures::task::noop_waker; 214 use std::future::Future; 215 use std::task::Context; 216 217 let notify = Notify::new(); 218 let mut future = spawn(notify.notified()); 219 220 let noop = noop_waker(); 221 future.enter(|_, fut| assert_pending!(fut.poll(&mut Context::from_waker(&noop)))); 222 223 assert_pending!(future.poll()); 224 notify.notify_one(); 225 226 assert!(future.is_woken()); 227 } 228