mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
fix(client): avoid :connect race with server detach
Also fix some warnings and flakiness in :restart/:connect tests.
This commit is contained in:
@@ -290,6 +290,8 @@ void ui_client_event_connect(Array args)
|
|||||||
|
|
||||||
char *server_addr = args.items[0].data.string.data;
|
char *server_addr = args.items[0].data.string.data;
|
||||||
multiqueue_put(main_loop.fast_events, channel_connect_event, server_addr);
|
multiqueue_put(main_loop.fast_events, channel_connect_event, server_addr);
|
||||||
|
// Set a dummy channel ID to prevent client exit when server detaches.
|
||||||
|
ui_client_channel_id = UINT64_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void channel_connect_event(void **argv)
|
static void channel_connect_event(void **argv)
|
||||||
@@ -302,15 +304,16 @@ static void channel_connect_event(void **argv)
|
|||||||
uint64_t chan = channel_connect(is_tcp, server_addr, true, on_data, 50, &err);
|
uint64_t chan = channel_connect(is_tcp, server_addr, true, on_data, 50, &err);
|
||||||
|
|
||||||
if (!strequal(err, "")) {
|
if (!strequal(err, "")) {
|
||||||
ELOG("Error handling UI event 'connect': %s", err);
|
ELOG("Cannot connect to server %s: %s", server_addr, err);
|
||||||
return;
|
ui_client_exit_status = 1;
|
||||||
|
os_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_client_channel_id = chan;
|
ui_client_channel_id = chan;
|
||||||
ui_client_is_remote = true;
|
ui_client_is_remote = true;
|
||||||
ui_client_attach(tui_width, tui_height, tui_term, tui_rgb);
|
ui_client_attach(tui_width, tui_height, tui_term, tui_rgb);
|
||||||
|
|
||||||
ELOG("Connected to channel: %" PRId64, chan);
|
ILOG("Connected to server %s on channel %" PRId64, server_addr, chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When a "restart" UI event is received, its arguments are saved here when
|
/// When a "restart" UI event is received, its arguments are saved here when
|
||||||
|
@@ -318,6 +318,7 @@ describe('TUI :restart', function()
|
|||||||
|
|
||||||
-- Cancel the operation (abandons restart).
|
-- Cancel the operation (abandons restart).
|
||||||
tt.feed_data('C\013')
|
tt.feed_data('C\013')
|
||||||
|
screen:expect({ any = vim.pesc('[No Name]') })
|
||||||
|
|
||||||
-- Check ":confirm restart <cmd>" on a modified buffer.
|
-- Check ":confirm restart <cmd>" on a modified buffer.
|
||||||
tt.feed_data(':confirm restart echo "Hello"\013')
|
tt.feed_data(':confirm restart echo "Hello"\013')
|
||||||
@@ -370,6 +371,12 @@ describe('TUI :connect', function()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local screen_empty = [[
|
||||||
|
^ |
|
||||||
|
{100:~ }|*5
|
||||||
|
|
|
||||||
|
]]
|
||||||
|
|
||||||
it('leaves the current server running', function()
|
it('leaves the current server running', function()
|
||||||
n.clear()
|
n.clear()
|
||||||
finally(function()
|
finally(function()
|
||||||
@@ -377,61 +384,45 @@ describe('TUI :connect', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
local server1 = new_pipename()
|
local server1 = new_pipename()
|
||||||
local screen = tt.setup_child_nvim({
|
local screen1 = tt.setup_child_nvim({ '--listen', server1, '--clean' })
|
||||||
'--listen',
|
screen1:expect({ any = vim.pesc('[No Name]') })
|
||||||
server1,
|
|
||||||
'-u',
|
|
||||||
'NONE',
|
|
||||||
})
|
|
||||||
|
|
||||||
tt.feed_data(':connect\013')
|
tt.feed_data(':connect\013')
|
||||||
screen:expect([[
|
screen1:expect({ any = 'E471: Argument required' })
|
||||||
^ |
|
|
||||||
~ |*3
|
|
||||||
[No Name] 0,0-1 All|
|
|
||||||
E471: Argument required |
|
|
||||||
{5:-- TERMINAL --} |
|
|
||||||
]])
|
|
||||||
|
|
||||||
screen:detach()
|
tt.feed_data('iThis is server 1.\027')
|
||||||
|
screen1:expect({ any = vim.pesc('This is server 1^.') })
|
||||||
|
|
||||||
|
-- Prevent screen2 from receiving the old terminal state.
|
||||||
|
command('enew')
|
||||||
|
screen1:expect(screen_empty)
|
||||||
|
screen1:detach()
|
||||||
|
|
||||||
local server2 = new_pipename()
|
local server2 = new_pipename()
|
||||||
local screen2 = tt.setup_child_nvim({
|
local screen2 = tt.setup_child_nvim({ '--listen', server2, '--clean' })
|
||||||
'--listen',
|
screen2:expect({ any = vim.pesc('[No Name]') })
|
||||||
server2,
|
|
||||||
'-u',
|
|
||||||
'NONE',
|
|
||||||
})
|
|
||||||
tt.feed_data('iThis is server 2.\027')
|
|
||||||
tt.feed_data(':connect ' .. server1 .. '\013')
|
|
||||||
|
|
||||||
screen2:expect({
|
tt.feed_data('iThis is server 2.\027')
|
||||||
any = [[Process exited]],
|
screen2:expect({ any = vim.pesc('This is server 2^.') })
|
||||||
})
|
|
||||||
|
tt.feed_data(':connect ' .. server1 .. '\013')
|
||||||
|
screen2:expect({ any = vim.pesc('This is server 1^.') })
|
||||||
|
|
||||||
local server1_session = n.connect(server1)
|
local server1_session = n.connect(server1)
|
||||||
server1_session:request('nvim_command', 'qall!')
|
server1_session:request('nvim_command', 'qall!')
|
||||||
|
screen2:expect({ any = [[Process exited]] })
|
||||||
|
|
||||||
screen2:detach()
|
screen2:detach()
|
||||||
|
|
||||||
local server2_session = n.connect(server2)
|
local server2_session = n.connect(server2)
|
||||||
|
|
||||||
local screen3 = tt.setup_child_nvim({
|
local screen3 = tt.setup_child_nvim({ '--remote-ui', '--server', server2 })
|
||||||
'--remote-ui',
|
screen3:expect({ any = vim.pesc('This is server 2^.') })
|
||||||
'--server',
|
|
||||||
server2,
|
|
||||||
})
|
|
||||||
screen3:expect([[
|
|
||||||
This is server 2^. |
|
|
||||||
~ |*3
|
|
||||||
{2:[No Name] [+] 1,17 All}|
|
|
||||||
|
|
|
||||||
{5:-- TERMINAL --} |
|
|
||||||
]])
|
|
||||||
|
|
||||||
screen3:detach()
|
screen3:detach()
|
||||||
server2_session:request('nvim_command', 'qall!')
|
server2_session:request('nvim_command', 'qall!')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('! stops the current server', function()
|
it('! stops the current server', function()
|
||||||
n.clear()
|
n.clear()
|
||||||
finally(function()
|
finally(function()
|
||||||
@@ -439,27 +430,23 @@ describe('TUI :connect', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
local server1 = new_pipename()
|
local server1 = new_pipename()
|
||||||
local screen1 = tt.setup_child_nvim({
|
local screen1 = tt.setup_child_nvim({ '--listen', server1, '--clean' })
|
||||||
'--listen',
|
screen1:expect({ any = vim.pesc('[No Name]') })
|
||||||
server1,
|
|
||||||
})
|
|
||||||
tt.feed_data('iThis is server 1')
|
|
||||||
|
|
||||||
|
tt.feed_data('iThis is server 1.\027')
|
||||||
|
screen1:expect({ any = vim.pesc('This is server 1^.') })
|
||||||
|
|
||||||
|
-- Prevent screen2 from receiving the old terminal state.
|
||||||
|
command('enew')
|
||||||
|
screen1:expect(screen_empty)
|
||||||
screen1:detach()
|
screen1:detach()
|
||||||
|
|
||||||
local server2 = new_pipename()
|
local server2 = new_pipename()
|
||||||
local screen2 = tt.setup_child_nvim({
|
local screen2 = tt.setup_child_nvim({ '--listen', server2, '--clean' })
|
||||||
'--listen',
|
screen2:expect({ any = vim.pesc('[No Name]') })
|
||||||
server2,
|
|
||||||
})
|
tt.feed_data(':connect! ' .. server1 .. '\013')
|
||||||
tt.feed_data('\027:connect! ' .. server1 .. '\013')
|
screen2:expect({ any = vim.pesc('This is server 1^.') })
|
||||||
screen2:expect([[
|
|
||||||
This is server 1^ |
|
|
||||||
~ |*3
|
|
||||||
[No Name] [+] 1,17 All|
|
|
||||||
-- INSERT -- |
|
|
||||||
{5:-- TERMINAL --} |
|
|
||||||
]])
|
|
||||||
|
|
||||||
local server1_session = n.connect(server1)
|
local server1_session = n.connect(server1)
|
||||||
server1_session:request('nvim_command', 'qall!')
|
server1_session:request('nvim_command', 'qall!')
|
||||||
|
Reference in New Issue
Block a user