diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/mio/src/token.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/mio/src/token.rs')
-rw-r--r-- | third_party/rust/mio/src/token.rs | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/third_party/rust/mio/src/token.rs b/third_party/rust/mio/src/token.rs new file mode 100644 index 0000000000..91601cde0c --- /dev/null +++ b/third_party/rust/mio/src/token.rs @@ -0,0 +1,138 @@ +/// Associates readiness events with [`event::Source`]s. +/// +/// `Token` is a wrapper around `usize` and is used as an argument to +/// [`Registry::register`] and [`Registry::reregister`]. +/// +/// See [`Poll`] for more documentation on polling. +/// +/// [`event::Source`]: ./event/trait.Source.html +/// [`Poll`]: struct.Poll.html +/// [`Registry::register`]: struct.Registry.html#method.register +/// [`Registry::reregister`]: struct.Registry.html#method.reregister +/// +/// # Example +/// +/// Using `Token` to track which socket generated the event. In this example, +/// `HashMap` is used, but usually something like [`slab`] is better. +/// +/// [`slab`]: https://crates.io/crates/slab +/// +#[cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")] +#[cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")] +/// # use std::error::Error; +/// # fn main() -> Result<(), Box<dyn Error>> { +/// use mio::{Events, Interest, Poll, 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 mut poll = Poll::new()?; +/// +/// // Tcp listener +/// let mut listener = TcpListener::bind("127.0.0.1:0".parse()?)?; +/// +/// // Register the listener +/// poll.registry().register(&mut listener, LISTENER, Interest::READABLE)?; +/// +/// // 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((mut 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.registry().register(&mut socket, token, Interest::READABLE)?; +/// +/// // 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 +/// } +/// } +/// } +/// } +/// } +/// } +/// # } +/// ``` +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Token(pub usize); + +impl From<Token> for usize { + fn from(val: Token) -> usize { + val.0 + } +} |