From 808428d5bd0511f8b3692fba8bdc9fdd16d54f87 Mon Sep 17 00:00:00 2001 From: irving ou Date: Thu, 25 Jan 2024 13:56:36 -0500 Subject: [PATCH] adding support if connect failed --- examples/tcp_client.rs | 11 +++++++---- src/epoll.rs | 5 +++++ src/iocp/mod.rs | 5 +++++ src/kqueue.rs | 8 +++++++- src/lib.rs | 43 ++++++++++++++++++++++++++++++++++++++++++ src/poll.rs | 5 +++++ src/port.rs | 5 +++++ 7 files changed, 77 insertions(+), 5 deletions(-) diff --git a/examples/tcp_client.rs b/examples/tcp_client.rs index 7637638..8828739 100644 --- a/examples/tcp_client.rs +++ b/examples/tcp_client.rs @@ -9,7 +9,7 @@ fn main() -> io::Result<()> { unsafe { poller.add(&socket, Event::new(0, true, true))?; } - let addr = net::SocketAddr::new(net::Ipv4Addr::LOCALHOST.into(), 8080); + let addr = net::SocketAddr::new(net::Ipv4Addr::LOCALHOST.into(), 12345); // some address with no server listening socket.set_nonblocking(true)?; let _ = socket.connect(&addr.into()); @@ -19,9 +19,12 @@ fn main() -> io::Result<()> { poller.wait(&mut events, None)?; let event = events.iter().next(); - let Some(event) = event else { - println!("no event"); - return Ok(()); + let event = match event { + Some(event) => event, + None => { + println!("no event"); + return Ok(()); + } }; println!("event: {:?}", event); diff --git a/src/epoll.rs b/src/epoll.rs index 34a584c..2b2ca3c 100644 --- a/src/epoll.rs +++ b/src/epoll.rs @@ -86,6 +86,11 @@ impl Poller { true } + /// Whether this poller supports checking for the tcp connection failure. + pub fn supports_is_connect_failed(&self) -> bool { + true + } + /// Adds a new file descriptor. /// /// # Safety diff --git a/src/iocp/mod.rs b/src/iocp/mod.rs index 1f37062..ce356d3 100644 --- a/src/iocp/mod.rs +++ b/src/iocp/mod.rs @@ -164,6 +164,11 @@ impl Poller { false } + /// Whether this poller supports checking for the tcp connection failure. + pub fn supports_is_connect_failed(&self) -> bool { + true + } + /// Add a new source to the poller. /// /// # Safety diff --git a/src/kqueue.rs b/src/kqueue.rs index 98adfc9..6ace93c 100644 --- a/src/kqueue.rs +++ b/src/kqueue.rs @@ -79,6 +79,11 @@ impl Poller { true } + /// Whether this poller supports checking for the tcp connection failure. + pub fn supports_is_connect_failed(&self) -> bool { + false + } + /// Adds a new file descriptor. /// /// # Safety @@ -372,9 +377,10 @@ impl EventExtra { false } + /// is the tcp connection failed? #[inline] pub fn is_connect_failed(&self) -> bool { - unimplemented!("is connect failed is not supported on kqueue"); + false } } diff --git a/src/lib.rs b/src/lib.rs index 71dd769..5e73c11 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -337,7 +337,45 @@ impl Event { /// This indicates a tcp connection has failed, it corresponds to the `EPOLLERR` along with `EPOLLHUP` event in linux /// and `CONNECT_FAILED` event in windows IOCP. /// + /// # Examples + /// + /// ``` + /// use std::{io, net}; + /// use polling::Event; + /// use socket2::Type; + /// + /// fn main() -> io::Result<()> { + /// let socket = socket2::Socket::new(socket2::Domain::IPV4, Type::STREAM, None)?; + /// let poller = polling::Poller::new()?; + /// unsafe { + /// poller.add(&socket, Event::new(0, true, true))?; + /// } + /// let addr = net::SocketAddr::new(net::Ipv4Addr::LOCALHOST.into(), 12345); // some address with no server listening + /// socket.set_nonblocking(true)?; + /// let _ = socket.connect(&addr.into()); + /// let mut events = polling::Events::new(); + + /// events.clear(); + /// poller.wait(&mut events, None)?; + + /// let event = events.iter().next(); + /// let event = match event { + /// Some(event) => event, + /// None => { + /// println!("no event"); + /// return Ok(()); + /// } + /// }; + + /// println!("event: {:?}", event); + /// if event.is_connect_failed() { + /// println!("connect failed"); + /// } + + /// Ok(()) + /// } + /// ``` #[inline] pub fn is_connect_failed(&self) -> bool { self.extra.is_connect_failed() @@ -395,6 +433,11 @@ impl Poller { self.poller.supports_edge() } + /// Whether this poller supports checking for the tcp connection failure. + pub fn supports_is_connect_failed(&self) -> bool { + self.poller.supports_is_connect_failed() + } + /// Adds a file descriptor or socket to the poller. /// /// A file descriptor or socket is considered readable or writable when a read or write diff --git a/src/poll.rs b/src/poll.rs index e1e3255..caec736 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -94,6 +94,11 @@ impl Poller { false } + /// Whether this poller supports checking for the tcp connection failure. + pub fn supports_is_connect_failed(&self) -> bool { + true + } + /// Adds a new file descriptor. pub fn add(&self, fd: RawFd, ev: Event, mode: PollMode) -> io::Result<()> { if self.notify.has_fd(fd) { diff --git a/src/port.rs b/src/port.rs index 0b9a63c..a5df8b0 100644 --- a/src/port.rs +++ b/src/port.rs @@ -42,6 +42,11 @@ impl Poller { false } + /// Whether this poller supports checking for the tcp connection failure. + pub fn supports_is_connect_failed(&self) -> bool { + true + } + /// Adds a file descriptor. /// /// # Safety