diff options
| author | William Boman <william@redwill.se> | 2022-04-16 01:43:09 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-16 01:43:09 +0200 |
| commit | c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5 (patch) | |
| tree | 0956a0e6f3b931921563eae6265abd3bad481d9b /lua/nvim-lsp-installer/core/async/init.lua | |
| parent | run autogen_metadata.lua (diff) | |
| download | mason-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.lua | 30 |
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 |
