mio_poll_wrapper/lib.rs
1#![deny(missing_docs)]
2
3//! Simple wrapper around mio's [Poll](https://docs.rs/mio/latest/mio/struct.Poll.html) method.
4//!
5//! ``` rust
6//! extern crate mio;
7//! extern crate mio_poll_wrapper;
8//!
9//! use mio_poll_wrapper::PollWrapper;
10//! use mio::net::TcpListener;
11//! use std::collections::HashMap;
12//!
13//! fn main() {
14//! let mut handle = PollWrapper::new().unwrap();
15//!
16//! let listener = TcpListener::bind(&"0.0.0.0:8000".parse().unwrap()).unwrap();
17//!
18//! let process_token = handle.register(&listener).unwrap();
19//! let mut clients = HashMap::new();
20//!
21//! let result: ::std::io::Result<()> = handle.handle(|event, handle| {
22//! if event.token() == process_token {
23//! let (stream, addr) = listener.accept()?;
24//! println!("Accepted socket from {:?}", addr);
25//! let token = handle.register(&stream)?;
26//! clients.insert(token, stream);
27//! } else if let Some(client) = clients.get_mut(&event.token()) {
28//! println!("Received data from client {:?}", client.peer_addr());
29//! }
30//! Ok(())
31//! });
32//!
33//! if let Err(e) = result {
34//! println!("Could not execute: {:?}", e);
35//! }
36//! }
37//! ```
38
39extern crate mio;
40
41use mio::{Event, Evented, Events, Poll, PollOpt, Ready, Token};
42
43/// A wrapper around mio's Poll method
44///
45/// You can create this
46pub struct PollWrapper {
47 poll: Poll,
48 tokens: Vec<Token>,
49 next_token_id: usize,
50}
51
52impl PollWrapper {
53 /// Create a new poll wrapper
54 pub fn new() -> ::std::io::Result<PollWrapper> {
55 Ok(PollWrapper {
56 poll: Poll::new()?,
57 tokens: Vec::new(),
58 next_token_id: 0,
59 })
60 }
61
62 /// Start the poll routine. Every time an event gets received, the callback handler gets called.
63 ///
64 /// The first argument of the handler is the event that is received.
65 ///
66 /// The second argument is a handle. See [Handle] for more information.
67 pub fn handle<E>(
68 mut self,
69 mut handler: impl FnMut(Event, &mut Handle) -> Result<(), E>,
70 ) -> Result<(), E> {
71 let mut events = Events::with_capacity(10);
72 loop {
73 self.poll.poll(&mut events, None).unwrap();
74 for event in &events {
75 let mut handle = Handle {
76 poll: &self.poll,
77 tokens: Vec::new(),
78 next_token_id: &mut self.next_token_id,
79 };
80 handler(event, &mut handle)?;
81 for token in handle.tokens {
82 self.tokens.push(token);
83 }
84 }
85 }
86 }
87
88 /// Register an evented with the poll.
89 /// This returns the token that was registered.
90 pub fn register(&mut self, evented: &impl Evented) -> ::std::io::Result<Token> {
91 let token = Token(self.next_token_id);
92 self.next_token_id += 1;
93 self.poll
94 .register(evented, token, Ready::all(), PollOpt::edge())?;
95 self.tokens.push(token);
96 Ok(token)
97 }
98}
99
100/// A handle that gets passed to the callback method of [PollWrapper].
101///
102/// This handle allows you to register evented methods to the poll while the wrapper is running.
103pub struct Handle<'a> {
104 poll: &'a Poll,
105 tokens: Vec<Token>,
106 next_token_id: &'a mut usize,
107}
108
109impl<'a> Handle<'a> {
110 /// Register an evented with the poll.
111 /// This returns the token that was registered.
112 pub fn register(&mut self, evented: &impl Evented) -> ::std::io::Result<Token> {
113 let token = Token(*self.next_token_id);
114 *self.next_token_id += 1;
115 self.poll
116 .register(evented, token, Ready::all(), PollOpt::edge())?;
117 self.tokens.push(token);
118 Ok(token)
119 }
120}