Skip to content

Commit 8c13344

Browse files
authored
fix(core): command events not firing consistently (#2082)
1 parent bd038b5 commit 8c13344

3 files changed

Lines changed: 45 additions & 39 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch
3+
---
4+
5+
Fixes `api::process::Command` events not firing consistently.

core/tauri/src/api/process/command.rs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use std::{
77
io::{BufRead, BufReader, Write},
88
path::PathBuf,
99
process::{Command as StdCommand, Stdio},
10-
sync::{Arc, Mutex},
10+
sync::{Arc, Mutex, RwLock},
11+
thread::spawn,
1112
};
1213

1314
#[cfg(unix)]
@@ -18,8 +19,7 @@ use std::os::windows::process::CommandExt;
1819
#[cfg(windows)]
1920
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
2021

21-
use crate::async_runtime::{channel, spawn, Receiver, RwLock};
22-
use futures::{future, FutureExt};
22+
use crate::async_runtime::{channel, spawn as spawn_task, Receiver};
2323
use os_pipe::{pipe, PipeWriter};
2424
use serde::Serialize;
2525
use shared_child::SharedChild;
@@ -243,56 +243,58 @@ impl Command {
243243

244244
let tx_ = tx.clone();
245245
let guard_ = guard.clone();
246-
let stdout_task = async move {
247-
let _lock = guard_.read().await;
246+
spawn(move || {
247+
let _lock = guard_.read().unwrap();
248248
let reader = BufReader::new(stdout_reader);
249249
for line in reader.lines() {
250-
let _ = match line {
251-
Ok(line) => tx_.send(CommandEvent::Stdout(line)).await,
252-
Err(e) => tx_.send(CommandEvent::Error(e.to_string())).await,
253-
};
250+
let tx_ = tx_.clone();
251+
spawn_task(async move {
252+
let _ = match line {
253+
Ok(line) => tx_.send(CommandEvent::Stdout(line)).await,
254+
Err(e) => tx_.send(CommandEvent::Error(e.to_string())).await,
255+
};
256+
});
254257
}
255-
};
258+
});
256259

257260
let tx_ = tx.clone();
258261
let guard_ = guard.clone();
259-
let stderr_task = async move {
260-
let _lock = guard_.read().await;
262+
spawn(move || {
263+
let _lock = guard_.read().unwrap();
261264
let reader = BufReader::new(stderr_reader);
262265
for line in reader.lines() {
263-
let _ = match line {
264-
Ok(line) => tx_.send(CommandEvent::Stderr(line)).await,
265-
Err(e) => tx_.send(CommandEvent::Error(e.to_string())).await,
266-
};
266+
let tx_ = tx_.clone();
267+
spawn_task(async move {
268+
let _ = match line {
269+
Ok(line) => tx_.send(CommandEvent::Stderr(line)).await,
270+
Err(e) => tx_.send(CommandEvent::Error(e.to_string())).await,
271+
};
272+
});
267273
}
268-
};
274+
});
269275

270-
let terminated_task = async move {
276+
spawn(move || {
271277
let _ = match child_.wait() {
272278
Ok(status) => {
273-
guard.write().await;
279+
let _l = guard.write().unwrap();
274280
commands().lock().unwrap().remove(&child_.id());
275-
tx.send(CommandEvent::Terminated(TerminatedPayload {
276-
code: status.code(),
277-
#[cfg(windows)]
278-
signal: None,
279-
#[cfg(unix)]
280-
signal: status.signal(),
281-
}))
282-
.await
281+
spawn_task(async move {
282+
tx.send(CommandEvent::Terminated(TerminatedPayload {
283+
code: status.code(),
284+
#[cfg(windows)]
285+
signal: None,
286+
#[cfg(unix)]
287+
signal: status.signal(),
288+
}))
289+
.await
290+
});
283291
}
284292
Err(e) => {
285-
guard.write().await;
286-
tx.send(CommandEvent::Error(e.to_string())).await
293+
let _l = guard.write().unwrap();
294+
spawn_task(async move { tx.send(CommandEvent::Error(e.to_string())).await });
287295
}
288296
};
289-
};
290-
291-
spawn(future::join_all(vec![
292-
stdout_task.boxed(),
293-
stderr_task.boxed(),
294-
terminated_task.boxed(),
295-
]));
297+
});
296298

297299
Ok((
298300
rx,

core/tauri/src/endpoints/shell.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,8 @@ impl Cmd {
102102
let pid = child.pid();
103103
command_childs().lock().unwrap().insert(pid, child);
104104

105-
// TODO: for some reason using `crate::async_runtime::spawn` and `rx.recv().await` doesn't work here, see issue #1935
106-
std::thread::spawn(move || {
107-
while let Some(event) = rx.blocking_recv() {
105+
crate::async_runtime::spawn(async move {
106+
while let Some(event) = rx.recv().await {
108107
if matches!(event, crate::api::process::CommandEvent::Terminated(_)) {
109108
command_childs().lock().unwrap().remove(&pid);
110109
}

0 commit comments

Comments
 (0)