Using std::process::Child stdin/stdout/stderr handles from different threads

#1

In my GUI app I want to spawn a process and then write to its stdin from the
main thread. Stdout and stderr of the process will also be read as they become
available for reading. Because this is a GUI app and I don’t have access to the
event loop I need to do this in another thread. The problem is I can’t share
ChildStdout/ChildStderr with a thread because those are fields of Child.
However if I wrap the whole Child into a Arc<Mutex<Child>> then I suffer
from bad ergonomics around Arc and Mutex (e.g. I can’t implement a (&mut self) -> &mut ChildStdin method because the reference can’t escape from the
MutexGuard's scope).

Currently what I do is I’m moving a copy of RawFds to the thread. This is not
ideal because if I drop the Child the fd will be closed, causing panics in the
thread.

Does anyone know any good ways to make this work, or should I keep passing a fd
to the thread and try to make sure the Child won’t be dropped before the
thread returns or gets killed.

Thanks

0 Likes

#2

You can use stdout.take() to remove ChildStdout from Child. And ChildStdout is shareable between threads.

As for usability of Arc<Mutex<>>, you can wrap it in a newtype (struct MyStdio(Arc<Mutex<Child>>), and implement Read/Write traits on the newtype, making locking hidden in the implementation.

0 Likes

#3

This makes so much sense. Using the Option this way never crossed my mind. Thanks.

0 Likes