Enable Thread::reset for Luau

This commit is contained in:
Alex Orlenko 2022-03-23 21:13:48 +00:00
parent 5089dd73c0
commit 714dd6249f
No known key found for this signature in database
GPG key ID: 4C150C250863B96D
3 changed files with 30 additions and 13 deletions

View file

@ -152,8 +152,8 @@ pub struct LuaOptions {
/// Max size of thread (coroutine) object cache used to execute asynchronous functions.
///
/// It works only on Lua 5.4 or LuaJIT (vendored) with [`lua_resetthread`] function,
/// and allows to reuse old coroutines with reset state.
/// It works on Lua 5.4, LuaJIT (vendored) and Luau, where [`lua_resetthread`] function
/// is available and allows to reuse old coroutines with reset state.
///
/// Default: **0** (disabled)
///

View file

@ -7,7 +7,11 @@ use crate::types::LuaRef;
use crate::util::{check_stack, error_traceback, pop_error, StackGuard};
use crate::value::{FromLuaMulti, ToLuaMulti};
#[cfg(any(feature = "lua54", all(feature = "luajit", feature = "vendored")))]
#[cfg(any(
feature = "lua54",
all(feature = "luajit", feature = "vendored"),
feature = "luau",
))]
use crate::function::Function;
#[cfg(feature = "async")]
@ -173,16 +177,20 @@ impl<'lua> Thread<'lua> {
/// Returns a error in case of either the original error that stopped the thread or errors
/// in closing methods.
///
/// In [LuaJIT]: resets to the initial state of a newly created Lua thread.
/// In [LuaJIT] and Luau: resets to the initial state of a newly created Lua thread.
/// Lua threads in arbitrary states (like yielded or errored) can be reset properly.
///
/// Sets a Lua function for the thread afterwards.
///
/// Requires `feature = "lua54"` OR `feature = "luajit,vendored"`
/// Requires `feature = "lua54"` OR `feature = "luajit,vendored"` OR `feature = "luau"`
///
/// [Lua 5.4]: https://www.lua.org/manual/5.4/manual.html#lua_resetthread
/// [LuaJIT]: https://github.com/openresty/luajit2#lua_resetthread
#[cfg(any(feature = "lua54", all(feature = "luajit", feature = "vendored")))]
#[cfg(any(
feature = "lua54",
all(feature = "luajit", feature = "vendored"),
feature = "luau",
))]
pub fn reset(&self, func: Function<'lua>) -> Result<()> {
let lua = self.0.lua;
unsafe {

View file

@ -94,7 +94,11 @@ fn test_thread() -> Result<()> {
}
#[test]
#[cfg(any(feature = "lua54", all(feature = "luajit", feature = "vendored")))]
#[cfg(any(
feature = "lua54",
all(feature = "luajit", feature = "vendored"),
feature = "luau",
))]
fn test_thread_reset() -> Result<()> {
use mlua::{AnyUserData, UserData};
use std::sync::Arc;
@ -121,14 +125,14 @@ fn test_thread_reset() -> Result<()> {
assert_eq!(Arc::strong_count(&arc), 1);
}
// Check for errors (Lua 5.4 only)
// Check for errors
let func: Function = lua.load(r#"function(ud) error("test error") end"#).eval()?;
let thread = lua.create_thread(func.clone())?;
let _ = thread.resume::<_, AnyUserData>(MyUserData(arc.clone()));
assert_eq!(thread.status(), ThreadStatus::Error);
assert_eq!(Arc::strong_count(&arc), 2);
#[cfg(feature = "lua54")]
{
let func: Function = lua.load(r#"function(ud) error("test error") end"#).eval()?;
let thread = lua.create_thread(func.clone())?;
let _ = thread.resume::<_, AnyUserData>(MyUserData(arc.clone()));
assert_eq!(thread.status(), ThreadStatus::Error);
assert_eq!(Arc::strong_count(&arc), 2);
assert!(thread.reset(func.clone()).is_err());
// Reset behavior has changed in Lua v5.4.4
// It's became possible to force reset thread by popping error object
@ -140,6 +144,11 @@ fn test_thread_reset() -> Result<()> {
// assert!(thread.reset(func.clone()).is_ok());
// assert_eq!(thread.status(), ThreadStatus::Resumable);
}
#[cfg(any(feature = "lua54", feature = "luau"))]
{
assert!(thread.reset(func.clone()).is_ok());
assert_eq!(thread.status(), ThreadStatus::Resumable);
}
Ok(())
}