mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
fix(lua): disallow vim.wait() in fast contexts
`vim.wait()` cannot be called in a fast callback since the main loop cannot be run in that context as it is not reentrant Fixes #26122
This commit is contained in:
parent
6343d41436
commit
84bbe4b0ca
@ -1143,6 +1143,8 @@ vim.wait({time}, {callback}, {interval}, {fast_only}) *vim.wait()*
|
|||||||
milliseconds (default 200). Nvim still processes other events during this
|
milliseconds (default 200). Nvim still processes other events during this
|
||||||
time.
|
time.
|
||||||
|
|
||||||
|
Cannot be called while in an |api-fast| event.
|
||||||
|
|
||||||
Examples: >lua
|
Examples: >lua
|
||||||
---
|
---
|
||||||
-- Wait for 100 ms, allowing other events to process
|
-- Wait for 100 ms, allowing other events to process
|
||||||
@ -1173,8 +1175,7 @@ vim.wait({time}, {callback}, {interval}, {fast_only}) *vim.wait()*
|
|||||||
• {interval} (integer|nil) (Approximate) number of milliseconds to
|
• {interval} (integer|nil) (Approximate) number of milliseconds to
|
||||||
wait between polls
|
wait between polls
|
||||||
• {fast_only} (boolean|nil) If true, only |api-fast| events will be
|
• {fast_only} (boolean|nil) If true, only |api-fast| events will be
|
||||||
processed. If called from while in an |api-fast| event,
|
processed.
|
||||||
will automatically be set to `true`.
|
|
||||||
|
|
||||||
Return: ~
|
Return: ~
|
||||||
boolean, nil|-1|-2
|
boolean, nil|-1|-2
|
||||||
@ -1828,7 +1829,8 @@ vim.system({cmd}, {opts}, {on_exit}) *vim.system()*
|
|||||||
• pid (integer) Process ID
|
• pid (integer) Process ID
|
||||||
• wait (fun(timeout: integer|nil): SystemCompleted) Wait for the
|
• wait (fun(timeout: integer|nil): SystemCompleted) Wait for the
|
||||||
process to complete. Upon timeout the process is sent the KILL
|
process to complete. Upon timeout the process is sent the KILL
|
||||||
signal (9) and the exit code is set to 124.
|
signal (9) and the exit code is set to 124. Cannot be called in
|
||||||
|
|api-fast|.
|
||||||
• SystemCompleted is an object with the fields:
|
• SystemCompleted is an object with the fields:
|
||||||
• code: (integer)
|
• code: (integer)
|
||||||
• signal: (integer)
|
• signal: (integer)
|
||||||
|
@ -325,6 +325,8 @@ The following changes to existing APIs or features add new behavior.
|
|||||||
NOTE: the regexp engine still has a hard-coded limit of considering
|
NOTE: the regexp engine still has a hard-coded limit of considering
|
||||||
6 composing chars only.
|
6 composing chars only.
|
||||||
|
|
||||||
|
• |vim.wait()| is no longer allowed to be called in |api-fast|.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
REMOVED FEATURES *news-removed*
|
REMOVED FEATURES *news-removed*
|
||||||
|
|
||||||
|
@ -124,7 +124,8 @@ vim.log = {
|
|||||||
--- @return vim.SystemObj Object with the fields:
|
--- @return vim.SystemObj Object with the fields:
|
||||||
--- - pid (integer) Process ID
|
--- - pid (integer) Process ID
|
||||||
--- - wait (fun(timeout: integer|nil): SystemCompleted) Wait for the process to complete. Upon
|
--- - wait (fun(timeout: integer|nil): SystemCompleted) Wait for the process to complete. Upon
|
||||||
--- timeout the process is sent the KILL signal (9) and the exit code is set to 124.
|
--- timeout the process is sent the KILL signal (9) and the exit code is set to 124. Cannot
|
||||||
|
--- be called in |api-fast|.
|
||||||
--- - SystemCompleted is an object with the fields:
|
--- - SystemCompleted is an object with the fields:
|
||||||
--- - code: (integer)
|
--- - code: (integer)
|
||||||
--- - signal: (integer)
|
--- - signal: (integer)
|
||||||
|
@ -205,6 +205,8 @@ function vim.schedule(fn) end
|
|||||||
--- milliseconds (default 200). Nvim still processes other events during
|
--- milliseconds (default 200). Nvim still processes other events during
|
||||||
--- this time.
|
--- this time.
|
||||||
---
|
---
|
||||||
|
--- Cannot be called while in an |api-fast| event.
|
||||||
|
---
|
||||||
--- Examples:
|
--- Examples:
|
||||||
---
|
---
|
||||||
--- ```lua
|
--- ```lua
|
||||||
@ -235,8 +237,6 @@ function vim.schedule(fn) end
|
|||||||
--- @param callback? fun(): boolean Optional callback. Waits until {callback} returns true
|
--- @param callback? fun(): boolean Optional callback. Waits until {callback} returns true
|
||||||
--- @param interval? integer (Approximate) number of milliseconds to wait between polls
|
--- @param interval? integer (Approximate) number of milliseconds to wait between polls
|
||||||
--- @param fast_only? boolean If true, only |api-fast| events will be processed.
|
--- @param fast_only? boolean If true, only |api-fast| events will be processed.
|
||||||
--- If called from while in an |api-fast| event, will
|
|
||||||
--- automatically be set to `true`.
|
|
||||||
--- @return boolean, nil|-1|-2
|
--- @return boolean, nil|-1|-2
|
||||||
--- - If {callback} returns `true` during the {time}: `true, nil`
|
--- - If {callback} returns `true` during the {time}: `true, nil`
|
||||||
--- - If {callback} never returns `true` during the {time}: `false, -1`
|
--- - If {callback} never returns `true` during the {time}: `false, -1`
|
||||||
|
@ -411,6 +411,10 @@ static bool nlua_wait_condition(lua_State *lstate, int *status, bool *callback_r
|
|||||||
static int nlua_wait(lua_State *lstate)
|
static int nlua_wait(lua_State *lstate)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
|
if (in_fast_callback) {
|
||||||
|
return luaL_error(lstate, e_luv_api_disabled, "vim.wait");
|
||||||
|
}
|
||||||
|
|
||||||
intptr_t timeout = luaL_checkinteger(lstate, 1);
|
intptr_t timeout = luaL_checkinteger(lstate, 1);
|
||||||
if (timeout < 0) {
|
if (timeout < 0) {
|
||||||
return luaL_error(lstate, "timeout must be >= 0");
|
return luaL_error(lstate, "timeout must be >= 0");
|
||||||
@ -449,8 +453,7 @@ static int nlua_wait(lua_State *lstate)
|
|||||||
fast_only = lua_toboolean(lstate, 4);
|
fast_only = lua_toboolean(lstate, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiQueue *loop_events = fast_only || in_fast_callback > 0
|
MultiQueue *loop_events = fast_only ? main_loop.fast_events : main_loop.events;
|
||||||
? main_loop.fast_events : main_loop.events;
|
|
||||||
|
|
||||||
TimeWatcher *tw = xmalloc(sizeof(TimeWatcher));
|
TimeWatcher *tw = xmalloc(sizeof(TimeWatcher));
|
||||||
|
|
||||||
|
@ -2769,6 +2769,19 @@ describe('lua stdlib', function()
|
|||||||
eq({'notification', 'wait', {-2}}, next_msg(500))
|
eq({'notification', 'wait', {-2}}, next_msg(500))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('should not run in fast callbacks #26122', function()
|
||||||
|
exec_lua([[
|
||||||
|
vim.uv.new_timer():start(0, 100, function()
|
||||||
|
local count = 0
|
||||||
|
vim.wait(100, function()
|
||||||
|
count = count + 1
|
||||||
|
return count == 10
|
||||||
|
end, 100)
|
||||||
|
end)
|
||||||
|
]])
|
||||||
|
assert_alive()
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('vim.notify_once', function()
|
it('vim.notify_once', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user