diff options
Diffstat (limited to 'third_party/rust/mio-0.6.23/src/token.rs')
-rw-r--r-- | third_party/rust/mio-0.6.23/src/token.rs | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/third_party/rust/mio-0.6.23/src/token.rs b/third_party/rust/mio-0.6.23/src/token.rs new file mode 100644 index 0000000000..09e42450bc --- /dev/null +++ b/third_party/rust/mio-0.6.23/src/token.rs @@ -0,0 +1,153 @@ +/// 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<Error>> { +/// 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<usize> for Token { + fn from(val: usize) -> Token { + Token(val) + } +} + +impl From<Token> for usize { + fn from(val: Token) -> usize { + val.0 + } +} |