Add missing task.cancel API

This commit is contained in:
Filip Tibell 2023-01-21 17:23:39 -05:00
parent 3689eb17d2
commit 8ab5855ccc
No account linked to committer's email address
6 changed files with 37 additions and 2 deletions

View file

@ -74,6 +74,7 @@ globals:
- required: false - required: false
type: table type: table
# Task # Task
task.cancel:
task.defer: task.defer:
args: args:
- type: thread | function - type: thread | function

View file

@ -53,6 +53,7 @@ declare process: {
} }
declare task: { declare task: {
cancel: (t: thread) -> (),
defer: <A..., R...>(f: thread | (A...) -> (R...), A...) -> (R...), defer: <A..., R...>(f: thread | (A...) -> (R...), A...) -> (R...),
delay: <A..., R...>(duration: number?, f: thread | (A...) -> (R...), A...) -> (R...), delay: <A..., R...>(duration: number?, f: thread | (A...) -> (R...), A...) -> (R...),
spawn: <A..., R...>(f: thread | (A...) -> (R...), A...) -> (R...), spawn: <A..., R...>(f: thread | (A...) -> (R...), A...) -> (R...),

View file

@ -21,6 +21,10 @@ pub struct WaitingThread<'a> {
pub fn new<'a>(lua: &'a Lua, _threads: &Arc<Mutex<Vec<WaitingThread<'a>>>>) -> Result<Table<'a>> { pub fn new<'a>(lua: &'a Lua, _threads: &Arc<Mutex<Vec<WaitingThread<'a>>>>) -> Result<Table<'a>> {
// TODO: Figure out how to insert into threads vec // TODO: Figure out how to insert into threads vec
ReadonlyTableBuilder::new(lua)? ReadonlyTableBuilder::new(lua)?
.with_function("cancel", |lua, thread: Thread| {
thread.reset(lua.create_function(|_, _: ()| Ok(()))?)?;
Ok(())
})?
.with_async_function( .with_async_function(
"defer", "defer",
|lua, (func, args): (Function, Variadic<Value>)| async move { |lua, (func, args): (Function, Variadic<Value>)| async move {
@ -31,7 +35,7 @@ pub fn new<'a>(lua: &'a Lua, _threads: &Arc<Mutex<Vec<WaitingThread<'a>>>>) -> R
)? )?
.with_async_function( .with_async_function(
"delay", "delay",
|lua, (func, duration, args): (Function, Option<f32>, Variadic<Value>)| async move { |lua, (duration, func, args): (Option<f32>, Function, Variadic<Value>)| async move {
let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION); let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION);
time::sleep(Duration::from_secs_f32(secs)).await; time::sleep(Duration::from_secs_f32(secs)).await;
let thread = lua.create_thread(func)?; let thread = lua.create_thread(func)?;

View file

@ -81,6 +81,7 @@ mod tests {
net_request_redirect: "net/request/redirect", net_request_redirect: "net/request/redirect",
net_json_decode: "net/json/decode", net_json_decode: "net/json/decode",
net_json_encode: "net/json/encode", net_json_encode: "net/json/encode",
task_cancel: "task/cancel",
task_defer: "task/defer", task_defer: "task/defer",
task_delay: "task/delay", task_delay: "task/delay",
task_spawn: "task/spawn", task_spawn: "task/spawn",

View file

@ -1,6 +1,6 @@
use std::future::Future; use std::future::Future;
use mlua::{FromLuaMulti, Lua, Result, Table, ToLuaMulti}; use mlua::{FromLuaMulti, Lua, Result, Table, ToLuaMulti, Value};
pub struct ReadonlyTableBuilder<'lua> { pub struct ReadonlyTableBuilder<'lua> {
lua: &'lua Lua, lua: &'lua Lua,
@ -13,6 +13,11 @@ impl<'lua> ReadonlyTableBuilder<'lua> {
Ok(Self { lua, tab }) Ok(Self { lua, tab })
} }
pub fn with_value(self, key: &'static str, value: Value) -> Result<Self> {
self.tab.raw_set(key, value)?;
Ok(self)
}
pub fn with_table(self, key: &'static str, value: Table) -> Result<Self> { pub fn with_table(self, key: &'static str, value: Table) -> Result<Self> {
self.tab.raw_set(key, value)?; self.tab.raw_set(key, value)?;
Ok(self) Ok(self)

View file

@ -0,0 +1,23 @@
-- Cancel should cancel any deferred or delayed threads
local flag: boolean = false
local thread = task.defer(function()
flag = true
end)
local thread2 = task.delay(0, function()
flag = true
end)
task.cancel(thread)
task.cancel(thread2)
task.wait(0.1)
assert(not flag, "Cancel should handle non-immediate threads")
-- Cancellation should be as immediate as possible
local flag2: number = 1
task.spawn(function()
flag2 = 2
task.wait()
flag2 = 3
end)
assert(flag2 == 2, "Cancel should properly handle yielding threads")