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()8fn 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()25fn 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()46fn 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()75fn 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()105fn 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