mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Add shortcuts to check thread status (Thread::is_resumable(), Thread::is_finished() etc)
This commit is contained in:
@@ -259,6 +259,31 @@ impl Thread {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this thread is resumable (meaning it can be resumed by calling
|
||||
/// [`Thread::resume`]).
|
||||
#[inline(always)]
|
||||
pub fn is_resumable(&self) -> bool {
|
||||
self.status() == ThreadStatus::Resumable
|
||||
}
|
||||
|
||||
/// Returns `true` if this thread is currently running.
|
||||
#[inline(always)]
|
||||
pub fn is_running(&self) -> bool {
|
||||
self.status() == ThreadStatus::Running
|
||||
}
|
||||
|
||||
/// Returns `true` if this thread has finished executing.
|
||||
#[inline(always)]
|
||||
pub fn is_finished(&self) -> bool {
|
||||
self.status() == ThreadStatus::Finished
|
||||
}
|
||||
|
||||
/// Returns `true` if this thread has raised a Lua error during execution.
|
||||
#[inline(always)]
|
||||
pub fn is_error(&self) -> bool {
|
||||
self.status() == ThreadStatus::Error
|
||||
}
|
||||
|
||||
/// Sets a hook function that will periodically be called as Lua code executes.
|
||||
///
|
||||
/// This function is similar or [`Lua::set_hook`] except that it sets for the thread.
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ use futures_util::stream::TryStreamExt;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use mlua::{
|
||||
Error, Function, Lua, LuaOptions, MultiValue, ObjectLike, Result, StdLib, Table, ThreadStatus, UserData,
|
||||
Error, Function, Lua, LuaOptions, MultiValue, ObjectLike, Result, StdLib, Table, UserData,
|
||||
UserDataMethods, UserDataRef, Value,
|
||||
};
|
||||
|
||||
@@ -714,7 +714,7 @@ fn test_async_yield_with() -> Result<()> {
|
||||
assert_eq!(thread.resume::<(i32, i32)>((10, 11))?, (21, 110));
|
||||
assert_eq!(thread.resume::<(i32, i32)>((11, 12))?, (23, 132));
|
||||
assert_eq!(thread.resume::<(i32, i32)>((12, 13))?, (0, 0));
|
||||
assert_eq!(thread.status(), ThreadStatus::Finished);
|
||||
assert!(thread.is_finished());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+4
-4
@@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicI64, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use mlua::debug::DebugEvent;
|
||||
use mlua::{Error, HookTriggers, Lua, Result, ThreadStatus, Value, VmState};
|
||||
use mlua::{Error, HookTriggers, Lua, Result, Value, VmState};
|
||||
|
||||
#[test]
|
||||
fn test_hook_triggers() {
|
||||
@@ -281,14 +281,14 @@ fn test_hook_yield() -> Result<()> {
|
||||
assert!(co.resume::<()>(()).is_ok());
|
||||
assert!(co.resume::<()>(()).is_ok());
|
||||
assert!(co.resume::<()>(()).is_ok());
|
||||
assert!(co.status() == ThreadStatus::Finished);
|
||||
assert!(co.is_finished());
|
||||
}
|
||||
#[cfg(any(feature = "lua51", feature = "lua52", feature = "luajit"))]
|
||||
{
|
||||
assert!(
|
||||
matches!(co.resume::<()>(()), Err(Error::RuntimeError(err)) if err.contains("attempt to yield from a hook"))
|
||||
);
|
||||
assert!(co.status() == ThreadStatus::Error);
|
||||
assert!(co.is_error());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -321,7 +321,7 @@ fn test_global_hook() -> Result<()> {
|
||||
thread.resume::<()>(()).unwrap();
|
||||
lua.remove_global_hook();
|
||||
thread.resume::<()>(()).unwrap();
|
||||
assert_eq!(thread.status(), ThreadStatus::Finished);
|
||||
assert!(thread.is_finished());
|
||||
assert_eq!(counter.load(Ordering::Relaxed), 3);
|
||||
|
||||
Ok(())
|
||||
|
||||
+3
-5
@@ -6,9 +6,7 @@ use std::os::raw::c_void;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU64, Ordering};
|
||||
|
||||
use mlua::{
|
||||
Compiler, Error, Function, Lua, LuaOptions, Result, StdLib, Table, ThreadStatus, Value, Vector, VmState,
|
||||
};
|
||||
use mlua::{Compiler, Error, Function, Lua, LuaOptions, Result, StdLib, Table, Value, Vector, VmState};
|
||||
|
||||
#[test]
|
||||
fn test_version() -> Result<()> {
|
||||
@@ -324,11 +322,11 @@ fn test_interrupts() -> Result<()> {
|
||||
.into_function()?,
|
||||
)?;
|
||||
co.resume::<()>(())?;
|
||||
assert_eq!(co.status(), ThreadStatus::Resumable);
|
||||
assert!(co.is_resumable());
|
||||
let result: i32 = co.resume(())?;
|
||||
assert_eq!(result, 6);
|
||||
assert_eq!(yield_count.load(Ordering::Relaxed), 7);
|
||||
assert_eq!(co.status(), ThreadStatus::Finished);
|
||||
assert!(co.is_finished());
|
||||
|
||||
// Test no yielding at non-yieldable points
|
||||
yield_count.store(0, Ordering::Relaxed);
|
||||
|
||||
+18
-18
@@ -1,6 +1,6 @@
|
||||
use std::panic::catch_unwind;
|
||||
|
||||
use mlua::{Error, Function, IntoLua, Lua, Result, Thread, ThreadStatus, Value};
|
||||
use mlua::{Error, Function, IntoLua, Lua, Result, Thread, Value};
|
||||
|
||||
#[test]
|
||||
fn test_thread() -> Result<()> {
|
||||
@@ -21,17 +21,17 @@ fn test_thread() -> Result<()> {
|
||||
.eval()?,
|
||||
)?;
|
||||
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
assert_eq!(thread.resume::<i64>(0)?, 0);
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
assert_eq!(thread.resume::<i64>(1)?, 1);
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
assert_eq!(thread.resume::<i64>(2)?, 3);
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
assert_eq!(thread.resume::<i64>(3)?, 6);
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
assert_eq!(thread.resume::<i64>(4)?, 10);
|
||||
assert_eq!(thread.status(), ThreadStatus::Finished);
|
||||
assert!(thread.is_finished());
|
||||
|
||||
let accumulate = lua.create_thread(
|
||||
lua.load(
|
||||
@@ -50,9 +50,9 @@ fn test_thread() -> Result<()> {
|
||||
accumulate.resume::<()>(i)?;
|
||||
}
|
||||
assert_eq!(accumulate.resume::<i64>(4)?, 10);
|
||||
assert_eq!(accumulate.status(), ThreadStatus::Resumable);
|
||||
assert!(accumulate.is_resumable());
|
||||
assert!(accumulate.resume::<()>("error").is_err());
|
||||
assert_eq!(accumulate.status(), ThreadStatus::Error);
|
||||
assert!(accumulate.is_error());
|
||||
|
||||
let thread = lua
|
||||
.load(
|
||||
@@ -65,7 +65,7 @@ fn test_thread() -> Result<()> {
|
||||
"#,
|
||||
)
|
||||
.eval::<Thread>()?;
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
assert_eq!(thread.resume::<i64>(())?, 42);
|
||||
|
||||
let thread: Thread = lua
|
||||
@@ -92,7 +92,7 @@ fn test_thread() -> Result<()> {
|
||||
|
||||
// Already running thread must be unresumable
|
||||
let thread = lua.create_thread(lua.create_function(|lua, ()| {
|
||||
assert_eq!(lua.current_thread().status(), ThreadStatus::Running);
|
||||
assert!(lua.current_thread().is_running());
|
||||
let result = lua.current_thread().resume::<()>(());
|
||||
assert!(
|
||||
matches!(result, Err(Error::CoroutineUnresumable)),
|
||||
@@ -123,12 +123,12 @@ fn test_thread_reset() -> Result<()> {
|
||||
assert!(thread.reset(func.clone()).is_ok());
|
||||
|
||||
for _ in 0..2 {
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
let _ = thread.resume::<AnyUserData>(MyUserData(arc.clone()))?;
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
assert_eq!(Arc::strong_count(&arc), 2);
|
||||
thread.resume::<()>(())?;
|
||||
assert_eq!(thread.status(), ThreadStatus::Finished);
|
||||
assert!(thread.is_finished());
|
||||
thread.reset(func.clone())?;
|
||||
lua.gc_collect()?;
|
||||
assert_eq!(Arc::strong_count(&arc), 1);
|
||||
@@ -138,21 +138,21 @@ fn test_thread_reset() -> Result<()> {
|
||||
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!(thread.is_error());
|
||||
assert_eq!(Arc::strong_count(&arc), 2);
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
{
|
||||
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
|
||||
assert!(matches!(thread.status(), ThreadStatus::Finished));
|
||||
assert!(thread.is_finished());
|
||||
assert!(thread.reset(func.clone()).is_ok());
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
}
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "luau"))]
|
||||
{
|
||||
assert!(thread.reset(func.clone()).is_ok());
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
assert!(thread.is_resumable());
|
||||
}
|
||||
|
||||
// Try reset running thread
|
||||
|
||||
Reference in New Issue
Block a user