Skip to content

Commit be57c55

Browse files
author
germaniuss
committed
♻️ zb: Use async versions of UnixStream when possible
When connecting to a UnixSocket a blocking/threaded API is being used. This commit changes this to use `tokio::net::UnixStream` and `Async<std::os::unix::net::UnixStream>` when possible preventing the use of extra threads. The windows version continues using the blocking/threaded API. The `UnixStream::connect_addr` function from `SocketAddrExt` is no longer used since neither tokio nor async-io supports it. Instead, we use the plain `connect` functions in both environments, since they allow for abstract names when the path is prepended with '\0' (a null byte).
1 parent f84ba5b commit be57c55

1 file changed

Lines changed: 36 additions & 32 deletions

File tree

  • zbus/src/address/transport

zbus/src/address/transport/mod.rs

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,24 @@ use async_io::Async;
1212
use std::collections::HashMap;
1313
#[cfg(not(feature = "tokio"))]
1414
use std::net::TcpStream;
15-
#[cfg(unix)]
16-
use std::os::unix::net::{SocketAddr, UnixStream};
1715
#[cfg(feature = "tokio")]
1816
use tokio::net::TcpStream;
1917
#[cfg(feature = "tokio-vsock")]
2018
use tokio_vsock::VsockStream;
21-
#[cfg(windows)]
22-
use uds_windows::UnixStream;
2319
#[cfg(all(feature = "vsock", not(feature = "tokio")))]
2420
use vsock::VsockStream;
2521
#[cfg(unix)]
2622
mod unixexec;
2723
#[cfg(unix)]
2824
pub use unixexec::Unixexec;
2925

26+
#[cfg(all(unix, not(feature = "tokio")))]
27+
use std::os::unix::net::UnixStream;
28+
#[cfg(all(unix, feature = "tokio"))]
29+
use tokio::net::UnixStream;
30+
#[cfg(windows)]
31+
use uds_windows::UnixStream;
32+
3033
use std::{
3134
fmt::{Display, Formatter},
3235
str::from_utf8_unchecked,
@@ -55,8 +58,6 @@ pub use ibus::Ibus;
5558
#[path = "vsock.rs"]
5659
// Gotta rename to avoid name conflict with the `vsock` crate.
5760
mod vsock_transport;
58-
#[cfg(target_os = "linux")]
59-
use std::os::linux::net::SocketAddrExt;
6061
#[cfg(any(
6162
all(feature = "vsock", not(feature = "tokio")),
6263
feature = "tokio-vsock"
@@ -103,38 +104,44 @@ impl Transport {
103104
pub(super) async fn connect(self) -> Result<Stream> {
104105
match self {
105106
Transport::Unix(unix) => {
106-
// This is a `path` in case of Windows until uds_windows provides the needed API:
107-
// https://github.com/haraldh/rust_uds_windows/issues/14
107+
// This is a `path` because neither uds_windows, tokio, nor async_io provide
108+
// the SocketAddrExt functions.
108109
let addr = match unix.take_path() {
109-
#[cfg(unix)]
110-
UnixSocket::File(path) => SocketAddr::from_pathname(path)?,
111-
#[cfg(windows)]
112110
UnixSocket::File(path) => path,
113111
#[cfg(target_os = "linux")]
114112
UnixSocket::Abstract(name) => {
115-
SocketAddr::from_abstract_name(name.as_encoded_bytes())?
113+
use std::{ffi::OsString, os::unix::ffi::OsStringExt, path::PathBuf};
114+
let mut v = name.into_vec();
115+
v.insert(0, 0);
116+
PathBuf::from(OsString::from_vec(v))
116117
}
117118
UnixSocket::Dir(_) | UnixSocket::TmpDir(_) => {
118119
// You can't connect to a unix:dir.
119120
return Err(Error::Unsupported);
120121
}
121122
};
122-
let stream = crate::Task::spawn_blocking(
123-
move || -> Result<_> {
124-
#[cfg(unix)]
125-
let stream = UnixStream::connect_addr(&addr)?;
126-
#[cfg(windows)]
127-
let stream = UnixStream::connect(addr)?;
128-
stream.set_nonblocking(true)?;
129-
130-
Ok(stream)
131-
},
132-
"unix stream connection",
133-
)
134-
.await??;
123+
135124
#[cfg(not(feature = "tokio"))]
136125
{
137-
Async::new(stream)
126+
#[cfg(unix)]
127+
let stream = Async::<UnixStream>::connect(addr).await;
128+
129+
#[cfg(not(unix))]
130+
let stream = {
131+
let stream = crate::Task::spawn_blocking(
132+
move || -> Result<_> {
133+
let stream = UnixStream::connect(addr)?;
134+
stream.set_nonblocking(true)?;
135+
136+
Ok(stream)
137+
},
138+
"unix stream connection",
139+
)
140+
.await??;
141+
Async::new(stream)
142+
};
143+
144+
stream
138145
.map(Stream::Unix)
139146
.map_err(|e| Error::InputOutput(e.into()))
140147
}
@@ -143,16 +150,13 @@ impl Transport {
143150
{
144151
#[cfg(unix)]
145152
{
146-
tokio::net::UnixStream::from_std(stream)
147-
.map(Stream::Unix)
153+
UnixStream::connect(addr)
154+
.await
148155
.map_err(|e| Error::InputOutput(e.into()))
149156
}
150157

151158
#[cfg(not(unix))]
152-
{
153-
let _ = stream;
154-
Err(Error::Unsupported)
155-
}
159+
Err(Error::Unsupported)
156160
}
157161
}
158162
#[cfg(unix)]

0 commit comments

Comments
 (0)