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