Working on issue where threads created in threads don't work

This commit is contained in:
Ryan Ward 2023-01-19 00:16:32 -05:00
parent 22f1375380
commit 0994ee2d2a
3 changed files with 107 additions and 149 deletions

192
init.lua
View File

@ -22,16 +22,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
traceback = debug.traceback
local multi = {}
local mainloopActive = false
local isRunning = false
local clock = os.clock
local thread = {}
local in_proc = false
local processes = {}
local find_optimization = false
local threadManager
if not _G["$multi"] then
_G["$multi"] = {multi=multi,thread=thread}
@ -387,7 +385,7 @@ function multi:newConnection(protect, func, kill)
if not call_funcs[i] then return end
local suc, err = pcall(call_funcs[i],...)
if not suc then
print(err)
multi.print(err)
end
if kill then
table.remove(call_funcs,i)
@ -667,7 +665,7 @@ function multi:newEvent(task)
end
c.OnEvent = self:newConnection():fastMode()
self:setPriority("core")
c:SetName(c.Type)
c:setName(c.Type)
multi:create(c)
return c
end
@ -689,7 +687,7 @@ function multi:newUpdater(skip)
return self
end
c.OnUpdate = self:newConnection():fastMode()
c:SetName(c.Type)
c:setName(c.Type)
multi:create(c)
return c
end
@ -726,7 +724,7 @@ function multi:newAlarm(set)
self.Parent.Pause(self)
return self
end
c:SetName(c.Type)
c:setName(c.Type)
multi:create(c)
return c
end
@ -751,7 +749,7 @@ function multi:newLoop(func,notime)
end
multi:create(c)
c:SetName(c.Type)
c:setName(c.Type)
return c
end
@ -809,7 +807,7 @@ function multi:newStep(start,reset,count,skip)
self:Resume()
return self
end
c:SetName(c.Type)
c:setName(c.Type)
multi:create(c)
return c
end
@ -845,13 +843,13 @@ function multi:newTLoop(func,set)
if func then
c.OnLoop(func)
end
c:SetName(c.Type)
c:setName(c.Type)
multi:create(c)
return c
end
function multi:setTimeout(func, t)
thread:newThread(function() thread.sleep(t) func() end)
thread:newThread("TimeoutThread",function() thread.sleep(t) func() end)
end
function multi:newTStep(start,reset,count,set)
@ -895,7 +893,7 @@ function multi:newTStep(start,reset,count,set)
self:Resume()
return self
end
c:SetName(c.Type)
c:setName(c.Type)
multi:create(c)
return c
end
@ -909,7 +907,7 @@ local function _task_handler()
end
function multi:newTask(func)
multi:newThread("Task Handler",function()
thread:newThread("Task Handler",function()
while true do
thread.hold(function()
return _tasks > 0
@ -1023,15 +1021,12 @@ function multi:newProcessor(name, nothread)
end
function c:newThread(name, func,...)
in_proc = c
local t = thread.newThread(c,name,func,...)
in_proc = false
return t
return thread.newThread(c, name, func, ...)
end
function c:newFunction(func, holdme)
return thread:newFunctionBase(function(...)
return c:newThread("TempThread",func,...)
return c:newThread("Threaded Function Handler", func, ...)
end, holdme)()
end
@ -1360,7 +1355,7 @@ end
function thread:newFunction(func, holdme)
return thread:newFunctionBase(function(...)
return thread:newThread("TempThread",func,...)
return thread:newThread("Threaded Function Handler", func, ...)
end, holdme)()
end
@ -1450,12 +1445,16 @@ function thread:newThread(name,func,...)
c.Destroy = c.Kill
if self.Type == "process" then
multi.print("Creating thread (" .. self.Name .."):", name)
table.insert(self.startme, c)
else
table.insert(startme,c)
multi.print("Creating thread (Global_Thread_Manager):", name)
if type(name) == "function" then
multi.print(debug.traceback())
end
table.insert(threadManager.startme, c)
end
startme_len = #startme
globalThreads[c] = multi
threadid = threadid + 1
multi:create(c)
@ -1617,7 +1616,6 @@ co_status = {
else
ref.OnError:Fire(ref,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16)
end
print(ref.Name, traceback())
if i then
table.remove(th,i)
else
@ -1632,30 +1630,6 @@ co_status = {
ref.__processed = true
end,
}
handler = coroutine.wrap(function(self)
local temp_start
while true do
for start = #startme, 1, -1 do
temp_start = startme[start]
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))
co_status[status(temp_start.thread)](temp_start.thread,temp_start,t_none,nil,threads) -- Make sure there was no error
table.insert(threads,temp_start)
yield()
end
for i=#threads,1,-1 do
ref = threads[i]
if ref then
task = ref.task
thd = ref.thread
ready = ref.__ready
co_status[status(thd)](thd,ref,task,i,threads)
end
yield()
end
yield()
end
end)
function multi:createHandler(threads,startme)
return coroutine.wrap(function(self)
@ -1716,7 +1690,7 @@ function multi:newService(func) -- Priority managed threads
return c
end
local th = thread:newThread(function()
local th = thread:newThread("Service_Handler",function()
while true do
process()
end
@ -1809,7 +1783,6 @@ local function mainloop(self)
ctask:Act()
__CurrentProcess = self
end
handler()
end
else
return nil, "Already Running!"
@ -1839,13 +1812,65 @@ local function p_mainloop(self)
end
end
end
handler()
end
else
return nil, "Already Running!"
end
end
local function doOpt()
function thread.hold(n,opt)
thread._Requests()
local opt = opt or {}
if type(opt)=="table" then
interval = opt.interval
if opt.cycles then
return yield(CMD, t_holdW, opt.cycles or 1, n or dFunc, interval)
elseif opt.sleep then
return yield(CMD, t_holdF, opt.sleep, n or dFunc, interval)
elseif opt.skip then
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)
elseif type(n) == "table" and n.Type == "connector" then
local rdy = function()
return false
end
n(function(a1,a2,a3,a4,a5,a6)
rdy = function()
if a1==nil then
return NIL,a2,a3,a4,a5,a6
end
return a1,a2,a3,a4,a5,a6
end
end)
return yield(CMD, t_hold, function()
return rdy()
end, nil, interval)
elseif type(n) == "function" then
local cache = string.dump(n)
local f_str = tostring(n)
local good = true
for i=1,#func_cache do
if func_cache[i][1] == cache and func_cache[i][2] ~= f_str and not func_cache[i][3] then
multi:getOptimizationConnection():Fire("It's better to store a function to a variable than to use an anonymous function within the hold method!\n" .. debug.traceback())
func_cache[i][3] = true
good = false
end
end
if good then
table.insert(func_cache, {cache, f_str})
end
return yield(CMD, t_hold, n or dFunc, nil, interval)
else
error("Invalid argument passed to thread.hold(...)!")
end
end
end
local init = false
function multi.init(settings, realsettings)
if settings == multi then settings = realsettings end
@ -1860,23 +1885,23 @@ function multi.init(settings, realsettings)
end
if settings.findopt then
find_optimization = true
doOpt()
multi.enableOptimization:Fire(multi, thread)
end
end
return _G["$multi"].multi,_G["$multi"].thread
end
function multi:uManager(proc)
function multi:uManager()
if self.Active then
__CurrentProcess = self
multi.OnPreLoad:Fire()
self.uManager=self.uManagerRef
multi.OnLoad:Fire()
if not proc then handler() end
end
end
function multi:uManagerRefP1(proc)
function multi:uManagerRefP1()
if self.Active then
__CurrentProcess = self
local Loop=self.Mainloop
@ -1889,11 +1914,10 @@ function multi:uManagerRefP1(proc)
end
end
end
if not proc then handler() end
end
end
function multi:uManagerRef(proc)
function multi:uManagerRef()
if self.Active then
__CurrentProcess = self
local Loop=self.Mainloop
@ -1902,7 +1926,6 @@ function multi:uManagerRef(proc)
__CurrentTask:Act()
__CurrentProcess = self
end
if not proc then handler() end
end
end
@ -2211,64 +2234,7 @@ else
multi.m.sentinel = newproxy(true)
getmetatable(multi.m.sentinel).__gc = multi.m.onexit
end
local func_cache = {}
multi:newThread(function()
thread.skip()
if find_optimization then
function thread.hold(n,opt)
thread._Requests()
local opt = opt or {}
if type(opt)=="table" then
interval = opt.interval
if opt.cycles then
return yield(CMD, t_holdW, opt.cycles or 1, n or dFunc, interval)
elseif opt.sleep then
return yield(CMD, t_holdF, opt.sleep, n or dFunc, interval)
elseif opt.skip then
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)
elseif type(n) == "table" and n.Type == "connector" then
local rdy = function()
return false
end
n(function(a1,a2,a3,a4,a5,a6)
rdy = function()
if a1==nil then
return NIL,a2,a3,a4,a5,a6
end
return a1,a2,a3,a4,a5,a6
end
end)
return yield(CMD, t_hold, function()
return rdy()
end, nil, interval)
elseif type(n) == "function" then
local cache = string.dump(n)
local f_str = tostring(n)
local good = true
for i=1,#func_cache do
if func_cache[i][1] == cache and func_cache[i][2] ~= f_str and not func_cache[i][3] then
multi:getOptimizationConnection():Fire("It's better to store a function to a variable than to use an anonymous function within the hold method!\n" .. debug.traceback())
func_cache[i][3] = true
good = false
end
end
if good then
table.insert(func_cache, {cache, f_str})
end
return yield(CMD, t_hold, n or dFunc, nil, interval)
else
error("Invalid argument passed to thread.hold(...)!")
end
end
-- Add more Overrides
end
end)
threadManager = multi:newProcessor("Global_Thread_Manager").Start()
return multi

View File

@ -20,9 +20,12 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]] if ISTHREAD then
]]
if ISTHREAD then
error("You cannot require the loveManager from within a thread!")
end
local ThreadFileData = [[
ISTHREAD = true
THREAD = require("multi.integration.loveManager.threads")
@ -35,7 +38,7 @@ math.randomseed(__THREADID__)
math.random()
math.random()
math.random()
stab = THREAD.createStaticTable(__THREADNAME__)
stab = THREAD.createStaticTable(__THREADNAME__ .. __THREADID__)
GLOBAL = THREAD.getGlobal()
multi, thread = require("multi").init()
multi.integration={}
@ -68,14 +71,13 @@ function multi:newSystemThread(name, func, ...)
GLOBAL["__THREAD_COUNT"] = THREAD_ID
THREAD_ID = THREAD_ID + 1
function c:getName() return c.name end
thread:newThread(function()
thread:newThread(name .. "_System_Thread_Handler",function()
if name == "TempSystemThread" then
local status_channel = love.thread.getChannel("STATCHAN_" .. c.ID)
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()))
if status_channel:peek() ~= nil then
c.statusconnector:Fire(unpack(status_channel:pop()))
end
return not c.thread:isRunning()
end)
@ -98,7 +100,7 @@ end
function THREAD:newFunction(func, holdme)
return thread:newFunctionBase(function(...)
return multi:newSystemThread("TempSystemThread", func, ...)
return multi:newSystemThread("SystemThreaded Function Handler", func, ...)
end, holdme)()
end

View File

@ -25,7 +25,6 @@ require("love.timer")
require("love.system")
require("love.data")
require("love.thread")
local socket = require("socket")
local multi, thread = require("multi").init()
local threads = {}
@ -49,15 +48,6 @@ local function manage(channel, value)
end
end
local function RandomVariable(length)
local res = {}
math.randomseed(socket.gettime()*10000)
for i = 1, length do
res[#res+1] = string.char(math.random(97, 122))
end
return table.concat(res)
end
local GNAME = "__GLOBAL_"
local proxy = {}
function threads.set(name,val)