Fix stack space issues, remove pending constant

This commit is contained in:
Filip Tibell 2024-01-18 21:53:13 +01:00
parent 78bb958797
commit dac729cf46
No known key found for this signature in database

View file

@ -3,7 +3,7 @@ use std::{collections::VecDeque, rc::Rc};
use mlua::prelude::*; use mlua::prelude::*;
use smol::{ use smol::{
channel::{Receiver, Sender}, channel::{Receiver, Sender},
future::{yield_now, FutureExt}, future::FutureExt,
lock::Mutex, lock::Mutex,
stream::StreamExt, stream::StreamExt,
*, *,
@ -15,7 +15,6 @@ use super::{
}; };
pub struct ThreadRuntime { pub struct ThreadRuntime {
pending_key: LuaRegistryKey,
queue: Rc<Mutex<VecDeque<ThreadWithArgs>>>, queue: Rc<Mutex<VecDeque<ThreadWithArgs>>>,
tx: Sender<()>, tx: Sender<()>,
rx: Receiver<()>, rx: Receiver<()>,
@ -74,22 +73,7 @@ impl ThreadRuntime {
lua.globals().set("spawn", fn_spawn)?; lua.globals().set("spawn", fn_spawn)?;
lua.globals().set("defer", fn_defer)?; lua.globals().set("defer", fn_defer)?;
// HACK: Extract mlua "pending" constant value and store it Ok(ThreadRuntime { queue, tx, rx })
let pending = lua
.create_async_function(|_, ()| async move {
yield_now().await;
Ok(())
})?
.into_lua_thread(lua)?
.resume::<_, LuaValue>(())?;
let pending_key = lua.create_registry_value(pending)?;
Ok(ThreadRuntime {
pending_key,
queue,
tx,
rx,
})
} }
/** /**
@ -145,26 +129,22 @@ impl ThreadRuntime {
// before we got here, so we need to check it again // before we got here, so we need to check it again
let (thread, args) = queued_thread.into_inner(lua); let (thread, args) = queued_thread.into_inner(lua);
if thread.status() == LuaThreadStatus::Resumable { if thread.status() == LuaThreadStatus::Resumable {
let pending = lua
.registry_value(&self.pending_key)
.expect("ran out of memory");
let mut stream = thread.into_async::<_, LuaValue>(args); let mut stream = thread.into_async::<_, LuaValue>(args);
lua_exec
// Keep resuming the thread until we get a .spawn(async move {
// value that is not the mlua pending value // Only run stream until first coroutine.yield or completion,
let fut = async move { // this will then get dropped right away and clear stack space
while let Some(res) = stream.next().await { match stream.next().await.unwrap() {
match res { Err(e) => {
Err(e) => eprintln!("{e}"), eprintln!("{e}");
Ok(v) if v != pending => { // TODO: Forward error
break; }
Ok(_) => {
// TODO: Forward value
} }
Ok(_) => {}
} }
} })
}; .detach();
lua_exec.spawn(fut).detach();
} }
} }