Skip to content

Commit 816a1e3

Browse files
committed
impl croutine.close
1 parent 13ead7b commit 816a1e3

File tree

1 file changed

+29
-17
lines changed

1 file changed

+29
-17
lines changed

resources/luajitCompact.lua

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ local getmetatable = getmetatable
44
local xpcall = xpcall
55
local math_floor = math.floor
66
local math_ceil = math.ceil
7+
local coroutine_resume = coroutine.resume
8+
local coroutine_status = coroutine.status
9+
local coroutine_running = coroutine.running
10+
local coroutine_create = coroutine.create
11+
local yield = coroutine.yield
12+
local pcall = pcall
13+
local unpack = unpack
714

815
table.unpack = unpack
916

@@ -36,45 +43,50 @@ function math.type(x)
3643
end
3744
end
3845

39-
local coroutine_resume = coroutine.resume
40-
local coroutine_status = coroutine.status
41-
local coroutine_running = coroutine.running
46+
4247

4348
local cancel_table = setmetatable({}, { __mode = 'kv' })
4449

4550
function coroutine.resume(co, ...)
46-
if cancel_table[co] then
47-
return false, 'cannot resume dead coroutine'
51+
local results = { pcall(coroutine_resume, co, ...) }
52+
local ok = results[1]
53+
if not ok then
54+
local reason = results[2]
55+
if reason == "cancel" then
56+
return false, 'cannot resume dead coroutine'
57+
end
4858
end
4959

50-
return coroutine_resume(co, ...)
60+
return ok, unpack(results, 2)
5161
end
5262

53-
function coroutine.status(co)
54-
if cancel_table[co] then
55-
return 'dead'
56-
end
63+
-- donot return 'dead' status
64+
-- function coroutine.status(co)
65+
-- return coroutine_status(co)
66+
-- end
5767

58-
return coroutine_status(co)
68+
-- 要实现取消, 只能在协程内的调用通过错误让协程消亡
69+
function coroutine.yield(...)
70+
if cancel_table[coroutine_running()] then
71+
error("cancel")
72+
end
73+
return yield(...)
5974
end
6075

6176
function coroutine.close(co)
6277
if coroutine_status(co) == 'suspended' then
6378
cancel_table[co] = true
79+
return true
6480
end
81+
return false
6582
end
6683

6784
function defer(toBeClosed, callback)
6885
local ctype = type(toBeClosed)
6986
local meta = getmetatable(toBeClosed)
70-
local closeCallback = nil
7187
local ok, result
7288

73-
local co = coroutine_running()
74-
if coroutine.status(co) ~= 'dead' then
75-
ok, result = xpcall(callback, log.error)
76-
end
77-
89+
ok, result = xpcall(callback, log.error)
7890
if meta and meta.__close then
7991
meta.__close(toBeClosed)
8092
elseif ctype == 'function' then

0 commit comments

Comments
 (0)