mirror of
https://github.com/lune-org/mlua-luau-scheduler.git
synced 2025-04-07 12:00:58 +01:00
Implement thread id struct and some more utils
This commit is contained in:
parent
f4ecf7e018
commit
5820858147
4 changed files with 80 additions and 25 deletions
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
runtime::Runtime,
|
runtime::Runtime,
|
||||||
status::Status,
|
status::Status,
|
||||||
traits::IntoLuaThread,
|
traits::IntoLuaThread,
|
||||||
util::{run_until_yield, ThreadWithArgs},
|
util::{run_until_yield, ThreadResult, ThreadWithArgs},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,7 @@ use crate::{
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Handle {
|
pub struct Handle {
|
||||||
thread: Rc<RefCell<Option<ThreadWithArgs>>>,
|
thread: Rc<RefCell<Option<ThreadWithArgs>>>,
|
||||||
result: Rc<RefCell<Option<(bool, LuaRegistryKey)>>>,
|
result: Rc<RefCell<Option<ThreadResult>>>,
|
||||||
status: Rc<Cell<bool>>,
|
status: Rc<Cell<bool>>,
|
||||||
event: Rc<Event>,
|
event: Rc<Event>,
|
||||||
}
|
}
|
||||||
|
@ -69,24 +69,14 @@ impl Handle {
|
||||||
.into_inner(lua)
|
.into_inner(lua)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set<'lua>(
|
fn set<'lua>(&self, lua: &'lua Lua, result: &LuaResult<LuaMultiValue<'lua>>, is_final: bool) {
|
||||||
&self,
|
self.result
|
||||||
lua: &'lua Lua,
|
.borrow_mut()
|
||||||
result: &LuaResult<LuaMultiValue<'lua>>,
|
.replace(ThreadResult::new(result.clone(), lua));
|
||||||
is_final: bool,
|
|
||||||
) -> LuaResult<()> {
|
|
||||||
self.result.borrow_mut().replace((
|
|
||||||
result.is_ok(),
|
|
||||||
match &result {
|
|
||||||
Ok(v) => lua.create_registry_value(v.clone().into_vec())?,
|
|
||||||
Err(e) => lua.create_registry_value(e.clone())?,
|
|
||||||
},
|
|
||||||
));
|
|
||||||
self.status.replace(is_final);
|
self.status.replace(is_final);
|
||||||
if is_final {
|
if is_final {
|
||||||
self.event.notify(usize::MAX);
|
self.event.notify(usize::MAX);
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,17 +87,15 @@ impl Handle {
|
||||||
- [`Status::NotStarted`]: returns `None`.
|
- [`Status::NotStarted`]: returns `None`.
|
||||||
- [`Status::Running`]: may return `Some(Ok(v))` or `Some(Err(e))`, but it is not guaranteed.
|
- [`Status::Running`]: may return `Some(Ok(v))` or `Some(Err(e))`, but it is not guaranteed.
|
||||||
- [`Status::Completed`]: returns `Some(Ok(v))` or `Some(Err(e))`.
|
- [`Status::Completed`]: returns `Some(Ok(v))` or `Some(Err(e))`.
|
||||||
|
|
||||||
|
Note that this method also takes the value out of the handle, so it may only be called once.
|
||||||
|
|
||||||
|
Any subsequent calls after this method returns `Some` will return `None`.
|
||||||
*/
|
*/
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn result<'lua>(&self, lua: &'lua Lua) -> Option<LuaResult<LuaMultiValue<'lua>>> {
|
pub fn result<'lua>(&self, lua: &'lua Lua) -> Option<LuaResult<LuaMultiValue<'lua>>> {
|
||||||
let res = self.result.borrow();
|
let mut res = self.result.borrow_mut();
|
||||||
let (is_ok, key) = res.as_ref()?;
|
res.take().map(|r| r.value(lua))
|
||||||
Some(if *is_ok {
|
|
||||||
let v = lua.registry_value(key).unwrap();
|
|
||||||
Ok(LuaMultiValue::from_vec(v))
|
|
||||||
} else {
|
|
||||||
Err(lua.registry_value(key).unwrap())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,7 +123,7 @@ impl LuaUserData for Handle {
|
||||||
let (thread, args) = this.take(lua);
|
let (thread, args) = this.take(lua);
|
||||||
let result = run_until_yield(thread.clone(), args).await;
|
let result = run_until_yield(thread.clone(), args).await;
|
||||||
let is_final = thread.status() != LuaThreadStatus::Resumable;
|
let is_final = thread.status() != LuaThreadStatus::Resumable;
|
||||||
this.set(lua, &result, is_final)?;
|
this.set(lua, &result, is_final);
|
||||||
result
|
result
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ mod handle;
|
||||||
mod queue;
|
mod queue;
|
||||||
mod runtime;
|
mod runtime;
|
||||||
mod status;
|
mod status;
|
||||||
|
mod thread_id;
|
||||||
mod traits;
|
mod traits;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
@ -11,4 +12,5 @@ pub use functions::Functions;
|
||||||
pub use handle::Handle;
|
pub use handle::Handle;
|
||||||
pub use runtime::Runtime;
|
pub use runtime::Runtime;
|
||||||
pub use status::Status;
|
pub use status::Status;
|
||||||
|
pub use thread_id::ThreadId;
|
||||||
pub use traits::{IntoLuaThread, LuaRuntimeExt};
|
pub use traits::{IntoLuaThread, LuaRuntimeExt};
|
||||||
|
|
32
lib/thread_id.rs
Normal file
32
lib/thread_id.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
|
use mlua::prelude::*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Opaque and unique ID representing a [`LuaThread`].
|
||||||
|
|
||||||
|
Typically used for associating metadata with a thread in a structure such as a `HashMap<ThreadId, ...>`.
|
||||||
|
|
||||||
|
Note that holding a `ThreadId` does not prevent the thread from being garbage collected.
|
||||||
|
The actual thread may or may not still exist and be active at any given point in time.
|
||||||
|
*/
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct ThreadId(usize);
|
||||||
|
|
||||||
|
impl From<LuaThread<'_>> for ThreadId {
|
||||||
|
fn from(thread: LuaThread) -> Self {
|
||||||
|
Self(LuaValue::Thread(thread).to_pointer() as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&LuaThread<'_>> for ThreadId {
|
||||||
|
fn from(thread: &LuaThread) -> Self {
|
||||||
|
Self(LuaValue::Thread(thread.clone()).to_pointer() as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash for ThreadId {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.0.hash(state);
|
||||||
|
}
|
||||||
|
}
|
33
lib/util.rs
33
lib/util.rs
|
@ -21,6 +21,39 @@ pub(crate) async fn run_until_yield<'lua>(
|
||||||
stream.next().await.unwrap()
|
stream.next().await.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Representation of a [`LuaResult`] with an associated [`LuaMultiValue`] currently stored in the Lua registry.
|
||||||
|
*/
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct ThreadResult {
|
||||||
|
inner: LuaResult<LuaRegistryKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ThreadResult {
|
||||||
|
pub fn new(result: LuaResult<LuaMultiValue>, lua: &Lua) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: match result {
|
||||||
|
Ok(v) => Ok({
|
||||||
|
let vec = v.into_vec();
|
||||||
|
lua.create_registry_value(vec).expect("out of memory")
|
||||||
|
}),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(self, lua: &Lua) -> LuaResult<LuaMultiValue> {
|
||||||
|
match self.inner {
|
||||||
|
Ok(key) => {
|
||||||
|
let vec = lua.registry_value(&key).unwrap();
|
||||||
|
lua.remove_registry_value(key).unwrap();
|
||||||
|
Ok(LuaMultiValue::from_vec(vec))
|
||||||
|
}
|
||||||
|
Err(e) => Err(e.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Representation of a [`LuaThread`] with its associated arguments currently stored in the Lua registry.
|
Representation of a [`LuaThread`] with its associated arguments currently stored in the Lua registry.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue