diff --git a/corcovado/README.md b/corcovado/README.md index 85d067b4..6231843d 100644 --- a/corcovado/README.md +++ b/corcovado/README.md @@ -1,3 +1,5 @@ # Corcovado -Corcovado is a maintained fork of mio 0.6.x along mio-signal-hook, mio-extras and using windows calls that works for Windows 11. It also uses Rust edition 2021 instead of 2018. \ No newline at end of file +Corcovado is a maintained fork of mio 0.6.x along mio-signal-hook, mio-extras and using Windows API that works in Windows 11. It uses Rust edition 2021 instead of 2018. + +Corcovado also uses Rust standard library for net and io instead of Mio 0.6.x. \ No newline at end of file diff --git a/corcovado/src/event_imp.rs b/corcovado/src/event_imp.rs index 66bb4462..bc160e47 100644 --- a/corcovado/src/event_imp.rs +++ b/corcovado/src/event_imp.rs @@ -25,101 +25,101 @@ use {Poll, Token}; /// [`Registration`]: ../struct.Registration.html /// [`SetReadiness`]: ../struct.SetReadiness.html /// -/// # Examples -/// -/// Implementing `Evented` on a struct containing a socket: -/// -/// ``` -/// use corcovado::{Ready, Poll, PollOpt, Token}; -/// use corcovado::event::Evented; -/// use corcovado::net::TcpStream; -/// -/// use std::io; -/// -/// pub struct MyEvented { -/// socket: TcpStream, -/// } -/// -/// impl Evented for MyEvented { -/// fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -/// -> io::Result<()> -/// { -/// // Delegate the `register` call to `socket` -/// self.socket.register(poll, token, interest, opts) -/// } -/// -/// fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -/// -> io::Result<()> -/// { -/// // Delegate the `reregister` call to `socket` -/// self.socket.reregister(poll, token, interest, opts) -/// } -/// -/// fn deregister(&self, poll: &Poll) -> io::Result<()> { -/// // Delegate the `deregister` call to `socket` -/// self.socket.deregister(poll) -/// } -/// } -/// ``` -/// -/// Implement `Evented` using [`Registration`] and [`SetReadiness`]. -/// -/// ``` -/// use corcovado::{Ready, Registration, Poll, PollOpt, Token}; -/// use corcovado::event::Evented; -/// -/// use std::io; -/// use std::time::Instant; -/// use std::thread; -/// -/// pub struct Deadline { -/// when: Instant, -/// registration: Registration, -/// } -/// -/// impl Deadline { -/// pub fn new(when: Instant) -> Deadline { -/// let (registration, set_readiness) = Registration::new2(); -/// -/// thread::spawn(move || { -/// let now = Instant::now(); -/// -/// if now < when { -/// thread::sleep(when - now); -/// } -/// -/// set_readiness.set_readiness(Ready::readable()); -/// }); -/// -/// Deadline { -/// when: when, -/// registration: registration, -/// } -/// } -/// -/// pub fn is_elapsed(&self) -> bool { -/// Instant::now() >= self.when -/// } -/// } -/// -/// impl Evented for Deadline { -/// fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -/// -> io::Result<()> -/// { -/// self.registration.register(poll, token, interest, opts) -/// } -/// -/// fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -/// -> io::Result<()> -/// { -/// self.registration.reregister(poll, token, interest, opts) -/// } -/// -/// fn deregister(&self, poll: &Poll) -> io::Result<()> { -/// self.registration.deregister(poll) -/// } -/// } -/// ``` +// # Examples +// +// Implementing `Evented` on a struct containing a socket: +// +// ``` +// use corcovado::{Ready, Poll, PollOpt, Token}; +// use corcovado::event::Evented; +// use std::net::TcpStream; +// +// use std::io; +// +// pub struct MyEvented { +// socket: TcpStream, +// } +// +// impl Evented for MyEvented { +// fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) +// -> io::Result<()> +// { +// // Delegate the `register` call to `socket` +// self.socket.register(poll, token, interest, opts) +// } +// +// fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) +// -> io::Result<()> +// { +// // Delegate the `reregister` call to `socket` +// self.socket.reregister(poll, token, interest, opts) +// } +// +// fn deregister(&self, poll: &Poll) -> io::Result<()> { +// // Delegate the `deregister` call to `socket` +// self.socket.deregister(poll) +// } +// } +// ``` +// +// Implement `Evented` using [`Registration`] and [`SetReadiness`]. +// +// ``` +// use corcovado::{Ready, Registration, Poll, PollOpt, Token}; +// use corcovado::event::Evented; +// +// use std::io; +// use std::time::Instant; +// use std::thread; +// +// pub struct Deadline { +// when: Instant, +// registration: Registration, +// } +// +// impl Deadline { +// pub fn new(when: Instant) -> Deadline { +// let (registration, set_readiness) = Registration::new2(); +// +// thread::spawn(move || { +// let now = Instant::now(); +// +// if now < when { +// thread::sleep(when - now); +// } +// +// set_readiness.set_readiness(Ready::readable()); +// }); +// +// Deadline { +// when: when, +// registration: registration, +// } +// } +// +// pub fn is_elapsed(&self) -> bool { +// Instant::now() >= self.when +// } +// } +// +// impl Evented for Deadline { +// fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) +// -> io::Result<()> +// { +// self.registration.register(poll, token, interest, opts) +// } +// +// fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) +// -> io::Result<()> +// { +// self.registration.reregister(poll, token, interest, opts) +// } +// +// fn deregister(&self, poll: &Poll) -> io::Result<()> { +// self.registration.deregister(poll) +// } +// } +// ``` pub trait Evented { /// Register `self` with the given `Poll` instance. /// diff --git a/corcovado/src/lib.rs b/corcovado/src/lib.rs index 9ab9d355..c6c1f8d3 100644 --- a/corcovado/src/lib.rs +++ b/corcovado/src/lib.rs @@ -42,60 +42,60 @@ //! [`Poll`]: struct.Poll.html //! [`Events`]: struct.Events.html //! -//! # Example -//! -//! ``` -//! use corcovado::*; -//! use corcovado::net::{TcpListener, TcpStream}; -//! -//! // Setup some tokens to allow us to identify which event is -//! // for which socket. -//! const SERVER: Token = Token(0); -//! const CLIENT: Token = Token(1); -//! -//! let addr = "127.0.0.1:13265".parse().unwrap(); -//! -//! // Setup the server socket -//! let server = TcpListener::bind(&addr).unwrap(); -//! -//! // Create a poll instance -//! let poll = Poll::new().unwrap(); -//! -//! // Start listening for incoming connections -//! poll.register(&server, SERVER, Ready::readable(), -//! PollOpt::edge()).unwrap(); -//! -//! // Setup the client socket -//! let sock = TcpStream::connect(&addr).unwrap(); -//! -//! // Register the socket -//! poll.register(&sock, CLIENT, Ready::readable(), -//! PollOpt::edge()).unwrap(); -//! -//! // Create storage for events -//! let mut events = Events::with_capacity(1024); -//! -//! loop { -//! poll.poll(&mut events, None).unwrap(); -//! -//! for event in events.iter() { -//! match event.token() { -//! SERVER => { -//! // Accept and drop the socket immediately, this will close -//! // the socket and notify the client of the EOF. -//! let _ = server.accept(); -//! } -//! CLIENT => { -//! // The server just shuts down the socket, let's just exit -//! // from our event loop. -//! return; -//! } -//! _ => unreachable!(), -//! } -//! } -//! } -//! -//! ``` +// # Example +// +// ``` +// use corcovado::*; +// use std::net::{TcpListener, TcpStream}; +// +// // Setup some tokens to allow us to identify which event is +// // for which socket. +// const SERVER: Token = Token(0); +// const CLIENT: Token = Token(1); +// +// let addr = "127.0.0.1:13265".parse().unwrap(); +// +// // Setup the server socket +// let server = TcpListener::bind(&addr).unwrap(); +// +// // Create a poll instance +// let poll = Poll::new().unwrap(); +// +// // Start listening for incoming connections +// poll.register(&server, SERVER, Ready::readable(), +// PollOpt::edge()).unwrap(); +// +// // Setup the client socket +// let sock = TcpStream::connect(&addr).unwrap(); +// +// // Register the socket +// poll.register(&sock, CLIENT, Ready::readable(), +// PollOpt::edge()).unwrap(); +// +// // Create storage for events +// let mut events = Events::with_capacity(1024); +// +// loop { +// poll.poll(&mut events, None).unwrap(); +// +// for event in events.iter() { +// match event.token() { +// SERVER => { +// // Accept and drop the socket immediately, this will close +// // the socket and notify the client of the EOF. +// let _ = server.accept(); +// } +// CLIENT => { +// // The server just shuts down the socket, let's just exit +// // from our event loop. +// return; +// } +// _ => unreachable!(), +// } +// } +// } +// +// ``` extern crate iovec; extern crate net2; diff --git a/corcovado/src/poll.rs b/corcovado/src/poll.rs index b7df961e..a61f0d4e 100644 --- a/corcovado/src/poll.rs +++ b/corcovado/src/poll.rs @@ -82,52 +82,51 @@ use {sys, Token}; /// [`write`]: tcp/struct.TcpStream.html#method.write /// [`register`]: #method.register /// -/// # Examples -/// -/// A basic example -- establishing a `TcpStream` connection. -/// -/// ``` -/// # use std::error::Error; -/// # fn try_main() -> Result<(), Box> { -/// use corcovado::{Events, Poll, Ready, PollOpt, Token}; -/// use corcovado::net::TcpStream; -/// -/// use std::net::{TcpListener, SocketAddr}; -/// -/// // Bind a server socket to connect to. -/// let addr: SocketAddr = "127.0.0.1:0".parse()?; -/// let server = TcpListener::bind(&addr)?; -/// -/// // Construct a new `Poll` handle as well as the `Events` we'll store into -/// let poll = Poll::new()?; -/// let mut events = Events::with_capacity(1024); -/// -/// // Connect the stream -/// let stream = TcpStream::connect(&server.local_addr()?)?; -/// -/// // Register the stream with `Poll` -/// poll.register(&stream, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge())?; -/// -/// // Wait for the socket to become ready. This has to happens in a loop to -/// // handle spurious wakeups. -/// loop { -/// poll.poll(&mut events, None)?; -/// -/// for event in &events { -/// if event.token() == Token(0) && event.readiness().is_writable() { -/// // The socket connected (probably, it could still be a spurious -/// // wakeup) -/// return Ok(()); -/// } -/// } -/// } -/// # Ok(()) -/// # } -/// # -/// # fn main() { -/// # try_main().unwrap(); -/// # } -/// ``` +// # Examples +// +// A basic example -- establishing a `TcpStream` connection. +// +// ``` +// # use std::error::Error; +// # fn try_main() -> Result<(), Box> { +// use corcovado::{Events, Poll, Ready, PollOpt, Token}; +// +// use std::net::{TcpStream, TcpListener, SocketAddr}; +// +// // Bind a server socket to connect to. +// let addr: SocketAddr = "127.0.0.1:0".parse()?; +// let server = TcpListener::bind(&addr)?; +// +// // Construct a new `Poll` handle as well as the `Events` we'll store into +// let poll = Poll::new()?; +// let mut events = Events::with_capacity(1024); +// +// // Connect the stream +// let stream = TcpStream::connect(&server.local_addr()?)?; +// +// // Register the stream with `Poll` +// poll.register(&stream, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge())?; +// +// // Wait for the socket to become ready. This has to happens in a loop to +// // handle spurious wakeups. +// loop { +// poll.poll(&mut events, None)?; +// +// for event in &events { +// if event.token() == Token(0) && event.readiness().is_writable() { +// // The socket connected (probably, it could still be a spurious +// // wakeup) +// return Ok(()); +// } +// } +// } +// # Ok(()) +// # } +// # +// # fn main() { +// # try_main().unwrap(); +// # } +// ``` /// /// # Edge-triggered and level-triggered /// @@ -263,30 +262,30 @@ use {sys, Token}; /// /// For example: /// -/// ``` -/// # use std::error::Error; -/// # fn try_main() -> Result<(), Box> { -/// use corcovado::{Poll, Ready, PollOpt, Token}; -/// use corcovado::net::TcpStream; -/// use std::time::Duration; -/// use std::thread; -/// -/// let sock = TcpStream::connect(&"216.58.193.100:80".parse()?)?; -/// -/// thread::sleep(Duration::from_secs(1)); -/// -/// let poll = Poll::new()?; -/// -/// // The connect is not guaranteed to have started until it is registered at -/// // this point -/// poll.register(&sock, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge())?; -/// # Ok(()) -/// # } -/// # -/// # fn main() { -/// # try_main().unwrap(); -/// # } -/// ``` +// ``` +// # use std::error::Error; +// # fn try_main() -> Result<(), Box> { +// use corcovado::{Poll, Ready, PollOpt, Token}; +// use std::net::TcpStream; +// use std::time::Duration; +// use std::thread; +// +// let sock = TcpStream::connect(&"216.58.193.100:80".parse()?)?; +// +// thread::sleep(Duration::from_secs(1)); +// +// let poll = Poll::new()?; +// +// // The connect is not guaranteed to have started until it is registered at +// // this point +// poll.register(&sock, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge())?; +// # Ok(()) +// # } +// # +// # fn main() { +// # try_main().unwrap(); +// # } +// ``` /// /// # Implementation notes /// @@ -734,50 +733,50 @@ impl Poll { /// [`oneshot`]: struct.PollOpt.html#method.oneshot /// [`Token`]: struct.Token.html /// - /// # Examples - /// - /// ``` - /// # use std::error::Error; - /// # fn try_main() -> Result<(), Box> { - /// use corcovado::{Events, Poll, Ready, PollOpt, Token}; - /// use corcovado::net::TcpStream; - /// use std::time::{Duration, Instant}; - /// - /// let poll = Poll::new()?; - /// let socket = TcpStream::connect(&"216.58.193.100:80".parse()?)?; - /// - /// // Register the socket with `poll` - /// poll.register(&socket, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge())?; - /// - /// let mut events = Events::with_capacity(1024); - /// let start = Instant::now(); - /// let timeout = Duration::from_millis(500); - /// - /// loop { - /// let elapsed = start.elapsed(); - /// - /// if elapsed >= timeout { - /// // Connection timed out - /// return Ok(()); - /// } - /// - /// let remaining = timeout - elapsed; - /// poll.poll(&mut events, Some(remaining))?; - /// - /// for event in &events { - /// if event.token() == Token(0) { - /// // Something (probably) happened on the socket. - /// return Ok(()); - /// } - /// } - /// } - /// # Ok(()) - /// # } - /// # - /// # fn main() { - /// # try_main().unwrap(); - /// # } - /// ``` + // # Examples + // + // ``` + // # use std::error::Error; + // # fn try_main() -> Result<(), Box> { + // use corcovado::{Events, Poll, Ready, PollOpt, Token}; + // use std::net::TcpStream; + // use std::time::{Duration, Instant}; + // + // let poll = Poll::new()?; + // let socket = TcpStream::connect(&"216.58.193.100:80".parse()?)?; + // + // // Register the socket with `poll` + // poll.register(&socket, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge())?; + // + // let mut events = Events::with_capacity(1024); + // let start = Instant::now(); + // let timeout = Duration::from_millis(500); + // + // loop { + // let elapsed = start.elapsed(); + // + // if elapsed >= timeout { + // // Connection timed out + // return Ok(()); + // } + // + // let remaining = timeout - elapsed; + // poll.poll(&mut events, Some(remaining))?; + // + // for event in &events { + // if event.token() == Token(0) { + // // Something (probably) happened on the socket. + // return Ok(()); + // } + // } + // } + // # Ok(()) + // # } + // # + // # fn main() { + // # try_main().unwrap(); + // # } + // ``` pub fn register( &self, handle: &E, @@ -826,36 +825,36 @@ impl Poll { /// arguments and see the [`struct`] docs for a high level overview of /// polling. /// - /// # Examples - /// - /// ``` - /// # use std::error::Error; - /// # fn try_main() -> Result<(), Box> { - /// use corcovado::{Poll, Ready, PollOpt, Token}; - /// use corcovado::net::TcpStream; - /// - /// let poll = Poll::new()?; - /// let socket = TcpStream::connect(&"216.58.193.100:80".parse()?)?; - /// - /// // Register the socket with `poll`, requesting readable - /// poll.register(&socket, Token(0), Ready::readable(), PollOpt::edge())?; - /// - /// // Reregister the socket specifying a different token and write interest - /// // instead. `PollOpt::edge()` must be specified even though that value - /// // is not being changed. - /// poll.reregister(&socket, Token(2), Ready::writable(), PollOpt::edge())?; - /// # Ok(()) - /// # } - /// # - /// # fn main() { - /// # try_main().unwrap(); - /// # } - /// ``` - /// - /// [`struct`]: # - /// [`register`]: #method.register - /// [`readable`]: struct.Ready.html#method.readable - /// [`writable`]: struct.Ready.html#method.writable + // # Examples + // + // ``` + // # use std::error::Error; + // # fn try_main() -> Result<(), Box> { + // use corcovado::{Poll, Ready, PollOpt, Token}; + // use std::net::TcpStream; + // + // let poll = Poll::new()?; + // let socket = TcpStream::connect(&"216.58.193.100:80".parse()?)?; + // + // // Register the socket with `poll`, requesting readable + // poll.register(&socket, Token(0), Ready::readable(), PollOpt::edge())?; + // + // // Reregister the socket specifying a different token and write interest + // // instead. `PollOpt::edge()` must be specified even though that value + // // is not being changed. + // poll.reregister(&socket, Token(2), Ready::writable(), PollOpt::edge())?; + // # Ok(()) + // # } + // # + // # fn main() { + // # try_main().unwrap(); + // # } + // ``` + // + // [`struct`]: # + // [`register`]: #method.register + // [`readable`]: struct.Ready.html#method.readable + // [`writable`]: struct.Ready.html#method.writable pub fn reregister( &self, handle: &E, @@ -890,35 +889,35 @@ impl Poll { /// `Evented` handles are automatically deregistered when they are dropped. /// It is common to never need to explicitly call `deregister`. /// - /// # Examples - /// - /// ``` - /// # use std::error::Error; - /// # fn try_main() -> Result<(), Box> { - /// use corcovado::{Events, Poll, Ready, PollOpt, Token}; - /// use corcovado::net::TcpStream; - /// use std::time::Duration; - /// - /// let poll = Poll::new()?; - /// let socket = TcpStream::connect(&"216.58.193.100:80".parse()?)?; - /// - /// // Register the socket with `poll` - /// poll.register(&socket, Token(0), Ready::readable(), PollOpt::edge())?; - /// - /// poll.deregister(&socket)?; - /// - /// let mut events = Events::with_capacity(1024); - /// - /// // Set a timeout because this poll should never receive any events. - /// let n = poll.poll(&mut events, Some(Duration::from_secs(1)))?; - /// assert_eq!(0, n); - /// # Ok(()) - /// # } - /// # - /// # fn main() { - /// # try_main().unwrap(); - /// # } - /// ``` + // # Examples + // + // ``` + // # use std::error::Error; + // # fn try_main() -> Result<(), Box> { + // use corcovado::{Events, Poll, Ready, PollOpt, Token}; + // use std::net::TcpStream; + // use std::time::Duration; + // + // let poll = Poll::new()?; + // let socket = TcpStream::connect(&"216.58.193.100:80".parse()?)?; + // + // // Register the socket with `poll` + // poll.register(&socket, Token(0), Ready::readable(), PollOpt::edge())?; + // + // poll.deregister(&socket)?; + // + // let mut events = Events::with_capacity(1024); + // + // // Set a timeout because this poll should never receive any events. + // let n = poll.poll(&mut events, Some(Duration::from_secs(1)))?; + // assert_eq!(0, n); + // # Ok(()) + // # } + // # + // # fn main() { + // # try_main().unwrap(); + // # } + // ``` pub fn deregister(&self, handle: &E) -> io::Result<()> where E: Evented, @@ -970,59 +969,58 @@ impl Poll { /// [struct]: # /// [`iter`]: struct.Events.html#method.iter /// - /// # Examples - /// - /// A basic example -- establishing a `TcpStream` connection. - /// - /// ``` - /// # use std::error::Error; - /// # fn try_main() -> Result<(), Box> { - /// use corcovado::{Events, Poll, Ready, PollOpt, Token}; - /// use corcovado::net::TcpStream; - /// - /// use std::net::{TcpListener, SocketAddr}; - /// use std::thread; - /// - /// // Bind a server socket to connect to. - /// let addr: SocketAddr = "127.0.0.1:0".parse()?; - /// let server = TcpListener::bind(&addr)?; - /// let addr = server.local_addr()?.clone(); - /// - /// // Spawn a thread to accept the socket - /// thread::spawn(move || { - /// let _ = server.accept(); - /// }); - /// - /// // Construct a new `Poll` handle as well as the `Events` we'll store into - /// let poll = Poll::new()?; - /// let mut events = Events::with_capacity(1024); - /// - /// // Connect the stream - /// let stream = TcpStream::connect(&addr)?; - /// - /// // Register the stream with `Poll` - /// poll.register(&stream, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge())?; - /// - /// // Wait for the socket to become ready. This has to happens in a loop to - /// // handle spurious wakeups. - /// loop { - /// poll.poll(&mut events, None)?; - /// - /// for event in &events { - /// if event.token() == Token(0) && event.readiness().is_writable() { - /// // The socket connected (probably, it could still be a spurious - /// // wakeup) - /// return Ok(()); - /// } - /// } - /// } - /// # Ok(()) - /// # } - /// # - /// # fn main() { - /// # try_main().unwrap(); - /// # } - /// ``` + // # Examples + // + // A basic example -- establishing a `TcpStream` connection. + // + // ``` + // # use std::error::Error; + // # fn try_main() -> Result<(), Box> { + // use corcovado::{Events, Poll, Ready, PollOpt, Token}; + // + // use std::net::{TcpStream, TcpListener, SocketAddr}; + // use std::thread; + // + // // Bind a server socket to connect to. + // let addr: SocketAddr = "127.0.0.1:0".parse()?; + // let server = TcpListener::bind(&addr)?; + // let addr = server.local_addr()?.clone(); + // + // // Spawn a thread to accept the socket + // thread::spawn(move || { + // let _ = server.accept(); + // }); + // + // // Construct a new `Poll` handle as well as the `Events` we'll store into + // let poll = Poll::new()?; + // let mut events = Events::with_capacity(1024); + // + // // Connect the stream + // let stream = TcpStream::connect(&addr)?; + // + // // Register the stream with `Poll` + // poll.register(&stream, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge())?; + // + // // Wait for the socket to become ready. This has to happens in a loop to + // // handle spurious wakeups. + // loop { + // poll.poll(&mut events, None)?; + // + // for event in &events { + // if event.token() == Token(0) && event.readiness().is_writable() { + // // The socket connected (probably, it could still be a spurious + // // wakeup) + // return Ok(()); + // } + // } + // } + // # Ok(()) + // # } + // # + // # fn main() { + // # try_main().unwrap(); + // # } + // ``` /// /// [struct]: # pub fn poll( diff --git a/corcovado/src/sys/unix/ready.rs b/corcovado/src/sys/unix/ready.rs index a9a09d0d..586f67c6 100644 --- a/corcovado/src/sys/unix/ready.rs +++ b/corcovado/src/sys/unix/ready.rs @@ -61,32 +61,32 @@ use std::ops; /// assert!(ready.is_readable()); /// ``` /// -/// Registering readable and error interest on a socket -/// -/// ``` -/// # use std::error::Error; -/// # fn try_main() -> Result<(), Box> { -/// use corcovado::{Ready, Poll, PollOpt, Token}; -/// use corcovado::net::TcpStream; -/// use corcovado::unix::UnixReady; -/// -/// let addr = "216.58.193.68:80".parse()?; -/// let socket = TcpStream::connect(&addr)?; -/// -/// let poll = Poll::new()?; -/// -/// poll.register(&socket, -/// Token(0), -/// Ready::readable() | UnixReady::error(), -/// PollOpt::edge())?; -/// # Ok(()) -/// # } -/// # -/// # fn main() { -/// # try_main().unwrap(); -/// # } -/// ``` -/// +// Registering readable and error interest on a socket +// +// ``` +// # use std::error::Error; +// # fn try_main() -> Result<(), Box> { +// use corcovado::{Ready, Poll, PollOpt, Token}; +// use std::net::TcpStream; +// use corcovado::unix::UnixReady; +// +// let addr = "216.58.193.68:80".parse()?; +// let socket = TcpStream::connect(&addr)?; +// +// let poll = Poll::new()?; +// +// poll.register(&socket, +// Token(0), +// Ready::readable() | UnixReady::error(), +// PollOpt::edge())?; +// # Ok(()) +// # } +// # +// # fn main() { +// # try_main().unwrap(); +// # } +// ``` +// /// [`Poll`]: ../struct.Poll.html /// [readiness]: struct.Poll.html#readiness-operations #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)] diff --git a/corcovado/src/token.rs b/corcovado/src/token.rs index 2095b940..6dd55875 100644 --- a/corcovado/src/token.rs +++ b/corcovado/src/token.rs @@ -1,137 +1,138 @@ -/// Associates readiness notifications with [`Evented`] handles. -/// -/// `Token` is a wrapper around `usize` and is used as an argument to -/// [`Poll::register`] and [`Poll::reregister`]. -/// -/// See [`Poll`] for more documentation on polling. -/// -/// # Example -/// -/// Using `Token` to track which socket generated the notification. In this -/// example, `HashMap` is used, but usually something like [`slab`] is better. -/// -/// ``` -/// # use std::error::Error; -/// # fn try_main() -> Result<(), Box> { -/// use corcovado::{Events, Ready, Poll, PollOpt, Token}; -/// use corcovado::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 poll = Poll::new()?; -/// -/// // Tcp listener -/// let listener = TcpListener::bind(&"127.0.0.1:0".parse()?)?; -/// -/// // Register the listener -/// poll.register(&listener, -/// LISTENER, -/// Ready::readable(), -/// PollOpt::edge())?; -/// -/// // 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((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.register(&socket, -/// token, -/// Ready::readable(), -/// PollOpt::edge())?; -/// -/// // 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 -/// } -/// } -/// } -/// } -/// } -/// } -/// # Ok(()) -/// # } -/// # -/// # fn main() { -/// # try_main().unwrap(); -/// # } -/// ``` -/// +// TODO: replace "//" with "///" and fix TcpListener with Evented +// Associates readiness notifications with [`Evented`] handles. +// +// `Token` is a wrapper around `usize` and is used as an argument to +// [`Poll::register`] and [`Poll::reregister`]. +// +// See [`Poll`] for more documentation on polling. +// +// # Example +// +// Using `Token` to track which socket generated the notification. In this +// example, `HashMap` is used, but usually something like [`slab`] is better. +// +// ``` +// # use std::error::Error; +// # fn try_main() -> Result<(), Box> { +// use urca::{Events, Ready, Poll, PollOpt, Token}; +// use urca::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 poll = Poll::new()?; +// +// // Tcp listener +// let listener = TcpListener::bind(&"127.0.0.1:0".parse()?)?; +// +// // Register the listener +// poll.register(&listener, +// LISTENER, +// Ready::readable(), +// PollOpt::edge())?; +// +// // 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((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.register(&socket, +// token, +// Ready::readable(), +// PollOpt::edge())?; +// +// // 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 +// } +// } +// } +// } +// } +// } +// # Ok(()) +// # } +// # +// # fn main() { +// # try_main().unwrap(); +// # } +// ``` +// /// [`Evented`]: event/trait.Evented.html /// [`Poll`]: struct.Poll.html /// [`Poll::register`]: struct.Poll.html#method.register