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._queue = {}
|
||||||
M._executor = assert(vim.loop.new_check())
|
M._executor = assert(vim.loop.new_check())
|
||||||
M._running = false
|
M._running = false
|
||||||
|
M.SLEEP = "sleep"
|
||||||
|
---@type Async
|
||||||
|
M.current = nil
|
||||||
|
|
||||||
---@class Async
|
---@class Async
|
||||||
---@field co thread
|
---@field co thread
|
||||||
---@field opts AsyncOpts
|
---@field opts AsyncOpts
|
||||||
|
---@field sleeping? boolean
|
||||||
local Async = {}
|
local Async = {}
|
||||||
|
|
||||||
---@param fn async fun()
|
---@param fn async fun()
|
||||||
|
@ -29,16 +33,38 @@ function Async:running()
|
||||||
return coroutine.status(self.co) ~= "dead"
|
return coroutine.status(self.co) ~= "dead"
|
||||||
end
|
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()
|
function Async:step()
|
||||||
|
if self.sleeping then
|
||||||
|
return true
|
||||||
|
end
|
||||||
local status = coroutine.status(self.co)
|
local status = coroutine.status(self.co)
|
||||||
if status == "suspended" then
|
if status == "suspended" then
|
||||||
|
M.current = self
|
||||||
local ok, res = coroutine.resume(self.co)
|
local ok, res = coroutine.resume(self.co)
|
||||||
|
M.current = nil
|
||||||
if not ok then
|
if not ok then
|
||||||
if self.opts.on_error then
|
if self.opts.on_error then
|
||||||
self.opts.on_error(tostring(res))
|
self.opts.on_error(tostring(res))
|
||||||
end
|
end
|
||||||
elseif res then
|
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)
|
self.opts.on_yield(res)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -222,6 +222,8 @@ function Task:spawn(cmd, opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self._running:suspend()
|
||||||
|
|
||||||
local running = true
|
local running = true
|
||||||
local ret = true
|
local ret = true
|
||||||
---@param output string
|
---@param output string
|
||||||
|
@ -234,6 +236,7 @@ function Task:spawn(cmd, opts)
|
||||||
end
|
end
|
||||||
ret = ok
|
ret = ok
|
||||||
running = false
|
running = false
|
||||||
|
self._running:resume()
|
||||||
end
|
end
|
||||||
|
|
||||||
if headless then
|
if headless then
|
||||||
|
@ -244,9 +247,8 @@ function Task:spawn(cmd, opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Process.spawn(cmd, opts)
|
Process.spawn(cmd, opts)
|
||||||
while running do
|
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
end
|
assert(not running, "process still running?")
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -232,13 +232,9 @@ end
|
||||||
---@async
|
---@async
|
||||||
---@param ms number
|
---@param ms number
|
||||||
function M.sleep(ms)
|
function M.sleep(ms)
|
||||||
local continue = false
|
local async = require("lazy.async").current
|
||||||
vim.defer_fn(function()
|
assert(async, "Not in an async context")
|
||||||
continue = true
|
async:sleep(ms)
|
||||||
end, ms)
|
|
||||||
while not continue do
|
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M._dump(value, result)
|
function M._dump(value, result)
|
||||||
|
|
Loading…
Reference in New Issue