| 67 | #[cfg(feature = "std")] |
| 68 | #[test] |
| 69 | fn test_waitv_wake() { |
| 70 | let lock = std::sync::Arc::new(AtomicU32::new(0)); |
| 71 | |
| 72 | let mut wait = futex::Wait::new(); |
| 73 | // In Rust 1.70, use `AtomicU32::as_ptr`. |
| 74 | wait.uaddr = (&*lock as *const AtomicU32 as *mut u32) |
| 75 | .cast::<c_void>() |
| 76 | .into(); |
| 77 | wait.flags = futex::WaitFlags::SIZE_U32; |
| 78 | wait.val = 1; |
| 79 | match futex::waitv( |
| 80 | &[wait], |
| 81 | futex::WaitvFlags::empty(), |
| 82 | None, |
| 83 | futex::ClockId::Monotonic, |
| 84 | ) { |
| 85 | Ok(_) => panic!("Nobody should be waking us!"), |
| 86 | Err(Errno::AGAIN) => { |
| 87 | assert_eq!(lock.load(Ordering::SeqCst), 0, "the lock should still be 0") |
| 88 | } |
| 89 | // Skip this test if the kernel doesn't support futex_waitv. |
| 90 | Err(Errno::NOSYS) => return, |
| 91 | Err(err) => panic!("{err}"), |
| 92 | } |
| 93 | |
| 94 | let other = std::thread::spawn({ |
| 95 | let lock = std::sync::Arc::clone(&lock); |
| 96 | move || { |
| 97 | std::thread::sleep(std::time::Duration::from_millis(1)); |
| 98 | lock.store(1, Ordering::SeqCst); |
| 99 | futex::wake(&lock, futex::Flags::empty(), 1).unwrap(); |
| 100 | |
| 101 | std::thread::sleep(std::time::Duration::from_millis(50)); |
| 102 | let mut wait = futex::Wait::new(); |
| 103 | // In Rust 1.70, use `AtomicU32::as_ptr`. |
| 104 | wait.uaddr = (&*lock as *const AtomicU32 as *mut u32) |
| 105 | .cast::<c_void>() |
| 106 | .into(); |
| 107 | wait.flags = futex::WaitFlags::SIZE_U32; |
| 108 | wait.val = 1; |
| 109 | match futex::waitv( |
| 110 | &[wait], |
| 111 | futex::WaitvFlags::empty(), |
| 112 | None, |
| 113 | futex::ClockId::Monotonic, |
| 114 | ) { |
| 115 | Ok(_) => panic!("Nobody should be waking us now!"), |
| 116 | Err(Errno::AGAIN) => { |
| 117 | assert_eq!(lock.load(Ordering::SeqCst), 2, "the lock should now be 2") |
| 118 | } |
| 119 | Err(err) => panic!("{err}"), |
| 120 | } |
| 121 | } |
| 122 | }); |
| 123 | |
| 124 | let mut wait = futex::Wait::new(); |
| 125 | // In Rust 1.70, use `AtomicU32::as_ptr`. |
| 126 | wait.uaddr = (&*lock as *const AtomicU32 as *mut u32) |