diff --git a/init.lua b/init.lua index 4959e2a..10ba6d5 100644 --- a/init.lua +++ b/init.lua @@ -1340,7 +1340,7 @@ end function thread.hold(n, opt) thread._Requests() local opt = opt or {} - if type(opt)=="table" then + if type(opt)=="table" and type(n) == "function" then interval = opt.interval if opt.cycles then return yield(CMD, t_holdW, opt.cycles or 1, n or dFunc, interval) @@ -1350,6 +1350,7 @@ function thread.hold(n, opt) return yield(CMD, t_skip, opt.skip or 1, nil, interval) end end + if type(n) == "number" then thread.getRunningThread().lastSleep = clock() return yield(CMD, t_sleep, n or 0, nil, interval) diff --git a/integration/lanesManager/threads.lua b/integration/lanesManager/threads.lua index 6db9b79..2c416ea 100644 --- a/integration/lanesManager/threads.lua +++ b/integration/lanesManager/threads.lua @@ -137,9 +137,19 @@ local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda, __Console) end end + function THREAD.defer(func) + local m = {onexit = function() func() end} + if _VERSION >= "Lua 5.2" then + setmetatable(m, {__gc = m.onexit}) + else + m.sentinel = newproxy(true) + getmetatable(m.sentinel).__gc = m.onexit + end + end + return GLOBAL, THREAD end -return {init = function(g,s,st,c) - return INIT(g,s,st,c) +return {init = function(g,s,st,c,onexit) + return INIT(g,s,st,c,onexit) end} \ No newline at end of file diff --git a/integration/loveManager/threads.lua b/integration/loveManager/threads.lua index d3cec2f..82d12f1 100644 --- a/integration/loveManager/threads.lua +++ b/integration/loveManager/threads.lua @@ -152,6 +152,10 @@ function INIT() end end + function THREAD.defer(func) + multi.OnExit(func) + end + return GLOBAL, THREAD end diff --git a/integration/pseudoManager/threads.lua b/integration/pseudoManager/threads.lua index 2b46982..91a1667 100644 --- a/integration/pseudoManager/threads.lua +++ b/integration/pseudoManager/threads.lua @@ -88,6 +88,8 @@ local function INIT(thread) THREAD.sleep = thread.sleep THREAD.hold = thread.hold + + THREAD.defer = thread.defer function THREAD.setENV(env, name) name = name or "__env" diff --git a/tests/threadtests.lua b/tests/threadtests.lua index 05dc643..3f62321 100644 --- a/tests/threadtests.lua +++ b/tests/threadtests.lua @@ -44,13 +44,32 @@ multi:newThread("Scheduler Thread",function() -- multi:Stop() -- os.exit(1) -- end) + queue = multi:newSystemThreadedQueue("Test_Queue"):init() + defer_queue = multi:newSystemThreadedQueue("Defer_Queue"):init() multi:newSystemThread("Test_Thread_0", function() + defer_queue = THREAD.waitFor("Defer_Queue"):init() + + THREAD.defer(function() + defer_queue:push("done") + multi.print("This function was defered until the end of the threads life") + end) + + multi.print("Testing defer, should print below this") + if THREAD_NAME~="Test_Thread_0" then multi.error("The name should be Test_Thread_0",THREAD_NAME,THREAD_NAME,_G.THREAD_NAME) end end) + + thread:newThread(function() + if thread.hold(function() + return defer_queue:pop() == "done" + end,{sleep=1}) == nil then + multi.error("Thread.defer didn't work!") + end + end) th1 = multi:newSystemThread("Test_Thread_1", function(a,b,c,d,e,f) queue = THREAD.waitFor("Test_Queue"):init()