From 2682c505e800ec0db38b9e9ea2dd3f0d582b1dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tymoteusz=20Wi=C5=9Bniewski?= Date: Sun, 20 Nov 2022 22:02:13 +0100 Subject: [PATCH] net: fix named pipe connect (#5208) --- tokio/src/net/windows/named_pipe.rs | 16 +++++------ .../{named_pipe.rs => net_named_pipe.rs} | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) rename tokio/tests/{named_pipe.rs => net_named_pipe.rs} (93%) diff --git a/tokio/src/net/windows/named_pipe.rs b/tokio/src/net/windows/named_pipe.rs index c895dabacc8..2446160a127 100644 --- a/tokio/src/net/windows/named_pipe.rs +++ b/tokio/src/net/windows/named_pipe.rs @@ -192,17 +192,15 @@ impl NamedPipeServer { /// # Ok(()) } /// ``` pub async fn connect(&self) -> io::Result<()> { - loop { - match self.io.connect() { - Ok(()) => break, - Err(e) if e.kind() == io::ErrorKind::WouldBlock => { - self.io.registration().readiness(Interest::WRITABLE).await?; - } - Err(e) => return Err(e), + match self.io.connect() { + Err(e) if e.kind() == io::ErrorKind::WouldBlock => { + self.io + .registration() + .async_io(Interest::WRITABLE, || self.io.connect()) + .await } + x => x, } - - Ok(()) } /// Disconnects the server end of a named pipe instance from a client diff --git a/tokio/tests/named_pipe.rs b/tokio/tests/net_named_pipe.rs similarity index 93% rename from tokio/tests/named_pipe.rs rename to tokio/tests/net_named_pipe.rs index 2055c3ce5be..05a01bbe2de 100644 --- a/tokio/tests/named_pipe.rs +++ b/tokio/tests/net_named_pipe.rs @@ -341,6 +341,33 @@ async fn test_named_pipe_mode_message() -> io::Result<()> { Ok(()) } +// This tests `NamedPipeServer::connect` with various access settings. +#[tokio::test] +async fn test_named_pipe_access() -> io::Result<()> { + const PIPE_NAME: &str = r"\\.\pipe\test-named-pipe-access"; + + for (inb, outb) in [(true, true), (true, false), (false, true)] { + let (tx, rx) = tokio::sync::oneshot::channel(); + let server = tokio::spawn(async move { + let s = ServerOptions::new() + .access_inbound(inb) + .access_outbound(outb) + .create(PIPE_NAME)?; + let mut connect_fut = tokio_test::task::spawn(s.connect()); + assert!(connect_fut.poll().is_pending()); + tx.send(()).unwrap(); + connect_fut.await + }); + + // Wait for the server to call connect. + rx.await.unwrap(); + let _ = ClientOptions::new().read(outb).write(inb).open(PIPE_NAME)?; + + server.await??; + } + Ok(()) +} + fn num_instances(pipe_name: impl AsRef) -> io::Result { use ntapi::ntioapi; use winapi::shared::ntdef;