local _sleeping = {
times = {}, -- list with wake-up times (睡眠时间由小到大)
cos = {}, -- list with coroutines, index matches the 'times' list (co按睡眠时间由小到大排列)
lethargy = {}, -- list of coroutines sleeping without a wakeup time
insert = fnil,
remove = fnil,
-- 把co加到队列中,
push = function(self, sleeptime, co)
if not co then return end
if sleeptime<0 then -- 如果睡眠时间小于0(没有唤醒时间),则放入lethargy队列中
--sleep until explicit wakeup through copas.wakeup
self.lethargy[co] = true
return
else
sleeptime = gettime() + sleeptime
end
local t, c = self.times, self.cos
local i, cou = 1, #t
--TODO: do a binary search
-- 将co按睡眠时间由小到大的顺序插入队列中
while i<=cou and t[i]<=sleeptime do i=i+1 end
table.insert(t, i, sleeptime)
table.insert(c, i, co)
end,
-- 返回睡眠时间最短的co与当前时间的差值(还需多久唤醒,当为负值时返回0)
getnext = function(self) -- returns delay until next sleep expires, or nil if there is none
local t = self.times
local delay = t[1] and t[1] - gettime() or nil
return delay and math.max(delay, 0) or nil
end,
-- find the thread that should wake up to the time
-- 返回第一个到达唤醒时间的co,同时从队列中移除
pop = function(self, time)
local t, c = self.times, self.cos
if #t==0 or time<t[1] then return end
local co = c[1]
table.remove(t, 1)
table.remove(c, 1)
return co
end,
-- 唤醒一个co。
-- 如果在lethargy队列中找到,则将其从lethargy队列中移除,并push到cos队列中,且睡眠时间参数为0(表示立即唤醒)
-- 如果在cos队列中找到,则先将其从cos队列中移除,然后以睡眠时间参数为0重新插入到cos队列中(表示立即唤醒)
wakeup = function(self, co)
local let = self.lethargy
if let[co] then
self:push(0, co)
let[co] = nil
else
let = self.cos
for i=1,#let do
if let[i]==co then
table.remove(let, i)
table.remove(self.times, i)
self:push(0, co)
return
end
end
end
end
} --_sleeping
times = {}, -- list with wake-up times (睡眠时间由小到大)
cos = {}, -- list with coroutines, index matches the 'times' list (co按睡眠时间由小到大排列)
lethargy = {}, -- list of coroutines sleeping without a wakeup time
insert = fnil,
remove = fnil,
-- 把co加到队列中,
push = function(self, sleeptime, co)
if not co then return end
if sleeptime<0 then -- 如果睡眠时间小于0(没有唤醒时间),则放入lethargy队列中
--sleep until explicit wakeup through copas.wakeup
self.lethargy[co] = true
return
else
sleeptime = gettime() + sleeptime
end
local t, c = self.times, self.cos
local i, cou = 1, #t
--TODO: do a binary search
-- 将co按睡眠时间由小到大的顺序插入队列中
while i<=cou and t[i]<=sleeptime do i=i+1 end
table.insert(t, i, sleeptime)
table.insert(c, i, co)
end,
-- 返回睡眠时间最短的co与当前时间的差值(还需多久唤醒,当为负值时返回0)
getnext = function(self) -- returns delay until next sleep expires, or nil if there is none
local t = self.times
local delay = t[1] and t[1] - gettime() or nil
return delay and math.max(delay, 0) or nil
end,
-- find the thread that should wake up to the time
-- 返回第一个到达唤醒时间的co,同时从队列中移除
pop = function(self, time)
local t, c = self.times, self.cos
if #t==0 or time<t[1] then return end
local co = c[1]
table.remove(t, 1)
table.remove(c, 1)
return co
end,
-- 唤醒一个co。
-- 如果在lethargy队列中找到,则将其从lethargy队列中移除,并push到cos队列中,且睡眠时间参数为0(表示立即唤醒)
-- 如果在cos队列中找到,则先将其从cos队列中移除,然后以睡眠时间参数为0重新插入到cos队列中(表示立即唤醒)
wakeup = function(self, co)
local let = self.lethargy
if let[co] then
self:push(0, co)
let[co] = nil
else
let = self.cos
for i=1,#let do
if let[i]==co then
table.remove(let, i)
table.remove(self.times, i)
self:push(0, co)
return
end
end
end
end
} --_sleeping