diff --git a/tokio-util/src/io/sync_bridge.rs b/tokio-util/src/io/sync_bridge.rs index 5587175b9..5682258c3 100644 --- a/tokio-util/src/io/sync_bridge.rs +++ b/tokio-util/src/io/sync_bridge.rs @@ -66,6 +66,21 @@ impl SyncIoBridge { } } +impl SyncIoBridge { + /// Shutdown this writer. This method provides a way to call the [`AsyncWriteExt::shutdown`] + /// function of the inner [`tokio::io::AsyncWrite`] instance. + /// + /// # Errors + /// + /// This method returns the same errors as [`AsyncWriteExt::shutdown`]. + /// + /// [`AsyncWriteExt::shutdown`]: tokio::io::AsyncWriteExt::shutdown + pub fn shutdown(&mut self) -> std::io::Result<()> { + let src = &mut self.src; + self.rt.block_on(src.shutdown()) + } +} + impl SyncIoBridge { /// Use a [`tokio::io::AsyncRead`] synchronously as a [`std::io::Read`] or /// a [`tokio::io::AsyncWrite`] as a [`std::io::Write`]. diff --git a/tokio-util/tests/io_sync_bridge.rs b/tokio-util/tests/io_sync_bridge.rs index e22631e48..76bbd0b4e 100644 --- a/tokio-util/tests/io_sync_bridge.rs +++ b/tokio-util/tests/io_sync_bridge.rs @@ -2,8 +2,8 @@ #![cfg(not(target_os = "wasi"))] // Wasi doesn't support threads use std::error::Error; -use std::io::{Cursor, Read, Result as IoResult}; -use tokio::io::AsyncRead; +use std::io::{Cursor, Read, Result as IoResult, Write}; +use tokio::io::{AsyncRead, AsyncReadExt}; use tokio_util::io::SyncIoBridge; async fn test_reader_len( @@ -42,3 +42,21 @@ async fn test_async_write_to_sync() -> Result<(), Box> { assert_eq!(dest.as_slice(), src); Ok(()) } + +#[tokio::test] +async fn test_shutdown() -> Result<(), Box> { + let (s1, mut s2) = tokio::io::duplex(1024); + let (_rh, wh) = tokio::io::split(s1); + tokio::task::spawn_blocking(move || -> std::io::Result<_> { + let mut wh = SyncIoBridge::new(wh); + wh.write_all(b"hello")?; + wh.shutdown()?; + assert!(wh.write_all(b" world").is_err()); + Ok(()) + }) + .await??; + let mut buf = vec![]; + s2.read_to_end(&mut buf).await?; + assert_eq!(buf, b"hello"); + Ok(()) +}