From 568c95fa7364a0921732ad67e668d3bc122ef888 Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Sat, 16 Apr 2022 00:02:54 -0400 Subject: [PATCH] Issue with love2d system threaded functions pushstatus fixed --- multi/init.lua | 5 +- multi/integration/loveManager/init.lua | 30 ++++++--- multi/integration/loveManager/threads.lua | 6 ++ multi/integration/pesudoManager/init.lua | 3 +- multi/integration/pesudoManager/threads.lua | 9 +-- test.lua | 74 ++++++++++----------- 6 files changed, 71 insertions(+), 56 deletions(-) diff --git a/multi/init.lua b/multi/init.lua index 509e006..cf0d71f 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -948,6 +948,7 @@ function multi:newProcessor(name,nothread) c.threads = {} c.startme = {} c.parent = self + local handler = c:createHandler(c.threads,c.startme) c.process = self:newLoop(function() @@ -1533,7 +1534,7 @@ co_status = { ["suspended"] = function(thd,ref,task,i,th) switch[task](ref,thd) cmds[r1](ref,r2,r3,r4,r5) - if ret~=CMD then -- The rework makes this necessary + if ret ~= CMD and _ ~= nil then -- The rework makes this necessary co_status["dead"](thd,ref,task,i,th) end r1=nil r2=nil r3=nil r4=nil r5=nil @@ -2118,4 +2119,4 @@ else multi.m.sentinel = newproxy(true) getmetatable(multi.m.sentinel).__gc = multi.m.onexit end -return multi +return multi \ No newline at end of file diff --git a/multi/integration/loveManager/init.lua b/multi/integration/loveManager/init.lua index a8508a9..1be7d0d 100644 --- a/multi/integration/loveManager/init.lua +++ b/multi/integration/loveManager/init.lua @@ -62,20 +62,28 @@ function multi:newSystemThread(name,func,...) GLOBAL["__THREAD_COUNT"] = THREAD_ID THREAD_ID=THREAD_ID + 1 thread:newThread(function() - thread.hold(function() - return not c.thread:isRunning() - end) - print("Thread: "..name.." finished executing...") + if name:find("TempSystemThread") then + local status_channel = love.thread.getChannel("__"..c.ID.."__MULTI__STATUS_CHANNEL__") + thread.hold(function() + -- While the thread is running we might as well do something in the loop + local status = status_channel + if status:peek()~=nil then + c.statusconnector:Fire(unpack(status:pop())) + end + return not c.thread:isRunning() + end) + else + thread.hold(function() + return not c.thread:isRunning() + end) + end -- If the thread is not running let's handle that. local thread_err = c.thread:getError() if thread_err == "Thread Killed!\1" then - print("Killed...") c.OnDeath:Fire(c,"Thread Killed!") elseif thread_err then - print("Error...",thread_err) c.OnError:Fire(c,thread_err) elseif c.stab.returns then - print("Returns",unpack(c.stab.returns)) c.OnDeath:Fire(c,unpack(c.stab.returns)) c.stab.returns = nil end @@ -85,18 +93,20 @@ end function THREAD:newFunction(func) return thread:newFunctionBase(function(...) - return multi:newSystemThread("TempSystemThread",func,...) + return multi:newSystemThread("TempSystemThread"..THREAD_ID,func,...) end)() end THREAD.newSystemThread = multi.newSystemThread + function love.threaderror(thread, errorstr) - print("Thread error!\n"..errorstr) + mulit.print("Thread error!\n"..errorstr) end + multi.integration.GLOBAL = GLOBAL multi.integration.THREAD = THREAD require("multi.integration.loveManager.extensions") -print("Integrated Love Threading!") +mulit.print("Integrated Love Threading!") return {init=function() return GLOBAL,THREAD end} \ No newline at end of file diff --git a/multi/integration/loveManager/threads.lua b/multi/integration/loveManager/threads.lua index 8886be7..afcb951 100644 --- a/multi/integration/loveManager/threads.lua +++ b/multi/integration/loveManager/threads.lua @@ -24,6 +24,7 @@ SOFTWARE. require("love.timer") require("love.system") require("love.data") +require("love.thread") local socket = require("socket") local multi, thread = require("multi").init() local threads = {} @@ -94,6 +95,11 @@ end function threads.kill() error("Thread Killed!\1") end +function THREAD.pushStatus(...) + local status_channel = love.thread.getChannel("__"..__THREADID__.."__MULTI__STATUS_CHANNEL__") + local args = {...} + status_channel:push(__THREADID__, args) +end function threads.getThreads() local t = {} for i=1,GLOBAL["__THREAD_COUNT"] do diff --git a/multi/integration/pesudoManager/init.lua b/multi/integration/pesudoManager/init.lua index c93b049..6c19d28 100644 --- a/multi/integration/pesudoManager/init.lua +++ b/multi/integration/pesudoManager/init.lua @@ -32,7 +32,7 @@ if multi.integration then } end -local GLOBAL, THREAD = require("multi.integration.pesudoManager.threads"):init() +local GLOBAL, THREAD = require("multi.integration.pesudoManager.threads"):init(thread) function multi:canSystemThread() -- We are emulating system threading return true @@ -75,6 +75,7 @@ function multi:newSystemThread(name,func,...) end) id = id + 1 end +THREAD.newSystemThread = multi.newSystemThread -- System threads as implemented here cannot share memory, but use a message passing system. -- An isolated thread allows us to mimic that behavior so if access data from the "main" thread happens things will not work. This behavior is in line with how the system threading works diff --git a/multi/integration/pesudoManager/threads.lua b/multi/integration/pesudoManager/threads.lua index 3f97e46..901bef9 100644 --- a/multi/integration/pesudoManager/threads.lua +++ b/multi/integration/pesudoManager/threads.lua @@ -28,7 +28,7 @@ local function getOS() return "unix" end end -local function INIT(env) +local function INIT(env,thread) local THREAD = {} local GLOBAL = {} THREAD.Priority_Core = 3 @@ -45,7 +45,6 @@ local function INIT(env) return GLOBAL[name] end function THREAD.waitFor(name) - print("Waiting",thread) return thread.hold(function() return GLOBAL[name] end) end if getOS() == "windows" then @@ -69,6 +68,7 @@ local function INIT(env) function THREAD.getThreads() return {}--GLOBAL.__THREADS__ end + THREAD.pushstatus = thread.pushstatus if os.getOS() == "windows" then THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS")) else @@ -83,6 +83,7 @@ local function INIT(env) function THREAD.getID() return GLOBAL["$THREAD_ID"] end + THREAD.pushstatus function THREAD.sleep(n) thread.sleep(n) end @@ -91,6 +92,6 @@ local function INIT(env) end return GLOBAL, THREAD end -return {init = function() - return INIT() +return {init = function(thread) + return INIT(nil,thread) end} \ No newline at end of file diff --git a/test.lua b/test.lua index 5668fd6..d17f6cc 100644 --- a/test.lua +++ b/test.lua @@ -2,45 +2,41 @@ package.path = "./?/init.lua;"..package.path multi, thread = require("multi"):init() GLOBAL, THREAD = require("multi.integration.lanesManager"):init() -thread:newThread(function() - func = THREAD:newFunction(function(count) - print("Starting Status test: ",count) - local a = 0 - while true do - a = a + 1 - THREAD.sleep(.1) - THREAD.pushStatus(a,count) - if a == count then break end - end - return "Done" - end) - local ret = func(10) - local ret2 = func(15) - local ret3 = func(20) - local s1,s2,s3 = 0,0,0 - ret.OnError(function(...) - print("Error:",...) - end) - ret2.OnError(function(...) - print("Error:",...) - end) - ret3.OnError(function(...) - print("Error:",...) - end) - ret.OnStatus(function(part,whole) - s1 = math.ceil((part/whole)*1000)/10 - print(s1) - end) - ret2.OnStatus(function(part,whole) - s2 = math.ceil((part/whole)*1000)/10 - print(s2) - end) - ret3.OnStatus(function(part,whole) - s3 = math.ceil((part/whole)*1000)/10 - print(s3) - end) - local err, timeout = thread.hold(ret.OnReturn + ret2.OnReturn + ret3.OnReturn) - print("Done") +func = THREAD:newFunction(function(count) + print("Starting Status test: ",count) + local a = 0 + while true do + a = a + 1 + THREAD.sleep(.1) + THREAD.pushStatus(a,count) + if a == count then break end + end + return "Done" +end) +local ret = func(10) +local ret2 = func(15) +local ret3 = func(20) +local s1,s2,s3 = 0,0,0 +ret.OnError(function(...) + print("Error:",...) +end) +ret2.OnError(function(...) + print("Error:",...) +end) +ret3.OnError(function(...) + print("Error:",...) +end) +ret.OnStatus(function(part,whole) + s1 = math.ceil((part/whole)*1000)/10 + print(s1) +end) +ret2.OnStatus(function(part,whole) + s2 = math.ceil((part/whole)*1000)/10 + print(s2) +end) +ret3.OnStatus(function(part,whole) + s3 = math.ceil((part/whole)*1000)/10 + print(s3) end) -- local proc = multi:newProcessor("Test")