Potential fix for process.spawn yield issue

This commit is contained in:
Filip Tibell 2023-01-24 15:36:09 -05:00
parent 7eff6e4555
commit d3046194bc
No known key found for this signature in database

View file

@ -1,8 +1,12 @@
use std::{env, process::Stdio, sync::Weak}; use std::{
env,
process::{Command, Stdio},
sync::Weak,
};
use mlua::prelude::*; use mlua::prelude::*;
use os_str_bytes::RawOsString; use os_str_bytes::RawOsString;
use smol::{channel::Sender, process::Command, LocalExecutor}; use smol::{channel::Sender, unblock};
use crate::{utils::table::TableBuilder, LuneMessage}; use crate::{utils::table::TableBuilder, LuneMessage};
@ -116,30 +120,24 @@ async fn process_spawn(
lua: &Lua, lua: &Lua,
(program, args): (String, Option<Vec<String>>), (program, args): (String, Option<Vec<String>>),
) -> LuaResult<LuaTable> { ) -> LuaResult<LuaTable> {
let exec = lua // Create and spawn a **blocking** child process to prevent
.app_data_ref::<Weak<LocalExecutor>>()
.unwrap()
.upgrade()
.unwrap();
// Create and spawn a child process in a new task to prevent
// issues with yielding across the metamethod/c-call boundary // issues with yielding across the metamethod/c-call boundary
let output = exec let pwd = env::current_dir()?;
.spawn(async move { let output = unblock(move || {
let mut cmd = Command::new(program); let mut cmd = Command::new(program);
if let Some(args) = args { if let Some(args) = args {
cmd.args(args); cmd.args(args);
} }
let child = cmd let child = cmd
.current_dir(env::current_dir().map_err(LuaError::external)?) .current_dir(pwd)
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn() .spawn()?;
.map_err(LuaError::external)?; child.wait_with_output()
let output = child.output().await.map_err(LuaError::external)?;
Ok::<_, LuaError>(output)
}) })
.await?; .await
.map_err(LuaError::external)?;
// NOTE: If an exit code was not given by the child process, // NOTE: If an exit code was not given by the child process,
// we default to 1 if it yielded any error output, otherwise 0 // we default to 1 if it yielded any error output, otherwise 0
let code = output let code = output