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