use core::future::poll_fn;
use std::os::fd::AsRawFd;
use std::os::unix::net::UnixDatagram;
use crate::io::source::{Kind, Source};
use crate::io::sys;
use crate::rt::context;
#[test]
fn one_armed_poll_serves_every_wait_of_a_unix_datagram() {
let Some(shard) = super::tests_recv::ring_shard_of(64, 16, 4096) else {
return;
};
let _current = context::enter(&shard);
let (mine, peer) = UnixDatagram::pair().unwrap();
sys::set_nonblocking(mine.as_raw_fd()).unwrap();
let src = Source::new(mine.as_raw_fd(), Kind::UnixDatagram);
let (taken, wait_taken) = std::sync::mpsc::channel::<()>();
let sender = std::thread::spawn(move || {
for i in 0..32u8 {
peer.send(&[i; 200]).unwrap();
wait_taken.recv().unwrap();
}
peer
});
shard.block_on(async {
for i in 0..32u8 {
let mut buf = [0u8; 512];
let (n, _) = poll_fn(|cx| src.poll_receive(cx, &mut buf, false))
.await
.unwrap();
assert_eq!(n, 200, "datagram {i} was cut");
assert!(buf[..n].iter().all(|&b| b == i), "datagram {i} changed");
taken.send(()).unwrap();
}
});
let armed = shard.ring().unwrap().polls_armed();
assert!(armed <= 1, "the poll was armed again {} times", armed - 1);
drop(sender.join().unwrap());
src.retire();
}
#[test]
fn one_armed_poll_serves_every_wait_of_a_udp_socket_the_ring_receives_none_ahead() {
let Some(shard) = super::tests_recv::ring_shard_of(64, 16, 4096) else {
return;
};
let _current = context::enter(&shard);
assert!(!shard.ring().unwrap().datagrams_ahead());
let mine = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
let to = mine.local_addr().unwrap();
sys::set_nonblocking(mine.as_raw_fd()).unwrap();
let src = Source::new(mine.as_raw_fd(), Kind::Udp);
let peer = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
let from = peer.local_addr().unwrap();
let (taken, wait_taken) = std::sync::mpsc::channel::<()>();
let sender = std::thread::spawn(move || {
for i in 0..32u8 {
peer.send_to(&[i; 1200], to).unwrap();
wait_taken.recv().unwrap();
}
});
shard.block_on(async {
for i in 0..32u8 {
let mut buf = [0u8; 2048];
let (n, sender) = poll_fn(|cx| src.poll_receive(cx, &mut buf, false))
.await
.unwrap();
assert_eq!(n, 1200, "datagram {i} was cut");
assert!(buf[..n].iter().all(|&b| b == i), "datagram {i} changed");
match sender {
crate::io::source::Addr::Inet(sender) => assert_eq!(sender, from),
other => panic!("a UDP sender came as {other:?}"),
}
taken.send(()).unwrap();
}
});
let ring = shard.ring().unwrap();
assert!(
ring.polls_armed() <= 1,
"the poll was armed again {} times",
ring.polls_armed() - 1
);
assert_eq!(
ring.multishot_counts().0,
0,
"a multishot receive of the ring's went out"
);
sender.join().unwrap();
src.retire();
}