Skip to content

Commit e638d4d

Browse files
committed
update the std::io::pipe() example to comment deadlocks
The previous version of the example wasn't a deadlock, but only because the Command object was a temporary. That's quite subtle, and I think it's better to call out the potential deadlock explicitly.
1 parent d45b9d0 commit e638d4d

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

content/Rust-1.87.0/index.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,25 @@ or platform-specific functions.
5151
use std::process::Command;
5252
use std::io::Read;
5353

54-
let (mut recv, send) = std::io::pipe()?;
54+
let (mut reader, writer) = std::io::pipe()?;
5555

56-
let mut command = Command::new("path/to/bin")
57-
// Both stdout and stderr will write to the same pipe, combining the two.
58-
.stdout(send.try_clone()?)
59-
.stderr(send)
60-
.spawn()?;
56+
let mut command = Command::new("path/to/bin");
57+
// Both stdout and stderr will write to the same pipe, combining the two.
58+
command.stdout(writer.try_clone()?);
59+
command.stderr(writer);
60+
let mut child = command.spawn()?;
61+
62+
// .read_to_end() will block until all pipe writers are closed, but the Command
63+
// object is still holding two of them. Dropping it closes those writers and
64+
// prevents a deadlock.
65+
drop(command);
6166

6267
let mut output = Vec::new();
63-
recv.read_to_end(&mut output)?;
68+
reader.read_to_end(&mut output)?;
6469

6570
// It's important that we read from the pipe before the process exits, to avoid
6671
// filling the OS buffers if the program emits too much output.
67-
assert!(command.wait()?.success());
72+
assert!(child.wait()?.success());
6873
```
6974

7075
### Safe architecture intrinsics

0 commit comments

Comments
 (0)