/// Associates readiness notifications with [`Evented`] handles. /// /// `Token` is a wrapper around `usize` and is used as an argument to /// [`Poll::register`] and [`Poll::reregister`]. /// /// See [`Poll`] for more documentation on polling. /// /// # Example /// /// Using `Token` to track which socket generated the notification. In this /// example, `HashMap` is used, but usually something like [`slab`] is better. /// /// ``` /// # use std::error::Error; /// # fn try_main() -> Result<(), Box> { /// use mio::{Events, Ready, Poll, PollOpt, Token}; /// use mio::net::TcpListener; /// /// use std::thread; /// use std::io::{self, Read}; /// use std::collections::HashMap; /// /// // After this number of sockets is accepted, the server will shutdown. /// const MAX_SOCKETS: usize = 32; /// /// // Pick a token that will not be used by any other socket and use that one /// // for the listener. /// const LISTENER: Token = Token(1024); /// /// // Used to store the sockets. /// let mut sockets = HashMap::new(); /// /// // This is used to generate a unique token for a socket /// let mut next_socket_index = 0; /// /// // The `Poll` instance /// let poll = Poll::new()?; /// /// // Tcp listener /// let listener = TcpListener::bind(&"127.0.0.1:0".parse()?)?; /// /// // Register the listener /// poll.register(&listener, /// LISTENER, /// Ready::readable(), /// PollOpt::edge())?; /// /// // Spawn a thread that will connect a bunch of sockets then close them /// let addr = listener.local_addr()?; /// thread::spawn(move || { /// use std::net::TcpStream; /// /// // +1 here is to connect an extra socket to signal the socket to close /// for _ in 0..(MAX_SOCKETS+1) { /// // Connect then drop the socket /// let _ = TcpStream::connect(&addr).unwrap(); /// } /// }); /// /// // Event storage /// let mut events = Events::with_capacity(1024); /// /// // Read buffer, this will never actually get filled /// let mut buf = [0; 256]; /// /// // The main event loop /// loop { /// // Wait for events /// poll.poll(&mut events, None)?; /// /// for event in &events { /// match event.token() { /// LISTENER => { /// // Perform operations in a loop until `WouldBlock` is /// // encountered. /// loop { /// match listener.accept() { /// Ok((socket, _)) => { /// // Shutdown the server /// if next_socket_index == MAX_SOCKETS { /// return Ok(()); /// } /// /// // Get the token for the socket /// let token = Token(next_socket_index); /// next_socket_index += 1; /// /// // Register the new socket w/ poll /// poll.register(&socket, /// token, /// Ready::readable(), /// PollOpt::edge())?; /// /// // Store the socket /// sockets.insert(token, socket); /// } /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { /// // Socket is not ready anymore, stop accepting /// break; /// } /// e => panic!("err={:?}", e), // Unexpected error /// } /// } /// } /// token => { /// // Always operate in a loop /// loop { /// match sockets.get_mut(&token).unwrap().read(&mut buf) { /// Ok(0) => { /// // Socket is closed, remove it from the map /// sockets.remove(&token); /// break; /// } /// // Data is not actually sent in this example /// Ok(_) => unreachable!(), /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { /// // Socket is not ready anymore, stop reading /// break; /// } /// e => panic!("err={:?}", e), // Unexpected error /// } /// } /// } /// } /// } /// } /// # Ok(()) /// # } /// # /// # fn main() { /// # try_main().unwrap(); /// # } /// ``` /// /// [`Evented`]: event/trait.Evented.html /// [`Poll`]: struct.Poll.html /// [`Poll::register`]: struct.Poll.html#method.register /// [`Poll::reregister`]: struct.Poll.html#method.reregister /// [`slab`]: https://crates.io/crates/slab #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Token(pub usize); impl From for Token { fn from(val: usize) -> Token { Token(val) } } impl From for usize { fn from(val: Token) -> usize { val.0 } }