|
@@ -7,7 +7,8 @@ use std::{
|
|
|
io::{BufRead, BufReader, Write},
|
|
|
path::PathBuf,
|
|
|
process::{Command as StdCommand, Stdio},
|
|
|
- sync::{Arc, Mutex},
|
|
|
+ sync::{Arc, Mutex, RwLock},
|
|
|
+ thread::spawn,
|
|
|
};
|
|
|
|
|
|
#[cfg(unix)]
|
|
@@ -18,8 +19,7 @@ use std::os::windows::process::CommandExt;
|
|
|
#[cfg(windows)]
|
|
|
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
|
|
|
|
|
-use crate::async_runtime::{channel, spawn, Receiver, RwLock};
|
|
|
-use futures::{future, FutureExt};
|
|
|
+use crate::async_runtime::{channel, spawn as spawn_task, Receiver};
|
|
|
use os_pipe::{pipe, PipeWriter};
|
|
|
use serde::Serialize;
|
|
|
use shared_child::SharedChild;
|
|
@@ -243,56 +243,58 @@ impl Command {
|
|
|
|
|
|
let tx_ = tx.clone();
|
|
|
let guard_ = guard.clone();
|
|
|
- let stdout_task = async move {
|
|
|
- let _lock = guard_.read().await;
|
|
|
+ spawn(move || {
|
|
|
+ let _lock = guard_.read().unwrap();
|
|
|
let reader = BufReader::new(stdout_reader);
|
|
|
for line in reader.lines() {
|
|
|
- let _ = match line {
|
|
|
- Ok(line) => tx_.send(CommandEvent::Stdout(line)).await,
|
|
|
- Err(e) => tx_.send(CommandEvent::Error(e.to_string())).await,
|
|
|
- };
|
|
|
+ let tx_ = tx_.clone();
|
|
|
+ spawn_task(async move {
|
|
|
+ let _ = match line {
|
|
|
+ Ok(line) => tx_.send(CommandEvent::Stdout(line)).await,
|
|
|
+ Err(e) => tx_.send(CommandEvent::Error(e.to_string())).await,
|
|
|
+ };
|
|
|
+ });
|
|
|
}
|
|
|
- };
|
|
|
+ });
|
|
|
|
|
|
let tx_ = tx.clone();
|
|
|
let guard_ = guard.clone();
|
|
|
- let stderr_task = async move {
|
|
|
- let _lock = guard_.read().await;
|
|
|
+ spawn(move || {
|
|
|
+ let _lock = guard_.read().unwrap();
|
|
|
let reader = BufReader::new(stderr_reader);
|
|
|
for line in reader.lines() {
|
|
|
- let _ = match line {
|
|
|
- Ok(line) => tx_.send(CommandEvent::Stderr(line)).await,
|
|
|
- Err(e) => tx_.send(CommandEvent::Error(e.to_string())).await,
|
|
|
- };
|
|
|
+ let tx_ = tx_.clone();
|
|
|
+ spawn_task(async move {
|
|
|
+ let _ = match line {
|
|
|
+ Ok(line) => tx_.send(CommandEvent::Stderr(line)).await,
|
|
|
+ Err(e) => tx_.send(CommandEvent::Error(e.to_string())).await,
|
|
|
+ };
|
|
|
+ });
|
|
|
}
|
|
|
- };
|
|
|
+ });
|
|
|
|
|
|
- let terminated_task = async move {
|
|
|
+ spawn(move || {
|
|
|
let _ = match child_.wait() {
|
|
|
Ok(status) => {
|
|
|
- guard.write().await;
|
|
|
+ let _l = guard.write().unwrap();
|
|
|
commands().lock().unwrap().remove(&child_.id());
|
|
|
- tx.send(CommandEvent::Terminated(TerminatedPayload {
|
|
|
- code: status.code(),
|
|
|
- #[cfg(windows)]
|
|
|
- signal: None,
|
|
|
- #[cfg(unix)]
|
|
|
- signal: status.signal(),
|
|
|
- }))
|
|
|
- .await
|
|
|
+ spawn_task(async move {
|
|
|
+ tx.send(CommandEvent::Terminated(TerminatedPayload {
|
|
|
+ code: status.code(),
|
|
|
+ #[cfg(windows)]
|
|
|
+ signal: None,
|
|
|
+ #[cfg(unix)]
|
|
|
+ signal: status.signal(),
|
|
|
+ }))
|
|
|
+ .await
|
|
|
+ });
|
|
|
}
|
|
|
Err(e) => {
|
|
|
- guard.write().await;
|
|
|
- tx.send(CommandEvent::Error(e.to_string())).await
|
|
|
+ let _l = guard.write().unwrap();
|
|
|
+ spawn_task(async move { tx.send(CommandEvent::Error(e.to_string())).await });
|
|
|
}
|
|
|
};
|
|
|
- };
|
|
|
-
|
|
|
- spawn(future::join_all(vec![
|
|
|
- stdout_task.boxed(),
|
|
|
- stderr_task.boxed(),
|
|
|
- terminated_task.boxed(),
|
|
|
- ]));
|
|
|
+ });
|
|
|
|
|
|
Ok((
|
|
|
rx,
|