Skip to content

Commit 7980b46

Browse files
committed
Reduce syscalls in blocking_fd
1 parent 73f3f8f commit 7980b46

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/lib.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,8 +1063,23 @@ impl fmt::Debug for Command {
10631063
/// Moves `Fd` out of non-blocking mode.
10641064
#[cfg(unix)]
10651065
fn blocking_fd(fd: rustix::fd::BorrowedFd<'_>) -> io::Result<()> {
1066-
let flags = rustix::fs::fcntl_getfl(fd)?;
1067-
rustix::fs::fcntl_setfl(fd, flags & !rustix::fs::OFlags::NONBLOCK)?;
1066+
cfg_if::cfg_if! {
1067+
// ioctl(FIONBIO) sets the flag atomically, but we use this only on Linux
1068+
// for now, as with the standard library, because it seems to behave
1069+
// differently depending on the platform.
1070+
// https://github.com/rust-lang/rust/commit/efeb42be2837842d1beb47b51bb693c7474aba3d
1071+
// https://github.com/libuv/libuv/blob/e9d91fccfc3e5ff772d5da90e1c4a24061198ca0/src/unix/poll.c#L78-L80
1072+
// https://github.com/tokio-rs/mio/commit/0db49f6d5caf54b12176821363d154384357e70a
1073+
if #[cfg(target_os = "linux")] {
1074+
rustix::io::ioctl_fionbio(fd, false)?;
1075+
} else {
1076+
let previous = rustix::fs::fcntl_getfl(fd)?;
1077+
let new = previous & !rustix::fs::OFlags::NONBLOCK;
1078+
if new != previous {
1079+
rustix::fs::fcntl_setfl(fd, new)?;
1080+
}
1081+
}
1082+
}
10681083
Ok(())
10691084
}
10701085

0 commit comments

Comments
 (0)