O(1) fork_queue pop, See #1277

This commit is contained in:
Cloud Wu
2020-12-16 23:05:52 +08:00
parent 698d032a9b
commit 8022a53e50

View File

@@ -65,7 +65,7 @@ local sleep_session = {}
local watching_session = {}
local error_queue = {}
local fork_queue = {}
local fork_queue = { h = 1, t = 0 }
do ---- request/select
local function send_requests(self)
@@ -429,9 +429,12 @@ function skynet.killthread(thread)
end
end
else
for i = 1, #fork_queue do
local t = fork_queue.t
for i = fork_queue.h, t do
if fork_queue[i] == thread then
tremove(fork_queue, i)
table.move(fork_queue, i+1, t, i)
fork_queue[t] = nil
fork_queue.t = t - 1
return thread
end
end
@@ -517,7 +520,7 @@ function skynet.time()
end
function skynet.exit()
fork_queue = {} -- no fork coroutine can be execute after skynet.exit
fork_queue = { h = 1, t = 0 } -- no fork coroutine can be execute after skynet.exit
skynet.send(".launcher","lua","REMOVE",skynet.self(), false)
-- report the sources that call me
for co, session in pairs(session_coroutine_id) do
@@ -757,7 +760,9 @@ function skynet.fork(func,...)
local args = { ... }
co = co_create(function() func(table.unpack(args,1,n)) end)
end
tinsert(fork_queue, co)
local t = fork_queue.t + 1
fork_queue.t = t
fork_queue[t] = co
return co
end
@@ -828,10 +833,18 @@ end
function skynet.dispatch_message(...)
local succ, err = pcall(raw_dispatch_message,...)
while true do
local co = tremove(fork_queue,1)
if co == nil then
if fork_queue.h > fork_queue.t then
-- queue is empty
fork_queue.h = 1
fork_queue.t = 0
break
end
-- pop queue
local h = fork_queue.h
local co = fork_queue[h]
fork_queue[h] = nil
fork_queue.h = h + 1
local fork_succ, fork_err = pcall(suspend,co,coroutine_resume(co))
if not fork_succ then
if succ then