Fix process.spawn yielding issue

This commit is contained in:
Filip Tibell 2023-01-23 13:18:48 -05:00
parent 5839a7b021
commit c2ee188ad5
No known key found for this signature in database
2 changed files with 33 additions and 15 deletions

View file

@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Fixed
- Potential fix for spawned processes that yield erroring
with "attempt to yield across metamethod/c-call boundary"
## `0.0.5` - January 22nd, 2023 ## `0.0.5` - January 22nd, 2023
### Added ### Added

View file

@ -1,11 +1,12 @@
use std::{ use std::{
env, env,
process::{exit, Stdio}, process::{exit, Stdio},
sync::Weak,
}; };
use mlua::prelude::*; use mlua::prelude::*;
use os_str_bytes::RawOsString; use os_str_bytes::RawOsString;
use smol::process::Command; use smol::{process::Command, LocalExecutor};
use crate::utils::table_builder::TableBuilder; use crate::utils::table_builder::TableBuilder;
@ -116,8 +117,15 @@ async fn process_spawn(
lua: &Lua, lua: &Lua,
(program, args): (String, Option<Vec<String>>), (program, args): (String, Option<Vec<String>>),
) -> LuaResult<LuaTable> { ) -> LuaResult<LuaTable> {
// Create and spawn a child process, and let exec = lua
// wait for it to terminate with output .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
let output = exec
.spawn(async 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);
@ -130,6 +138,9 @@ async fn process_spawn(
.spawn() .spawn()
.map_err(LuaError::external)?; .map_err(LuaError::external)?;
let output = child.output().await.map_err(LuaError::external)?; let output = child.output().await.map_err(LuaError::external)?;
Ok::<_, LuaError>(output)
})
.await?;
// 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