xref: /third_party/rust/crates/rustix/tests/net/poll.rs (revision b8a62b91)
1b8a62b91Sopenharmony_ci//! The same as v6.rs, but with `poll` calls.
2b8a62b91Sopenharmony_ci
3b8a62b91Sopenharmony_ci#![cfg(not(any(target_os = "redox", target_os = "wasi")))]
4b8a62b91Sopenharmony_ci
5b8a62b91Sopenharmony_ciuse rustix::io::{poll, PollFd, PollFlags};
6b8a62b91Sopenharmony_ciuse rustix::net::{
7b8a62b91Sopenharmony_ci    accept, bind_v6, connect_v6, getsockname, listen, recv, send, socket, AddressFamily, Ipv6Addr,
8b8a62b91Sopenharmony_ci    Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV6, SocketType,
9b8a62b91Sopenharmony_ci};
10b8a62b91Sopenharmony_ciuse std::sync::{Arc, Condvar, Mutex};
11b8a62b91Sopenharmony_ciuse std::thread;
12b8a62b91Sopenharmony_ci
13b8a62b91Sopenharmony_ciconst BUFFER_SIZE: usize = 20;
14b8a62b91Sopenharmony_ci
15b8a62b91Sopenharmony_cifn server(ready: Arc<(Mutex<u16>, Condvar)>) {
16b8a62b91Sopenharmony_ci    let connection_socket = socket(
17b8a62b91Sopenharmony_ci        AddressFamily::INET6,
18b8a62b91Sopenharmony_ci        SocketType::STREAM,
19b8a62b91Sopenharmony_ci        Protocol::default(),
20b8a62b91Sopenharmony_ci    )
21b8a62b91Sopenharmony_ci    .unwrap();
22b8a62b91Sopenharmony_ci
23b8a62b91Sopenharmony_ci    let name = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 0, 0, 0);
24b8a62b91Sopenharmony_ci    bind_v6(&connection_socket, &name).unwrap();
25b8a62b91Sopenharmony_ci
26b8a62b91Sopenharmony_ci    let who = match getsockname(&connection_socket).unwrap() {
27b8a62b91Sopenharmony_ci        SocketAddrAny::V6(addr) => addr,
28b8a62b91Sopenharmony_ci        _ => panic!(),
29b8a62b91Sopenharmony_ci    };
30b8a62b91Sopenharmony_ci
31b8a62b91Sopenharmony_ci    listen(&connection_socket, 1).unwrap();
32b8a62b91Sopenharmony_ci
33b8a62b91Sopenharmony_ci    {
34b8a62b91Sopenharmony_ci        let (lock, cvar) = &*ready;
35b8a62b91Sopenharmony_ci        let mut port = lock.lock().unwrap();
36b8a62b91Sopenharmony_ci        *port = who.port();
37b8a62b91Sopenharmony_ci        cvar.notify_all();
38b8a62b91Sopenharmony_ci    }
39b8a62b91Sopenharmony_ci
40b8a62b91Sopenharmony_ci    let mut buffer = vec![0; BUFFER_SIZE];
41b8a62b91Sopenharmony_ci    let data_socket = accept(&connection_socket).unwrap();
42b8a62b91Sopenharmony_ci
43b8a62b91Sopenharmony_ci    let mut fds = [PollFd::new(&data_socket, PollFlags::IN)];
44b8a62b91Sopenharmony_ci    assert_eq!(poll(&mut fds, -1).unwrap(), 1);
45b8a62b91Sopenharmony_ci    assert!(fds[0].revents().intersects(PollFlags::IN));
46b8a62b91Sopenharmony_ci    assert!(!fds[0].revents().intersects(PollFlags::OUT));
47b8a62b91Sopenharmony_ci
48b8a62b91Sopenharmony_ci    let expected_nread = rustix::io::ioctl_fionread(&data_socket).unwrap();
49b8a62b91Sopenharmony_ci    let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap();
50b8a62b91Sopenharmony_ci    assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "hello, world");
51b8a62b91Sopenharmony_ci    assert_eq!(expected_nread, nread as u64);
52b8a62b91Sopenharmony_ci
53b8a62b91Sopenharmony_ci    let mut fds = [PollFd::new(&data_socket, PollFlags::OUT)];
54b8a62b91Sopenharmony_ci    assert_eq!(poll(&mut fds, -1).unwrap(), 1);
55b8a62b91Sopenharmony_ci    assert!(!fds[0].revents().intersects(PollFlags::IN));
56b8a62b91Sopenharmony_ci    assert!(fds[0].revents().intersects(PollFlags::OUT));
57b8a62b91Sopenharmony_ci
58b8a62b91Sopenharmony_ci    send(&data_socket, b"goodnight, moon", SendFlags::empty()).unwrap();
59b8a62b91Sopenharmony_ci}
60b8a62b91Sopenharmony_ci
61b8a62b91Sopenharmony_cifn client(ready: Arc<(Mutex<u16>, Condvar)>) {
62b8a62b91Sopenharmony_ci    let port = {
63b8a62b91Sopenharmony_ci        let (lock, cvar) = &*ready;
64b8a62b91Sopenharmony_ci        let mut port = lock.lock().unwrap();
65b8a62b91Sopenharmony_ci        while *port == 0 {
66b8a62b91Sopenharmony_ci            port = cvar.wait(port).unwrap();
67b8a62b91Sopenharmony_ci        }
68b8a62b91Sopenharmony_ci        *port
69b8a62b91Sopenharmony_ci    };
70b8a62b91Sopenharmony_ci
71b8a62b91Sopenharmony_ci    let addr = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), port, 0, 0);
72b8a62b91Sopenharmony_ci    let mut buffer = vec![0; BUFFER_SIZE];
73b8a62b91Sopenharmony_ci
74b8a62b91Sopenharmony_ci    let data_socket = socket(
75b8a62b91Sopenharmony_ci        AddressFamily::INET6,
76b8a62b91Sopenharmony_ci        SocketType::STREAM,
77b8a62b91Sopenharmony_ci        Protocol::default(),
78b8a62b91Sopenharmony_ci    )
79b8a62b91Sopenharmony_ci    .unwrap();
80b8a62b91Sopenharmony_ci    connect_v6(&data_socket, &addr).unwrap();
81b8a62b91Sopenharmony_ci
82b8a62b91Sopenharmony_ci    let mut fds = [PollFd::new(&data_socket, PollFlags::OUT)];
83b8a62b91Sopenharmony_ci    assert_eq!(poll(&mut fds, -1).unwrap(), 1);
84b8a62b91Sopenharmony_ci    assert!(!fds[0].revents().intersects(PollFlags::IN));
85b8a62b91Sopenharmony_ci    assert!(fds[0].revents().intersects(PollFlags::OUT));
86b8a62b91Sopenharmony_ci
87b8a62b91Sopenharmony_ci    send(&data_socket, b"hello, world", SendFlags::empty()).unwrap();
88b8a62b91Sopenharmony_ci
89b8a62b91Sopenharmony_ci    let mut fds = [PollFd::new(&data_socket, PollFlags::IN)];
90b8a62b91Sopenharmony_ci    assert_eq!(poll(&mut fds, -1).unwrap(), 1);
91b8a62b91Sopenharmony_ci    assert!(fds[0].revents().intersects(PollFlags::IN));
92b8a62b91Sopenharmony_ci    assert!(!fds[0].revents().intersects(PollFlags::OUT));
93b8a62b91Sopenharmony_ci
94b8a62b91Sopenharmony_ci    let expected_nread = rustix::io::ioctl_fionread(&data_socket).unwrap();
95b8a62b91Sopenharmony_ci    let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap();
96b8a62b91Sopenharmony_ci    assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "goodnight, moon");
97b8a62b91Sopenharmony_ci    assert_eq!(expected_nread, nread as u64);
98b8a62b91Sopenharmony_ci}
99b8a62b91Sopenharmony_ci
100b8a62b91Sopenharmony_ci#[test]
101b8a62b91Sopenharmony_cifn test_poll() {
102b8a62b91Sopenharmony_ci    let ready = Arc::new((Mutex::new(0_u16), Condvar::new()));
103b8a62b91Sopenharmony_ci    let ready_clone = Arc::clone(&ready);
104b8a62b91Sopenharmony_ci
105b8a62b91Sopenharmony_ci    let server = thread::Builder::new()
106b8a62b91Sopenharmony_ci        .name("server".to_string())
107b8a62b91Sopenharmony_ci        .spawn(move || {
108b8a62b91Sopenharmony_ci            server(ready);
109b8a62b91Sopenharmony_ci        })
110b8a62b91Sopenharmony_ci        .unwrap();
111b8a62b91Sopenharmony_ci    let client = thread::Builder::new()
112b8a62b91Sopenharmony_ci        .name("client".to_string())
113b8a62b91Sopenharmony_ci        .spawn(move || {
114b8a62b91Sopenharmony_ci            client(ready_clone);
115b8a62b91Sopenharmony_ci        })
116b8a62b91Sopenharmony_ci        .unwrap();
117b8a62b91Sopenharmony_ci    client.join().unwrap();
118b8a62b91Sopenharmony_ci    server.join().unwrap();
119b8a62b91Sopenharmony_ci}
120