From d3046194bcac8cba197b7b77397936abae5e26bd Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Tue, 24 Jan 2023 15:36:09 -0500 Subject: [PATCH] Potential fix for process.spawn yield issue --- src/lib/globals/process.rs | 48 ++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/lib/globals/process.rs b/src/lib/globals/process.rs index 19d6014..7a2c274 100644 --- a/src/lib/globals/process.rs +++ b/src/lib/globals/process.rs @@ -1,8 +1,12 @@ -use std::{env, process::Stdio, sync::Weak}; +use std::{ + env, + process::{Command, Stdio}, + sync::Weak, +}; use mlua::prelude::*; use os_str_bytes::RawOsString; -use smol::{channel::Sender, process::Command, LocalExecutor}; +use smol::{channel::Sender, unblock}; use crate::{utils::table::TableBuilder, LuneMessage}; @@ -116,30 +120,24 @@ async fn process_spawn( lua: &Lua, (program, args): (String, Option>), ) -> LuaResult { - let exec = lua - .app_data_ref::>() - .unwrap() - .upgrade() - .unwrap(); - // Create and spawn a child process in a new task to prevent + // Create and spawn a **blocking** child process to prevent // issues with yielding across the metamethod/c-call boundary - let output = exec - .spawn(async move { - let mut cmd = Command::new(program); - if let Some(args) = args { - cmd.args(args); - } - let child = cmd - .current_dir(env::current_dir().map_err(LuaError::external)?) - .stdin(Stdio::null()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .map_err(LuaError::external)?; - let output = child.output().await.map_err(LuaError::external)?; - Ok::<_, LuaError>(output) - }) - .await?; + let pwd = env::current_dir()?; + let output = unblock(move || { + let mut cmd = Command::new(program); + if let Some(args) = args { + cmd.args(args); + } + let child = cmd + .current_dir(pwd) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn()?; + child.wait_with_output() + }) + .await + .map_err(LuaError::external)?; // NOTE: If an exit code was not given by the child process, // we default to 1 if it yielded any error output, otherwise 0 let code = output