Fixed broken threads for love

This commit is contained in:
Ryan Ward 2023-01-20 00:11:55 -05:00
parent 0994ee2d2a
commit ef9267d8fc
2 changed files with 43 additions and 71 deletions

View File

@ -32,7 +32,7 @@ local find_optimization = false
local threadManager local threadManager
if not _G["$multi"] then if not _G["$multi"] then
_G["$multi"] = {multi=multi,thread=thread} _G["$multi"] = {multi = multi, thread = thread}
end end
multi.Version = "16.0.0" multi.Version = "16.0.0"
@ -140,23 +140,7 @@ end
function multi.ForEach(tab,func) function multi.ForEach(tab,func)
for i=1,#tab do func(tab[i]) end for i=1,#tab do func(tab[i]) end
end end
local CRef = {
Fire = function() end
}
--[[
cn(function(...)
local data = pack(obj1(...))
local len = #data
if len ~= 0 then
if data[1] == true then
obj2:Fire(...)
else
obj2:Fire(unpack(data))
end
end
end)
]]
local optimization_stats = {} local optimization_stats = {}
local ignoreconn = true local ignoreconn = true
function multi:newConnection(protect, func, kill) function multi:newConnection(protect, func, kill)
@ -849,7 +833,7 @@ function multi:newTLoop(func,set)
end end
function multi:setTimeout(func, t) function multi:setTimeout(func, t)
thread:newThread("TimeoutThread",function() thread.sleep(t) func() end) thread:newThread("TimeoutThread", function() thread.sleep(t) func() end)
end end
function multi:newTStep(start,reset,count,set) function multi:newTStep(start,reset,count,set)
@ -901,23 +885,18 @@ end
local tasks = {} local tasks = {}
local _tasks = 0 local _tasks = 0
local function _task_handler() local function _task_handler(self, func)
tasks[#tasks + 1] = func tasks[#tasks + 1] = func
_tasks = _tasks + 1 _tasks = _tasks + 1
end end
function multi:newTask(func) function multi:newTask(func)
thread:newThread("Task Handler",function() multi:newLoop(function(loop)
while true do for i=1,_tasks do
thread.hold(function() tasks[i]()
return _tasks > 0
end)
for i=1,_tasks do
tasks[i]()
end
_tasks = 0
end end
end) _tasks = 0
end):setName("Task Handler")
-- Re bind this method to use the one that doesn't init a thread! -- Re bind this method to use the one that doesn't init a thread!
multi.newTask = _task_handler multi.newTask = _task_handler
tasks[#tasks + 1] = func tasks[#tasks + 1] = func
@ -989,7 +968,7 @@ function multi:newProcessor(name, nothread)
c.startme = {} c.startme = {}
c.parent = self c.parent = self
local handler = c:createHandler(c.threads, c.startme) local handler = c:createHandler(c)
if not nothread then -- Don't create a loop if we are triggering this manually if not nothread then -- Don't create a loop if we are triggering this manually
c.process = self:newLoop(function() c.process = self:newLoop(function()
@ -1362,21 +1341,17 @@ end
-- A cross version way to set enviroments, not the same as fenv though -- A cross version way to set enviroments, not the same as fenv though
function multi.setEnv(func,env) function multi.setEnv(func,env)
local f = string.dump(func) local f = string.dump(func)
local chunk = load(f,"env","bt",env) local chunk = load(f, "env", "bt", env)
return chunk return chunk
end end
local threads = {} function thread:newThread(name, func, ...)
local startme = {}
local startme_len = 0
function thread:newThread(name,func,...)
multi.OnLoad:Fire() -- This was done incase a threaded function was called before mainloop/uManager was called multi.OnLoad:Fire() -- This was done incase a threaded function was called before mainloop/uManager was called
local func = func or name local func = func or name
if func == name then if func == name then
name = name or multi.randomString(16) name = name or multi.randomString(16)
end end
local c={nil,nil,nil,nil,nil,nil,nil} local c={nil,nil,nil,nil,nil,nil,nil}
local env = {self=c}
c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil} c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
c.startArgs = {...} c.startArgs = {...}
c.ref={} c.ref={}
@ -1404,7 +1379,7 @@ function thread:newThread(name,func,...)
local resumed = false local resumed = false
function c:Pause() function c:Pause()
if not self._isPaused then if not self._isPaused then
thread.request(self,"exec",function() thread.request(self, "exec", function()
thread.hold(function() thread.hold(function()
return resumed return resumed
end) end)
@ -1427,7 +1402,7 @@ function thread:newThread(name,func,...)
end end
function c:Sleep(n) function c:Sleep(n)
thread.request(self, "exec",function() thread.request(self, "exec", function()
thread.sleep(n) thread.sleep(n)
resumed = false resumed = false
end) end)
@ -1435,7 +1410,7 @@ function thread:newThread(name,func,...)
end end
function c:Hold(n,opt) function c:Hold(n,opt)
thread.request(self, "exec",function() thread.request(self, "exec", function()
thread.hold(n, opt) thread.hold(n, opt)
resumed = false resumed = false
end) end)
@ -1443,16 +1418,21 @@ function thread:newThread(name,func,...)
end end
c.Destroy = c.Kill c.Destroy = c.Kill
if thread.isThread() then
if self.Type == "process" then multi:newLoop(function(loop)
multi.print("Creating thread (" .. self.Name .."):", name) if self.Type == "process" then
table.insert(self.startme, c) table.insert(self.startme, c)
else
table.insert(threadManager.startme, c)
end
loop:Break()
end)
else else
multi.print("Creating thread (Global_Thread_Manager):", name) if self.Type == "process" then
if type(name) == "function" then table.insert(self.startme, c)
multi.print(debug.traceback()) else
table.insert(threadManager.startme, c)
end end
table.insert(threadManager.startme, c)
end end
globalThreads[c] = multi globalThreads[c] = multi
@ -1474,8 +1454,8 @@ function thread:newISOThread(name, func, _env, ...)
if type(name) == "function" then if type(name) == "function" then
name = "Thread#"..threadCount name = "Thread#"..threadCount
end end
local func = isolateFunction(func,env) local func = isolateFunction(func, env)
return thread:newThread(name,func,...) return thread:newThread(name, func, ...)
end end
multi.newThread = thread.newThread multi.newThread = thread.newThread
@ -1631,16 +1611,17 @@ co_status = {
end, end,
} }
function multi:createHandler(threads,startme) function multi:createHandler()
return coroutine.wrap(function(self) local threads, startme = self.threads, self.startme
return coroutine.wrap(function()
local temp_start local temp_start
while true do while true do
for start = #startme, 1, -1 do for start = #startme, 1, -1 do
temp_start = startme[start] temp_start = startme[start]
table.remove(startme) table.remove(startme)
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = resume(temp_start.thread,unpack(temp_start.startArgs)) _, ret, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16 = resume(temp_start.thread, unpack(temp_start.startArgs))
co_status[status(temp_start.thread)](temp_start.thread,temp_start,t_none,nil,threads) -- Make sure there was no error co_status[status(temp_start.thread)](temp_start.thread, temp_start, t_none, nil, threads)
table.insert(threads,temp_start) table.insert(threads, temp_start)
yield() yield()
end end
for i=#threads,1,-1 do for i=#threads,1,-1 do
@ -1649,7 +1630,7 @@ function multi:createHandler(threads,startme)
task = ref.task task = ref.task
thd = ref.thread thd = ref.thread
ready = ref.__ready ready = ref.__ready
co_status[status(thd)](thd,ref,task,i,threads) co_status[status(thd)](thd, ref, task, i, threads)
end end
yield() yield()
end end
@ -1676,7 +1657,7 @@ function multi:newService(func) -- Priority managed threads
time = self:newTimer() time = self:newTimer()
time:Start() time:Start()
active = true active = true
c:OnStarted(c,Service_Data) c:OnStarted(c, Service_Data)
end end
return c return c
end end
@ -1685,7 +1666,7 @@ function multi:newService(func) -- Priority managed threads
thread.hold(function() thread.hold(function()
return active return active
end) end)
func(c,Service_Data) func(c, Service_Data)
task(ap) task(ap)
return c return c
end end

View File

@ -25,7 +25,7 @@ require("love.timer")
require("love.system") require("love.system")
require("love.data") require("love.data")
require("love.thread") require("love.thread")
local multi, thread = require("multi").init() local multi, thread = require("multi"):init()
local threads = {} local threads = {}
function threads.loadDump(d) function threads.loadDump(d)
@ -180,20 +180,11 @@ function threads.getConsole()
end end
if not ISTHREAD then if not ISTHREAD then
local clock = os.clock
local lastproc = clock()
local queue = love.thread.getChannel("__CONSOLE__") local queue = love.thread.getChannel("__CONSOLE__")
thread:newThread("consoleManager",function() multi:newLoop(function(loop)
while true do dat = queue:pop()
thread.yield() if dat then
dat = queue:pop() print(unpack(dat))
if dat then
lastproc = clock()
print(unpack(dat))
end
if clock()-lastproc>2 then
thread.sleep(.1)
end
end end
end) end)
end end