aboutsummaryrefslogtreecommitdiffstats
path: root/lua/nvim-lsp-installer/core/async/init.lua
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2022-04-16 01:43:09 +0200
committerGitHub <noreply@github.com>2022-04-16 01:43:09 +0200
commitc472f3ea46a5dd5f62bb12b5857e779ae0d74dc5 (patch)
tree0956a0e6f3b931921563eae6265abd3bad481d9b /lua/nvim-lsp-installer/core/async/init.lua
parentrun autogen_metadata.lua (diff)
downloadmason-c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5.tar
mason-c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5.tar.gz
mason-c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5.tar.bz2
mason-c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5.tar.lz
mason-c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5.tar.xz
mason-c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5.tar.zst
mason-c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5.zip
fix(async): slightly better support for nested coroutine contexts (#600)
* fix(async): only dispatch first failure in a.wait_all * add InstallContext:run_concurrently This is needed due to how multiple coroutine contexts are used in a hierchical structure, and the async coroutine dispatcher loses this hierchical context inside callback functions invoked via FFI (I… assume?).
Diffstat (limited to 'lua/nvim-lsp-installer/core/async/init.lua')
-rw-r--r--lua/nvim-lsp-installer/core/async/init.lua30
1 files changed, 16 insertions, 14 deletions
diff --git a/lua/nvim-lsp-installer/core/async/init.lua b/lua/nvim-lsp-installer/core/async/init.lua
index 8537b909..27a4c7cb 100644
--- a/lua/nvim-lsp-installer/core/async/init.lua
+++ b/lua/nvim-lsp-installer/core/async/init.lua
@@ -147,6 +147,9 @@ local function oneshot_channel()
local saved_callback
return {
+ is_closed = function()
+ return has_sent
+ end,
send = function(...)
assert(not has_sent, "Oneshot channel can only send once.")
has_sent = true
@@ -174,32 +177,31 @@ exports.wait_all = function(suspend_fns)
do
local results = {}
- local threads = {}
+ local thread_cancellations = {}
local count = #suspend_fns
local completed = 0
- local function callback(i)
- return function(success, result)
+ for i, suspend_fn in ipairs(suspend_fns) do
+ thread_cancellations[i] = exports.run(suspend_fn, function(success, result)
+ completed = completed + 1
if not success then
- for _, cancel_thread in ipairs(threads) do
- cancel_thread()
+ if not channel.is_closed() then
+ for _, cancel_thread in ipairs(thread_cancellations) do
+ cancel_thread()
+ end
+ channel.send(false, result)
+ results = nil
+ thread_cancellations = {}
end
- channel.send(false, result)
- results = nil
- threads = nil
else
results[i] = result
- completed = completed + 1
if completed >= count then
channel.send(true, results)
results = nil
- threads = nil
+ thread_cancellations = {}
end
end
- end
- end
- for i, suspend_fn in ipairs(suspend_fns) do
- threads[i] = exports.run(suspend_fn, callback(i))
+ end)
end
end