Skip to content

Commit dba9139

Browse files
committed
Review comments
Signed-off-by: John Nunley <[email protected]>
1 parent ea3a4bc commit dba9139

File tree

2 files changed

+119
-2
lines changed

2 files changed

+119
-2
lines changed

examples/windows-uds.rs

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,122 @@
66
//! cargo run --example windows-uds
77
//! ```
88
9+
#[cfg(windows)]
10+
fn main() -> std::io::Result<()> {
11+
use std::ops::Deref;
12+
use std::os::windows::io::{AsRawSocket, AsSocket, BorrowedSocket};
13+
use std::path::PathBuf;
14+
15+
use async_io::Async;
16+
use blocking::Unblock;
17+
use futures_lite::{future, prelude::*};
18+
use std::io;
19+
use tempfile::tempdir;
20+
21+
// n.b.: notgull: uds_windows does not support I/O safety uet, hence the wrapper types
22+
23+
struct UnixListener(uds_windows::UnixListener);
24+
25+
impl From<uds_windows::UnixListener> for UnixListener {
26+
fn from(ul: uds_windows::UnixListener) -> Self {
27+
Self(ul)
28+
}
29+
}
30+
31+
impl Deref for UnixListener {
32+
type Target = uds_windows::UnixListener;
33+
34+
fn deref(&self) -> &uds_windows::UnixListener {
35+
&self.0
36+
}
37+
}
38+
39+
impl AsSocket for UnixListener {
40+
fn as_socket(&self) -> BorrowedSocket<'_> {
41+
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
42+
}
43+
}
44+
45+
struct UnixStream(uds_windows::UnixStream);
46+
47+
impl From<uds_windows::UnixStream> for UnixStream {
48+
fn from(ul: uds_windows::UnixStream) -> Self {
49+
Self(ul)
50+
}
51+
}
52+
53+
impl Deref for UnixStream {
54+
type Target = uds_windows::UnixStream;
55+
56+
fn deref(&self) -> &uds_windows::UnixStream {
57+
&self.0
58+
}
59+
}
60+
61+
impl AsSocket for UnixStream {
62+
fn as_socket(&self) -> BorrowedSocket<'_> {
63+
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
64+
}
65+
}
66+
67+
impl io::Read for UnixStream {
68+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
69+
io::Read::read(&mut self.0, buf)
70+
}
71+
}
72+
73+
impl io::Write for UnixStream {
74+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
75+
io::Write::write(&mut self.0, buf)
76+
}
77+
78+
fn flush(&mut self) -> io::Result<()> {
79+
io::Write::flush(&mut self.0)
80+
}
81+
}
82+
83+
unsafe impl async_io::IoSafe for UnixStream {}
84+
85+
async fn client(addr: PathBuf) -> io::Result<()> {
86+
// Connect to the address.
87+
let stream = Async::new(UnixStream::from(uds_windows::UnixStream::connect(addr)?))?;
88+
println!("Connected to {:?}", stream.get_ref().peer_addr()?);
89+
90+
// Pipe the stream to stdout.
91+
let mut stdout = Unblock::new(std::io::stdout());
92+
futures_lite::io::copy(stream, &mut stdout).await?;
93+
Ok(())
94+
}
95+
96+
let dir = tempdir()?;
97+
let path = dir.path().join("socket");
98+
99+
future::block_on(async {
100+
// Create a listener.
101+
let listener = Async::new(UnixListener::from(uds_windows::UnixListener::bind(&path)?))?;
102+
println!("Listening on {:?}", listener.get_ref().local_addr()?);
103+
104+
future::try_zip(
105+
async {
106+
// Accept the client.
107+
let (stream, _) = listener.read_with(|l| l.accept()).await?;
108+
println!("Accepted a client");
109+
110+
// Send a message, drop the stream, and wait for the client.
111+
Async::new(UnixStream::from(stream))?
112+
.write_all(b"Hello!\n")
113+
.await?;
114+
Ok(())
115+
},
116+
client(path),
117+
)
118+
.await?;
119+
120+
Ok(())
121+
})
122+
}
123+
124+
#[cfg(not(windows))]
9125
fn main() {
10-
println!("TODO: Restore this example from git once uds_windows implements I/O safety");
126+
println!("This example works only on Windows!");
11127
}

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ impl<T> Drop for Async<T> {
11531153
/// happen if the inner resource (the [`TcpStream`], [`UnixListener`] or other `T`) is moved out
11541154
/// and dropped before the [`Async`]. Because of this, functions that grant mutable access to
11551155
/// the inner type are unsafe, as there is no way to guarantee that the source won't be dropped
1156-
/// and a dangling pointer won't be left behind.
1156+
/// and a dangling handle won't be left behind.
11571157
///
11581158
/// Unfortunately this extends to implementations of [`Read`] and [`Write`]. Since methods on those
11591159
/// traits take `&mut`, there is no guarantee that the implementor of those traits won't move the
@@ -1205,6 +1205,7 @@ unsafe impl<T: IoSafe + Write> IoSafe for std::io::BufWriter<T> {}
12051205
unsafe impl<T: IoSafe + Write> IoSafe for std::io::LineWriter<T> {}
12061206
unsafe impl<T: IoSafe + ?Sized> IoSafe for &mut T {}
12071207
unsafe impl<T: IoSafe + ?Sized> IoSafe for Box<T> {}
1208+
unsafe impl<T: Clone + IoSafe + ?Sized> IoSafe for std::borrow::Cow<'_, T> {}
12081209

12091210
impl<T: IoSafe + Read> AsyncRead for Async<T> {
12101211
fn poll_read(

0 commit comments

Comments
 (0)