Skip to content

Commit 68cee30

Browse files
committed
perf: prevent active waiting in coroutines. suspend/resume instead
1 parent 79bcc02 commit 68cee30

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

lua/lazy/async.lua

+27-1
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ local M = {}
99
M._queue = {}
1010
M._executor = assert(vim.loop.new_check())
1111
M._running = false
12+
M.SLEEP = "sleep"
13+
---@type Async
14+
M.current = nil
1215

1316
---@class Async
1417
---@field co thread
1518
---@field opts AsyncOpts
19+
---@field sleeping? boolean
1620
local Async = {}
1721

1822
---@param fn async fun()
@@ -29,16 +33,38 @@ function Async:running()
2933
return coroutine.status(self.co) ~= "dead"
3034
end
3135

36+
function Async:sleep(ms)
37+
self.sleeping = true
38+
vim.defer_fn(function()
39+
self.sleeping = false
40+
end, ms)
41+
end
42+
43+
function Async:suspend()
44+
self.sleeping = true
45+
end
46+
47+
function Async:resume()
48+
self.sleeping = false
49+
end
50+
3251
function Async:step()
52+
if self.sleeping then
53+
return true
54+
end
3355
local status = coroutine.status(self.co)
3456
if status == "suspended" then
57+
M.current = self
3558
local ok, res = coroutine.resume(self.co)
59+
M.current = nil
3660
if not ok then
3761
if self.opts.on_error then
3862
self.opts.on_error(tostring(res))
3963
end
4064
elseif res then
41-
if self.opts.on_yield then
65+
if res == M.SLEEP then
66+
self.sleeping = true
67+
elseif self.opts.on_yield then
4268
self.opts.on_yield(res)
4369
end
4470
end

lua/lazy/manage/task/init.lua

+5-3
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ function Task:spawn(cmd, opts)
222222
end
223223
end
224224

225+
self._running:suspend()
226+
225227
local running = true
226228
local ret = true
227229
---@param output string
@@ -234,6 +236,7 @@ function Task:spawn(cmd, opts)
234236
end
235237
ret = ok
236238
running = false
239+
self._running:resume()
237240
end
238241

239242
if headless then
@@ -244,9 +247,8 @@ function Task:spawn(cmd, opts)
244247
end
245248
end
246249
Process.spawn(cmd, opts)
247-
while running do
248-
coroutine.yield()
249-
end
250+
coroutine.yield()
251+
assert(not running, "process still running?")
250252
return ret
251253
end
252254

lua/lazy/util.lua

+3-7
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,9 @@ end
232232
---@async
233233
---@param ms number
234234
function M.sleep(ms)
235-
local continue = false
236-
vim.defer_fn(function()
237-
continue = true
238-
end, ms)
239-
while not continue do
240-
coroutine.yield()
241-
end
235+
local async = require("lazy.async").current
236+
assert(async, "Not in an async context")
237+
async:sleep(ms)
242238
end
243239

244240
function M._dump(value, result)

0 commit comments

Comments
 (0)