O(1) fork_queue pop, See
@@ -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
