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