mirror of
https://github.com/neovim/neovim.git
synced 2026-08-29 18:41:48 +00:00
fix(lua): close vim.defer_fn() timer if vim.schedule() failed (#37647)
Problem: Using vim.defer_fn() just before Nvim exit leaks luv handles. Solution: Make vim.schedule() return an error message if scheduling failed. Make vim.defer_fn() close timer if vim.schedule() failed.
This commit is contained in:
@@ -509,25 +509,28 @@ end
|
||||
--- Defers calling {fn} until {timeout} ms passes.
|
||||
---
|
||||
--- Use to do a one-shot timer that calls {fn}
|
||||
--- Note: The {fn} is |vim.schedule_wrap()|ped automatically, so API functions are
|
||||
--- Note: The {fn} is |vim.schedule()|d automatically, so API functions are
|
||||
--- safe to call.
|
||||
---@param fn function Callback to call once `timeout` expires
|
||||
---@param timeout integer Number of milliseconds to wait before calling `fn`
|
||||
---@return table timer luv timer object
|
||||
function vim.defer_fn(fn, timeout)
|
||||
vim.validate('fn', fn, 'callable', true)
|
||||
|
||||
local timer = assert(vim.uv.new_timer())
|
||||
timer:start(
|
||||
timeout,
|
||||
0,
|
||||
vim.schedule_wrap(function()
|
||||
timer:start(timeout, 0, function()
|
||||
local _, err = vim.schedule(function()
|
||||
if not timer:is_closing() then
|
||||
timer:close()
|
||||
end
|
||||
|
||||
fn()
|
||||
end)
|
||||
)
|
||||
|
||||
if err then
|
||||
timer:close()
|
||||
end
|
||||
end)
|
||||
|
||||
return timer
|
||||
end
|
||||
|
||||
@@ -178,6 +178,8 @@ function vim.iconv(str, from, to, opts) end
|
||||
--- Schedules {fn} to be invoked soon by the main event-loop. Useful
|
||||
--- to avoid |textlock| or other temporary restrictions.
|
||||
--- @param fn fun()
|
||||
--- @return nil result
|
||||
--- @return string? err Error message if scheduling failed, `nil` otherwise.
|
||||
function vim.schedule(fn) end
|
||||
|
||||
--- Waits up to `time` milliseconds, until `callback` returns `true` (success). Executes
|
||||
|
||||
Reference in New Issue
Block a user