mirror of https://github.com/helix-editor/helix
Join input and wait tasks in external formatter Tokio command
This matches the layout of `shell_impl_async` in `commands.rs` and avoids a hang or maybe deadlock in `to_writer`'s calls to `tokio::io::AsyncWriteExt::write_all`. I don't really understand the underlying cause of the hang but it seems it's necessary to spawn a new tokio task to provide input to stdin. This is shown in an example in `tokio::process::Child::wait` but not documented explicitly.pull/12748/head
parent
e9c16b7fc5
commit
c3620b7116
|
@ -796,17 +796,21 @@ impl Document {
|
||||||
command: fmt_cmd.to_string_lossy().into(),
|
command: fmt_cmd.to_string_lossy().into(),
|
||||||
error: e.kind(),
|
error: e.kind(),
|
||||||
})?;
|
})?;
|
||||||
{
|
|
||||||
let mut stdin = process.stdin.take().ok_or(FormatterError::BrokenStdin)?;
|
|
||||||
to_writer(&mut stdin, (encoding::UTF_8, false), &text)
|
|
||||||
.await
|
|
||||||
.map_err(|_| FormatterError::BrokenStdin)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let output = process
|
let mut stdin = process.stdin.take().ok_or(FormatterError::BrokenStdin)?;
|
||||||
.wait_with_output()
|
let input_text = text.clone();
|
||||||
.await
|
let input_task = tokio::spawn(async move {
|
||||||
.map_err(|_| FormatterError::WaitForOutputFailed)?;
|
to_writer(&mut stdin, (encoding::UTF_8, false), &input_text).await
|
||||||
|
// Note that `stdin` is dropped here, causing the pipe to close. This can
|
||||||
|
// avoid a deadlock with `wait_with_output` below if the process is waiting on
|
||||||
|
// stdin to close before exiting.
|
||||||
|
});
|
||||||
|
let (input_result, output_result) = tokio::join! {
|
||||||
|
input_task,
|
||||||
|
process.wait_with_output(),
|
||||||
|
};
|
||||||
|
let _ = input_result.map_err(|_| FormatterError::BrokenStdin)?;
|
||||||
|
let output = output_result.map_err(|_| FormatterError::WaitForOutputFailed)?;
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
if !output.stderr.is_empty() {
|
if !output.stderr.is_empty() {
|
||||||
|
|
Loading…
Reference in New Issue