diff --git a/src/iocp/mod.rs b/src/iocp/mod.rs index cdf6d6e..d27d252 100644 --- a/src/iocp/mod.rs +++ b/src/iocp/mod.rs @@ -781,8 +781,9 @@ impl PacketUnwrapped { // If there was a change, indicate that we need an update. match socket.status { SocketStatus::Polling { flags } => { - let our_flags = event_to_afd_mask(interest.readable, interest.writable, true) - | interest.extra.flags; + let our_flags = + event_to_afd_mask(interest.readable, interest.writable, true) + | interest.extra.flags; our_flags != flags } @@ -799,7 +800,7 @@ impl PacketUnwrapped { // Update if there is no ongoing wait. handle.status.is_idle() } - _ => true + _ => true, } } diff --git a/src/lib.rs b/src/lib.rs index bd748ce..7674118 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ //! # Examples //! //! ```no_run -//! use polling::{Event, Poller}; +//! use polling::{Event, Events, Poller}; //! use std::net::TcpListener; //! //! // Create a TCP listener. @@ -33,13 +33,13 @@ //! } //! //! // The event loop. -//! let mut events = Vec::new(); +//! let mut events = Events::new(); //! loop { //! // Wait for at least one I/O event. //! events.clear(); //! poller.wait(&mut events, None)?; //! -//! for ev in &events { +//! for ev in events.iter() { //! if ev.key == key { //! // Perform a non-blocking accept operation. //! socket.accept()?; @@ -603,7 +603,7 @@ impl Poller { /// # Examples /// /// ``` - /// use polling::{Event, Poller}; + /// use polling::{Event, Events, Poller}; /// use std::net::TcpListener; /// use std::time::Duration; /// @@ -616,7 +616,7 @@ impl Poller { /// poller.add(&socket, Event::all(key))?; /// } /// - /// let mut events = Vec::new(); + /// let mut events = Events::new(); /// let n = poller.wait(&mut events, Some(Duration::from_secs(1)))?; /// poller.delete(&socket)?; /// # std::io::Result::Ok(()) @@ -650,14 +650,14 @@ impl Poller { /// # Examples /// /// ``` - /// use polling::Poller; + /// use polling::{Events, Poller}; /// /// let poller = Poller::new()?; /// /// // Notify the poller. /// poller.notify()?; /// - /// let mut events = Vec::new(); + /// let mut events = Events::new(); /// poller.wait(&mut events, None)?; // wakes up immediately /// assert!(events.is_empty()); /// # std::io::Result::Ok(()) @@ -804,7 +804,7 @@ impl Events { /// ``` #[inline] pub fn is_empty(&self) -> bool { - self.len() != 0 + self.len() == 0 } /// Get the total capacity of the list. diff --git a/src/os/iocp.rs b/src/os/iocp.rs index 625606c..bc37843 100644 --- a/src/os/iocp.rs +++ b/src/os/iocp.rs @@ -19,7 +19,7 @@ pub trait PollerIocpExt: PollerSealed { /// # Examples /// /// ```rust - /// use polling::{Poller, Event}; + /// use polling::{Poller, Event, Events}; /// use polling::os::iocp::{CompletionPacket, PollerIocpExt}; /// /// use std::thread; @@ -39,7 +39,7 @@ pub trait PollerIocpExt: PollerSealed { /// }); /// /// // Wait for the event. - /// let mut events = vec![]; + /// let mut events = Events::new(); /// poller.wait(&mut events, None)?; /// /// assert_eq!(events.len(), 1); @@ -72,7 +72,7 @@ pub trait PollerIocpExt: PollerSealed { /// # Examples /// /// ```no_run - /// use polling::{Poller, Event, PollMode}; + /// use polling::{Poller, Event, Events, PollMode}; /// use polling::os::iocp::PollerIocpExt; /// /// use std::process::Command; @@ -92,11 +92,11 @@ pub trait PollerIocpExt: PollerSealed { /// } /// /// // Wait for the child process to exit. - /// let mut events = vec![]; + /// let mut events = Events::new(); /// poller.wait(&mut events, None).unwrap(); /// /// assert_eq!(events.len(), 1); - /// assert_eq!(events[0], Event::all(0)); + /// assert_eq!(events.iter().next().unwrap(), Event::all(0)); /// ``` unsafe fn add_waitable( &self, @@ -115,7 +115,7 @@ pub trait PollerIocpExt: PollerSealed { /// # Examples /// /// ```no_run - /// use polling::{Poller, Event, PollMode}; + /// use polling::{Poller, Event, Events, PollMode}; /// use polling::os::iocp::PollerIocpExt; /// /// use std::process::Command; @@ -135,11 +135,11 @@ pub trait PollerIocpExt: PollerSealed { /// } /// /// // Wait for the child process to exit. - /// let mut events = vec![]; + /// let mut events = Events::new(); /// poller.wait(&mut events, None).unwrap(); /// /// assert_eq!(events.len(), 1); - /// assert_eq!(events[0], Event::all(0)); + /// assert_eq!(events.iter().next().unwrap(), Event::all(0)); /// /// // Modify the waitable handle. /// poller.modify_waitable(&child, Event::readable(0), PollMode::Oneshot).unwrap(); @@ -161,7 +161,7 @@ pub trait PollerIocpExt: PollerSealed { /// # Examples /// /// ```no_run - /// use polling::{Poller, Event, PollMode}; + /// use polling::{Poller, Event, Events, PollMode}; /// use polling::os::iocp::PollerIocpExt; /// /// use std::process::Command; @@ -181,11 +181,11 @@ pub trait PollerIocpExt: PollerSealed { /// } /// /// // Wait for the child process to exit. - /// let mut events = vec![]; + /// let mut events = Events::new(); /// poller.wait(&mut events, None).unwrap(); /// /// assert_eq!(events.len(), 1); - /// assert_eq!(events[0], Event::all(0)); + /// assert_eq!(events.iter().next().unwrap(), Event::all(0)); /// /// // Remove the waitable handle. /// poller.remove_waitable(&child).unwrap(); diff --git a/src/os/kqueue.rs b/src/os/kqueue.rs index 684bd3e..c3db033 100644 --- a/src/os/kqueue.rs +++ b/src/os/kqueue.rs @@ -31,7 +31,7 @@ pub trait PollerKqueueExt: PollerSealed { /// # Examples /// /// ```no_run - /// use polling::{Poller, PollMode}; + /// use polling::{Events, Poller, PollMode}; /// use polling::os::kqueue::{Filter, PollerKqueueExt, Signal}; /// /// let poller = Poller::new().unwrap(); @@ -40,7 +40,7 @@ pub trait PollerKqueueExt: PollerSealed { /// poller.add_filter(Signal(libc::SIGINT), 0, PollMode::Oneshot).unwrap(); /// /// // Wait for the signal. - /// let mut events = vec![]; + /// let mut events = Events::new(); /// poller.wait(&mut events, None).unwrap(); /// # let _ = events; /// ``` @@ -54,7 +54,7 @@ pub trait PollerKqueueExt: PollerSealed { /// # Examples /// /// ```no_run - /// use polling::{Poller, PollMode}; + /// use polling::{Events, Poller, PollMode}; /// use polling::os::kqueue::{Filter, PollerKqueueExt, Signal}; /// /// let poller = Poller::new().unwrap(); @@ -66,7 +66,7 @@ pub trait PollerKqueueExt: PollerSealed { /// poller.modify_filter(Signal(libc::SIGINT), 1, PollMode::Oneshot).unwrap(); /// /// // Wait for the signal. - /// let mut events = vec![]; + /// let mut events = Events::new(); /// poller.wait(&mut events, None).unwrap(); /// # let _ = events; /// ``` @@ -183,7 +183,12 @@ pub enum ProcessOps { impl<'a> Process<'a> { /// Monitor a child process. - pub fn new(child: &'a Child, ops: ProcessOps) -> Self { + /// + /// # Safety + /// + /// Once registered into the `Poller`, the `Child` object must outlive this filter's + /// registration into the poller. + pub unsafe fn new(child: &'a Child, ops: ProcessOps) -> Self { Self { child, ops } } } diff --git a/tests/concurrent_modification.rs b/tests/concurrent_modification.rs index ff00ddb..b0333b2 100644 --- a/tests/concurrent_modification.rs +++ b/tests/concurrent_modification.rs @@ -33,7 +33,9 @@ fn concurrent_add() -> io::Result<()> { poller.delete(&reader)?; result?; - assert_eq!(events.iter().collect::>(), [Event::readable(0)]); + assert_eq!(events.len(), 1); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); Ok(()) } @@ -63,7 +65,9 @@ fn concurrent_modify() -> io::Result<()> { .into_iter() .collect::>()?; - assert_eq!(events.iter().collect::>(), [Event::readable(0)]); + assert_eq!(events.len(), 1); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); Ok(()) } diff --git a/tests/io.rs b/tests/io.rs index 965e477..404f389 100644 --- a/tests/io.rs +++ b/tests/io.rs @@ -29,7 +29,10 @@ fn basic_io() { .unwrap(), 1 ); - assert_eq!(events.iter().collect::>(), &[Event::readable(1)]); + + assert_eq!(events.len(), 1); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); poller.delete(&read).unwrap(); } diff --git a/tests/other_modes.rs b/tests/other_modes.rs index 863ed36..e0d8cf2 100644 --- a/tests/other_modes.rs +++ b/tests/other_modes.rs @@ -39,10 +39,10 @@ fn level_triggered() { .wait(&mut events, Some(Duration::from_secs(10))) .unwrap(); - assert_eq!( - events.iter().collect::>(), - [Event::readable(reader_token)] - ); + assert_eq!(events.len(), 1); + assert_eq!(events.iter().next().unwrap().key, reader_token); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); // If we read some of the data, the notification should still be available. reader.read_exact(&mut [0; 3]).unwrap(); @@ -50,10 +50,11 @@ fn level_triggered() { poller .wait(&mut events, Some(Duration::from_secs(10))) .unwrap(); - assert_eq!( - events.iter().collect::>(), - [Event::readable(reader_token)] - ); + + assert_eq!(events.len(), 1); + assert_eq!(events.iter().next().unwrap().key, reader_token); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); // If we read the rest of the data, the notification should be gone. reader.read_exact(&mut [0; 2]).unwrap(); @@ -77,10 +78,10 @@ fn level_triggered() { .wait(&mut events, Some(Duration::from_secs(10))) .unwrap(); - assert_eq!( - events.iter().collect::>(), - [Event::readable(reader_token)] - ); + assert_eq!(events.len(), 1); + assert_eq!(events.iter().next().unwrap().key, reader_token); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); // After reading, the notification should vanish. reader.read(&mut [0; 5]).unwrap(); @@ -137,10 +138,10 @@ fn edge_triggered() { .wait(&mut events, Some(Duration::from_secs(10))) .unwrap(); - assert_eq!( - events.iter().collect::>(), - [Event::readable(reader_token)] - ); + assert_eq!(events.len(), 1); + assert_eq!(events.iter().next().unwrap().key, reader_token); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); // If we read some of the data, the notification should not still be available. reader.read_exact(&mut [0; 3]).unwrap(); @@ -156,10 +157,11 @@ fn edge_triggered() { poller .wait(&mut events, Some(Duration::from_secs(10))) .unwrap(); - assert_eq!( - events.iter().collect::>(), - [Event::readable(reader_token)] - ); + + assert_eq!(events.len(), 1); + assert_eq!(events.iter().next().unwrap().key, reader_token); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); // After modifying the stream and sending more data, it should be oneshot. poller @@ -172,10 +174,10 @@ fn edge_triggered() { .wait(&mut events, Some(Duration::from_secs(10))) .unwrap(); - assert_eq!( - events.iter().collect::>(), - [Event::readable(reader_token)] - ); + assert_eq!(events.len(), 1); + assert_eq!(events.iter().next().unwrap().key, reader_token); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); } #[test] @@ -229,10 +231,9 @@ fn edge_oneshot_triggered() { .wait(&mut events, Some(Duration::from_secs(10))) .unwrap(); - assert_eq!( - events.iter().collect::>(), - [Event::readable(reader_token)] - ); + assert_eq!(events.len(), 1); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); // If we read some of the data, the notification should not still be available. reader.read_exact(&mut [0; 3]).unwrap(); @@ -254,10 +255,10 @@ fn edge_oneshot_triggered() { poller .wait(&mut events, Some(Duration::from_secs(0))) .unwrap(); - assert_eq!( - events.iter().collect::>(), - [Event::readable(reader_token)] - ); + + assert_eq!(events.len(), 1); + assert!(events.iter().next().unwrap().readable); + assert!(!events.iter().next().unwrap().writable); } fn tcp_pair() -> io::Result<(TcpStream, TcpStream)> { diff --git a/tests/windows_post.rs b/tests/windows_post.rs index 425b09c..c0bef9f 100644 --- a/tests/windows_post.rs +++ b/tests/windows_post.rs @@ -47,7 +47,10 @@ fn post_multithread() { .unwrap(); assert_eq!(events.len(), 1); - assert_eq!(events.iter().next(), Some(Event::writable(i))); + assert_eq!(events.iter().next().unwrap().key, i); + assert!(!events.iter().next().unwrap().readable); + assert!(events.iter().next().unwrap().writable); + events.clear(); } poller diff --git a/tests/windows_waitable.rs b/tests/windows_waitable.rs index bd17a72..fd05983 100644 --- a/tests/windows_waitable.rs +++ b/tests/windows_waitable.rs @@ -3,7 +3,7 @@ #![cfg(windows)] use polling::os::iocp::PollerIocpExt; -use polling::{Event, PollMode, Poller}; +use polling::{Event, Events, PollMode, Poller}; use windows_sys::Win32::Foundation::CloseHandle; use windows_sys::Win32::System::Threading::{CreateEventW, ResetEvent, SetEvent}; @@ -85,7 +85,7 @@ fn smoke() { .unwrap(); } - let mut events = vec![]; + let mut events = Events::new(); poller .wait(&mut events, Some(Duration::from_millis(100))) .unwrap(); @@ -100,7 +100,8 @@ fn smoke() { .unwrap(); assert_eq!(events.len(), 1); - assert_eq!(events[0], Event::all(0)); + assert!(events.iter().next().unwrap().readable); + assert!(events.iter().next().unwrap().writable); // Interest should be cleared. events.clear(); @@ -121,7 +122,8 @@ fn smoke() { .unwrap(); assert_eq!(events.len(), 1); - assert_eq!(events[0], Event::all(0)); + assert!(events.iter().next().unwrap().readable); + assert!(events.iter().next().unwrap().writable); // If we reset the event, it should not be signaled. event.reset().unwrap();