mirror of https://github.com/folke/lazy.nvim.git
perf: prevent active waiting in coroutines. suspend/resume instead
This commit is contained in:
parent
79bcc02d17
commit
68cee30cdb
|
@ -9,10 +9,14 @@ local M = {}
|
|||
M._queue = {}
|
||||
M._executor = assert(vim.loop.new_check())
|
||||
M._running = false
|
||||
M.SLEEP = "sleep"
|
||||
---@type Async
|
||||
M.current = nil
|
||||
|
||||
---@class Async
|
||||
---@field co thread
|
||||
---@field opts AsyncOpts
|
||||
---@field sleeping? boolean
|
||||
local Async = {}
|
||||
|
||||
---@param fn async fun()
|
||||
|
@ -29,16 +33,38 @@ function Async:running()
|
|||
return coroutine.status(self.co) ~= "dead"
|
||||
end
|
||||
|
||||
function Async:sleep(ms)
|
||||
self.sleeping = true
|
||||
vim.defer_fn(function()
|
||||
self.sleeping = false
|
||||
end, ms)
|
||||
end
|
||||
|
||||
function Async:suspend()
|
||||
self.sleeping = true
|
||||
end
|
||||
|
||||
function Async:resume()
|
||||
self.sleeping = false
|
||||
end
|
||||
|
||||
function Async:step()
|
||||
if self.sleeping then
|
||||
return true
|
||||
end
|
||||
local status = coroutine.status(self.co)
|
||||
if status == "suspended" then
|
||||
M.current = self
|
||||
local ok, res = coroutine.resume(self.co)
|
||||
M.current = nil
|
||||
if not ok then
|
||||
if self.opts.on_error then
|
||||
self.opts.on_error(tostring(res))
|
||||
end
|
||||
elseif res then
|
||||
if self.opts.on_yield then
|
||||
if res == M.SLEEP then
|
||||
self.sleeping = true
|
||||
elseif self.opts.on_yield then
|
||||
self.opts.on_yield(res)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -222,6 +222,8 @@ function Task:spawn(cmd, opts)
|
|||
end
|
||||
end
|
||||
|
||||
self._running:suspend()
|
||||
|
||||
local running = true
|
||||
local ret = true
|
||||
---@param output string
|
||||
|
@ -234,6 +236,7 @@ function Task:spawn(cmd, opts)
|
|||
end
|
||||
ret = ok
|
||||
running = false
|
||||
self._running:resume()
|
||||
end
|
||||
|
||||
if headless then
|
||||
|
@ -244,9 +247,8 @@ function Task:spawn(cmd, opts)
|
|||
end
|
||||
end
|
||||
Process.spawn(cmd, opts)
|
||||
while running do
|
||||
coroutine.yield()
|
||||
end
|
||||
assert(not running, "process still running?")
|
||||
return ret
|
||||
end
|
||||
|
||||
|
|
|
@ -232,13 +232,9 @@ end
|
|||
---@async
|
||||
---@param ms number
|
||||
function M.sleep(ms)
|
||||
local continue = false
|
||||
vim.defer_fn(function()
|
||||
continue = true
|
||||
end, ms)
|
||||
while not continue do
|
||||
coroutine.yield()
|
||||
end
|
||||
local async = require("lazy.async").current
|
||||
assert(async, "Not in an async context")
|
||||
async:sleep(ms)
|
||||
end
|
||||
|
||||
function M._dump(value, result)
|
||||
|
|
Loading…
Reference in New Issue