mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(stream): do not close handle if it is already closing (#26537)
uv_close asserts that a handle is not already closing. We can guard against this assertion failure by manually checking the handle's closing status ourselves.
This commit is contained in:
parent
2c96f1c4f0
commit
1907abb4c2
@ -128,15 +128,22 @@ void stream_may_close(Stream *stream)
|
|||||||
void stream_close_handle(Stream *stream)
|
void stream_close_handle(Stream *stream)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
|
uv_handle_t *handle = NULL;
|
||||||
if (stream->uvstream) {
|
if (stream->uvstream) {
|
||||||
if (uv_stream_get_write_queue_size(stream->uvstream) > 0) {
|
if (uv_stream_get_write_queue_size(stream->uvstream) > 0) {
|
||||||
WLOG("closed Stream (%p) with %zu unwritten bytes",
|
WLOG("closed Stream (%p) with %zu unwritten bytes",
|
||||||
(void *)stream,
|
(void *)stream,
|
||||||
uv_stream_get_write_queue_size(stream->uvstream));
|
uv_stream_get_write_queue_size(stream->uvstream));
|
||||||
}
|
}
|
||||||
uv_close((uv_handle_t *)stream->uvstream, close_cb);
|
handle = (uv_handle_t *)stream->uvstream;
|
||||||
} else {
|
} else {
|
||||||
uv_close((uv_handle_t *)&stream->uv.idle, close_cb);
|
handle = (uv_handle_t *)&stream->uv.idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(handle != NULL);
|
||||||
|
|
||||||
|
if (!uv_is_closing(handle)) {
|
||||||
|
uv_close(handle, close_cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
local helpers = require('test.functional.helpers')(after_each)
|
local helpers = require('test.functional.helpers')(after_each)
|
||||||
|
local thelpers = require('test.functional.terminal.helpers')
|
||||||
local clear, eq, eval, exc_exec, feed_command, feed, insert, neq, next_msg, nvim,
|
local clear, eq, eval, exc_exec, feed_command, feed, insert, neq, next_msg, nvim,
|
||||||
testprg, ok, source, write_file, mkdir, rmdir = helpers.clear,
|
testprg, ok, source, write_file, mkdir, rmdir = helpers.clear,
|
||||||
helpers.eq, helpers.eval, helpers.exc_exec, helpers.feed_command, helpers.feed,
|
helpers.eq, helpers.eval, helpers.exc_exec, helpers.feed_command, helpers.feed,
|
||||||
@ -1140,6 +1141,31 @@ describe('jobs', function()
|
|||||||
command('call jobstop(' .. other_jobid .. ')')
|
command('call jobstop(' .. other_jobid .. ')')
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('does not close the same handle twice on exit #25086', function()
|
||||||
|
local filename = string.format('%s.lua', helpers.tmpname())
|
||||||
|
write_file(filename, [[
|
||||||
|
vim.api.nvim_create_autocmd('VimLeavePre', {
|
||||||
|
callback = function()
|
||||||
|
local id = vim.fn.jobstart('sleep 0')
|
||||||
|
vim.fn.jobwait({id})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
]])
|
||||||
|
|
||||||
|
local screen = thelpers.setup_child_nvim({
|
||||||
|
'-i', 'NONE',
|
||||||
|
'-u', filename,
|
||||||
|
'+q'
|
||||||
|
})
|
||||||
|
|
||||||
|
screen:expect{grid=[[
|
||||||
|
|
|
||||||
|
[Process exited 0]{1: } |
|
||||||
|
|*4
|
||||||
|
{3:-- TERMINAL --} |
|
||||||
|
]]}
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe("pty process teardown", function()
|
describe("pty process teardown", function()
|
||||||
|
Loading…
Reference in New Issue
Block a user