• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! The same as v6.rs, but with `poll` calls.
2 
3 #![cfg(not(any(target_os = "redox", target_os = "wasi")))]
4 
5 use rustix::io::{poll, PollFd, PollFlags};
6 use rustix::net::{
7     accept, bind_v6, connect_v6, getsockname, listen, recv, send, socket, AddressFamily, Ipv6Addr,
8     Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV6, SocketType,
9 };
10 use std::sync::{Arc, Condvar, Mutex};
11 use std::thread;
12 
13 const BUFFER_SIZE: usize = 20;
14 
server(ready: Arc<(Mutex<u16>, Condvar)>)15 fn 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 
client(ready: Arc<(Mutex<u16>, Condvar)>)61 fn 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]
test_poll()101 fn 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