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