1 #![warn(rust_2018_idioms)] 2 #![cfg(feature = "full")] 3 4 use tokio::sync::Notify; 5 use tokio_test::task::spawn; 6 use tokio_test::*; 7 8 trait AssertSend: Send + Sync {} 9 impl AssertSend for Notify {} 10 11 #[test] notify_notified_one()12fn notify_notified_one() { 13 let notify = Notify::new(); 14 let mut notified = spawn(async { notify.notified().await }); 15 16 notify.notify_one(); 17 assert_ready!(notified.poll()); 18 } 19 20 #[test] notified_one_notify()21fn notified_one_notify() { 22 let notify = Notify::new(); 23 let mut notified = spawn(async { notify.notified().await }); 24 25 assert_pending!(notified.poll()); 26 27 notify.notify_one(); 28 assert!(notified.is_woken()); 29 assert_ready!(notified.poll()); 30 } 31 32 #[test] notified_multi_notify()33fn notified_multi_notify() { 34 let notify = Notify::new(); 35 let mut notified1 = spawn(async { notify.notified().await }); 36 let mut notified2 = spawn(async { notify.notified().await }); 37 38 assert_pending!(notified1.poll()); 39 assert_pending!(notified2.poll()); 40 41 notify.notify_one(); 42 assert!(notified1.is_woken()); 43 assert!(!notified2.is_woken()); 44 45 assert_ready!(notified1.poll()); 46 assert_pending!(notified2.poll()); 47 } 48 49 #[test] notify_notified_multi()50fn notify_notified_multi() { 51 let notify = Notify::new(); 52 53 notify.notify_one(); 54 55 let mut notified1 = spawn(async { notify.notified().await }); 56 let mut notified2 = spawn(async { notify.notified().await }); 57 58 assert_ready!(notified1.poll()); 59 assert_pending!(notified2.poll()); 60 61 notify.notify_one(); 62 63 assert!(notified2.is_woken()); 64 assert_ready!(notified2.poll()); 65 } 66 67 #[test] notified_drop_notified_notify()68fn notified_drop_notified_notify() { 69 let notify = Notify::new(); 70 let mut notified1 = spawn(async { notify.notified().await }); 71 let mut notified2 = spawn(async { notify.notified().await }); 72 73 assert_pending!(notified1.poll()); 74 75 drop(notified1); 76 77 assert_pending!(notified2.poll()); 78 79 notify.notify_one(); 80 assert!(notified2.is_woken()); 81 assert_ready!(notified2.poll()); 82 } 83 84 #[test] notified_multi_notify_drop_one()85fn notified_multi_notify_drop_one() { 86 let notify = Notify::new(); 87 let mut notified1 = spawn(async { notify.notified().await }); 88 let mut notified2 = spawn(async { notify.notified().await }); 89 90 assert_pending!(notified1.poll()); 91 assert_pending!(notified2.poll()); 92 93 notify.notify_one(); 94 95 assert!(notified1.is_woken()); 96 assert!(!notified2.is_woken()); 97 98 drop(notified1); 99 100 assert!(notified2.is_woken()); 101 assert_ready!(notified2.poll()); 102 } 103 104 #[test] notify_in_drop_after_wake()105fn notify_in_drop_after_wake() { 106 use futures::task::ArcWake; 107 use std::future::Future; 108 use std::sync::Arc; 109 110 let notify = Arc::new(Notify::new()); 111 112 struct NotifyOnDrop(Arc<Notify>); 113 114 impl ArcWake for NotifyOnDrop { 115 fn wake_by_ref(_arc_self: &Arc<Self>) {} 116 } 117 118 impl Drop for NotifyOnDrop { 119 fn drop(&mut self) { 120 self.0.notify_waiters(); 121 } 122 } 123 124 let mut fut = Box::pin(async { 125 notify.notified().await; 126 }); 127 128 { 129 let waker = futures::task::waker(Arc::new(NotifyOnDrop(notify.clone()))); 130 let mut cx = std::task::Context::from_waker(&waker); 131 assert!(fut.as_mut().poll(&mut cx).is_pending()); 132 } 133 134 // Now, notifying **should not** deadlock 135 notify.notify_waiters(); 136 } 137 138 #[test] notify_one_after_dropped_all()139fn notify_one_after_dropped_all() { 140 let notify = Notify::new(); 141 let mut notified1 = spawn(async { notify.notified().await }); 142 143 assert_pending!(notified1.poll()); 144 145 notify.notify_waiters(); 146 notify.notify_one(); 147 148 drop(notified1); 149 150 let mut notified2 = spawn(async { notify.notified().await }); 151 152 assert_ready!(notified2.poll()); 153 } 154