mio/
token.rs

1/// Associates readiness events with [`event::Source`]s.
2///
3/// `Token` is a wrapper around `usize` and is used as an argument to
4/// [`Registry::register`] and [`Registry::reregister`].
5///
6/// See [`Poll`] for more documentation on polling.
7///
8/// [`event::Source`]: ./event/trait.Source.html
9/// [`Poll`]: struct.Poll.html
10/// [`Registry::register`]: struct.Registry.html#method.register
11/// [`Registry::reregister`]: struct.Registry.html#method.reregister
12///
13/// # Example
14///
15/// Using `Token` to track which socket generated the event. In this example,
16/// `HashMap` is used, but usually something like [`slab`] is better.
17///
18/// [`slab`]: https://crates.io/crates/slab
19///
20#[cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
21#[cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
22/// # use std::error::Error;
23/// # fn main() -> Result<(), Box<dyn Error>> {
24/// # // WASI does not yet support multithreading:
25/// # if cfg!(target_os = "wasi") { return Ok(()) }
26/// use mio::{Events, Interest, Poll, Token};
27/// use mio::net::TcpListener;
28///
29/// use std::thread;
30/// use std::io::{self, Read};
31/// use std::collections::HashMap;
32///
33/// // After this number of sockets is accepted, the server will shutdown.
34/// const MAX_SOCKETS: usize = 32;
35///
36/// // Pick a token that will not be used by any other socket and use that one
37/// // for the listener.
38/// const LISTENER: Token = Token(1024);
39///
40/// // Used to store the sockets.
41/// let mut sockets = HashMap::new();
42///
43/// // This is used to generate a unique token for a socket
44/// let mut next_socket_index = 0;
45///
46/// // The `Poll` instance
47/// let mut poll = Poll::new()?;
48///
49/// // Tcp listener
50/// let mut listener = TcpListener::bind("127.0.0.1:0".parse()?)?;
51///
52/// // Register the listener
53/// poll.registry().register(&mut listener, LISTENER, Interest::READABLE)?;
54///
55/// // Spawn a thread that will connect a bunch of sockets then close them
56/// let addr = listener.local_addr()?;
57/// thread::spawn(move || {
58///     use std::net::TcpStream;
59///
60///     // +1 here is to connect an extra socket to signal the socket to close
61///     for _ in 0..(MAX_SOCKETS+1) {
62///         // Connect then drop the socket
63///         let _ = TcpStream::connect(addr).unwrap();
64///     }
65/// });
66///
67/// // Event storage
68/// let mut events = Events::with_capacity(1024);
69///
70/// // Read buffer, this will never actually get filled
71/// let mut buf = [0; 256];
72///
73/// // The main event loop
74/// loop {
75///     // Wait for events
76///     poll.poll(&mut events, None)?;
77///
78///     for event in &events {
79///         match event.token() {
80///             LISTENER => {
81///                 // Perform operations in a loop until `WouldBlock` is
82///                 // encountered.
83///                 loop {
84///                     match listener.accept() {
85///                         Ok((mut socket, _)) => {
86///                             // Shutdown the server
87///                             if next_socket_index == MAX_SOCKETS {
88///                                 return Ok(());
89///                             }
90///
91///                             // Get the token for the socket
92///                             let token = Token(next_socket_index);
93///                             next_socket_index += 1;
94///
95///                             // Register the new socket w/ poll
96///                             poll.registry().register(&mut socket, token, Interest::READABLE)?;
97///
98///                             // Store the socket
99///                             sockets.insert(token, socket);
100///                         }
101///                         Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
102///                             // Socket is not ready anymore, stop accepting
103///                             break;
104///                         }
105///                         e => panic!("err={:?}", e), // Unexpected error
106///                     }
107///                 }
108///             }
109///             token => {
110///                 // Always operate in a loop
111///                 loop {
112///                     match sockets.get_mut(&token).unwrap().read(&mut buf) {
113///                         Ok(0) => {
114///                             // Socket is closed, remove it from the map
115///                             sockets.remove(&token);
116///                             break;
117///                         }
118///                         // Data is not actually sent in this example
119///                         Ok(_) => unreachable!(),
120///                         Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
121///                             // Socket is not ready anymore, stop reading
122///                             break;
123///                         }
124///                         e => panic!("err={:?}", e), // Unexpected error
125///                     }
126///                 }
127///             }
128///         }
129///     }
130/// }
131/// # }
132/// ```
133#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
134pub struct Token(pub usize);
135
136impl From<Token> for usize {
137    fn from(val: Token) -> usize {
138        val.0
139    }
140}