/rust/registry/src/index.crates.io-1949cf8c6b5b557f/mio-1.2.0/src/token.rs
Line | Count | Source |
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)] |
134 | | pub struct Token(pub usize); |
135 | | |
136 | | impl From<Token> for usize { |
137 | 0 | fn from(val: Token) -> usize { |
138 | 0 | val.0 |
139 | 0 | } |
140 | | } |