Skip to content

Commit cc13a4e

Browse files
committed
Fix nonblocking setting in parallel::job_token
Refactor it to use `parallel::stderr::set_non_blocking`, so that there's only one implementation and it would fix the bug. Signed-off-by: Jiahao XU <[email protected]>
1 parent aff20bf commit cc13a4e

File tree

4 files changed

+15
-26
lines changed

4 files changed

+15
-26
lines changed

src/command_helpers.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ impl StderrForwarder {
167167
pub(crate) fn set_non_blocking(&mut self) -> Result<(), Error> {
168168
assert!(!self.is_non_blocking);
169169

170-
if let Some((stderr, _)) = self.inner.as_mut() {
170+
if let Some((stderr, _)) = self.inner.as_ref() {
171+
#[cfg(unix)]
171172
crate::parallel::stderr::set_non_blocking(stderr)?;
172173
}
173174

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,7 @@ impl Build {
14991499
};
15001500
let mut child = spawn(&mut cmd, &program, &self.cargo_output)?;
15011501
let mut stderr_forwarder = StderrForwarder::new(&mut child);
1502+
#[cfg(unix)]
15021503
stderr_forwarder.set_non_blocking()?;
15031504

15041505
cell_update(&pendings, |mut pendings| {

src/parallel/job_token/unix.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use std::{
1313
path::Path,
1414
};
1515

16+
use crate::parallel::stderr::set_non_blocking;
17+
1618
pub(super) struct JobServerClient {
1719
read: File,
1820
write: Option<File>,
@@ -48,7 +50,7 @@ impl JobServerClient {
4850
if is_pipe(&file)? {
4951
// File in Rust is always closed-on-exec as long as it's opened by
5052
// `File::open` or `fs::OpenOptions::open`.
51-
set_nonblocking(&file)?;
53+
set_non_blocking(&file).ok()?;
5254

5355
Some(Self {
5456
read: file,
@@ -92,8 +94,8 @@ impl JobServerClient {
9294
let write = write.try_clone().ok()?;
9395

9496
// Set read and write end to nonblocking
95-
set_nonblocking(&read)?;
96-
set_nonblocking(&write)?;
97+
set_non_blocking(&read)?;
98+
set_non_blocking(&write)?;
9799

98100
Some(Self {
99101
read,
@@ -148,21 +150,6 @@ impl JobServerClient {
148150
}
149151
}
150152

151-
fn set_nonblocking(file: &File) -> Option<()> {
152-
// F_SETFL can only set the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and
153-
// O_NONBLOCK flags.
154-
//
155-
// For pipe, only O_NONBLOCK is meaningful, so it is ok to
156-
// not issue a F_GETFL fcntl syscall.
157-
let ret = unsafe { libc::fcntl(file.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK) };
158-
159-
if ret == -1 {
160-
None
161-
} else {
162-
Some(())
163-
}
164-
}
165-
166153
fn cvt(t: c_int) -> io::Result<c_int> {
167154
if t == -1 {
168155
Err(io::Error::last_os_error())

src/parallel/stderr.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,19 @@ use crate::{Error, ErrorKind};
66
#[cfg(all(not(unix), not(windows)))]
77
compile_error!("Only unix and windows support non-blocking pipes! For other OSes, disable the parallel feature.");
88

9-
#[allow(unused_variables)]
10-
pub fn set_non_blocking(stderr: &mut ChildStderr) -> Result<(), Error> {
9+
#[cfg(unix)]
10+
pub fn set_non_blocking(pipe: &impl std::os::unix::io::AsRawFd) -> Result<(), Error> {
1111
// On Unix, switch the pipe to non-blocking mode.
1212
// On Windows, we have a different way to be non-blocking.
13-
#[cfg(unix)]
1413
{
15-
use std::os::unix::io::AsRawFd;
16-
let fd = stderr.as_raw_fd();
14+
let fd = pipe.as_raw_fd();
1715
let flags = unsafe { libc::fcntl(fd, libc::F_GETFL, 0) };
1816
if flags == -1 {
1917
return Err(Error::new(
2018
ErrorKind::IOError,
2119
format!(
22-
"Failed to get flags for child stderr: {}",
20+
"Failed to get flags for pipe {}: {}",
21+
fd,
2322
std::io::Error::last_os_error()
2423
),
2524
));
@@ -29,7 +28,8 @@ pub fn set_non_blocking(stderr: &mut ChildStderr) -> Result<(), Error> {
2928
return Err(Error::new(
3029
ErrorKind::IOError,
3130
format!(
32-
"Failed to set flags for child stderr: {}",
31+
"Failed to set flags for pipe {}: {}",
32+
fd,
3333
std::io::Error::last_os_error()
3434
),
3535
));

0 commit comments

Comments
 (0)