Skip to content

Commit

Permalink
Check handle to close in current loop when loop_gc
Browse files Browse the repository at this point in the history
* Fix #437
* Fix #599
  • Loading branch information
zhaozg committed May 26, 2023
1 parent 16bbffd commit 3d71269
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/luv.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,8 +794,8 @@ LUALIB_API void luv_set_cthread(lua_State* L, luv_CFcpcall cpcall) {

static void walk_cb(uv_handle_t *handle, void *arg)
{
(void)arg;
if (!uv_is_closing(handle)) {
uv_loop_t* loop = arg;
if (handle->loop ==loop && !uv_is_closing(handle)) {
uv_close(handle, luv_close_cb);
}
}
Expand All @@ -806,7 +806,7 @@ static int loop_gc(lua_State *L) {
if (loop==NULL)
return 0;
// Call uv_close on every active handle
uv_walk(loop, walk_cb, NULL);
uv_walk(loop, walk_cb, loop);
// Run the event loop until all handles are successfully closed
while (uv_loop_close(loop)) {
uv_run(loop, UV_RUN_DEFAULT);
Expand Down
22 changes: 22 additions & 0 deletions tests/manual-test-exit.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--come from https://github.com/luvit/luv/issues/599

-- run `lua manual-test-exit.lua || echo $?`
-- it shoud print `5`

local uv = require('luv')

local function setTimeout(callback, ms)
local timer = uv.new_timer()
timer:start(ms, 0, function()
timer:stop()
timer:close()
callback()
end)
return timer
end

setTimeout(function()
os.exit(5, true)
end, 1000)

uv.run()
4 changes: 4 additions & 0 deletions tests/manual-test-without-uv.run.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
local uv = require('luv')

local test = uv.new_pipe(false)
uv.close(test)
28 changes: 28 additions & 0 deletions tests/test-loop.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,32 @@ return require('lib/tap')(function (test)
end))
end)

test("issue #437, crash without uv.run", function (print, p, expect, uv)
local handle
handle = uv.spawn(arg[-1], {
args = { "tests/manual-test-without-uv.run.lua" }
},
expect(function(status, signal)
-- macos status==0
-- linux status==1
assert(status==0 || status==1)
assert(signal==0)
handle:close()
end))
uv.run()
end)

test("issue #599, crash during calling os.exit", function (print, p, expect, uv)
local handle
handle = uv.spawn(arg[-1], {
args = { "tests/manual-test-exit.lua" }
},
expect(function(status, signal)
assert(status==5)
assert(signal==0)
handle:close()
end))
uv.run()
end)

end)

0 comments on commit 3d71269

Please sign in to comment.