aboutsummaryrefslogtreecommitdiffstats
path: root/lua/mason-core/async/control.lua
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2022-07-08 18:34:38 +0200
committerGitHub <noreply@github.com>2022-07-08 18:34:38 +0200
commit976aa4fbee8a070f362cab6f6ec84e9251a90cf9 (patch)
tree5e8d9c9c59444a25c7801b8f39763c4ba6e1f76d /lua/mason-core/async/control.lua
parentfeat: add gotests, gomodifytags, impl (#28) (diff)
downloadmason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar
mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.gz
mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.bz2
mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.lz
mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.xz
mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.tar.zst
mason-976aa4fbee8a070f362cab6f6ec84e9251a90cf9.zip
refactor: add mason-schemas and mason-core modules (#29)
* refactor: add mason-schemas and move generated filetype map to mason-lspconfig * refactor: add mason-core module
Diffstat (limited to 'lua/mason-core/async/control.lua')
-rw-r--r--lua/mason-core/async/control.lua75
1 files changed, 75 insertions, 0 deletions
diff --git a/lua/mason-core/async/control.lua b/lua/mason-core/async/control.lua
new file mode 100644
index 00000000..3252c070
--- /dev/null
+++ b/lua/mason-core/async/control.lua
@@ -0,0 +1,75 @@
+local a = require "mason-core.async"
+
+---@class Condvar
+local Condvar = {}
+Condvar.__index = Condvar
+
+function Condvar.new()
+ return setmetatable({ handles = {}, queue = {}, is_notifying = false }, Condvar)
+end
+
+---@async
+function Condvar:wait()
+ a.wait(function(resolve)
+ if self.is_notifying then
+ self.queue[resolve] = true
+ else
+ self.handles[resolve] = true
+ end
+ end)
+end
+
+function Condvar:notify_all()
+ self.is_notifying = true
+ for handle in pairs(self.handles) do
+ handle()
+ end
+ self.handles = self.queue
+ self.queue = {}
+ self.is_notifying = false
+end
+
+local Permit = {}
+Permit.__index = Permit
+
+function Permit.new(semaphore)
+ return setmetatable({ semaphore = semaphore }, Permit)
+end
+
+function Permit:forget()
+ local semaphore = self.semaphore
+ semaphore.permits = semaphore.permits + 1
+
+ if semaphore.permits > 0 and #semaphore.handles > 0 then
+ semaphore.permits = semaphore.permits - 1
+ local release = table.remove(semaphore.handles, 1)
+ release(Permit.new(semaphore))
+ end
+end
+
+---@class Semaphore
+local Semaphore = {}
+Semaphore.__index = Semaphore
+
+---@param permits integer
+function Semaphore.new(permits)
+ return setmetatable({ permits = permits, handles = {} }, Semaphore)
+end
+
+---@async
+function Semaphore:acquire()
+ if self.permits > 0 then
+ self.permits = self.permits - 1
+ else
+ return a.wait(function(resolve)
+ table.insert(self.handles, resolve)
+ end)
+ end
+
+ return Permit.new(self)
+end
+
+return {
+ Condvar = Condvar,
+ Semaphore = Semaphore,
+}