forked from nvim-lua/plenary.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.lua
More file actions
115 lines (91 loc) · 2.21 KB
/
utils.lua
File metadata and controls
115 lines (91 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
local a = require('plenary.async.async')
local co = coroutine
local VecDeque = require('plenary.async.helpers').VecDeque
local uv = vim.loop
local M = {}
M.sleep = a.wrap(function(ms, callback)
local timer = uv.new_timer()
uv.timer_start(timer, ms, 0, function()
uv.timer_stop(timer)
uv.close(timer)
callback()
end)
end)
M.timer = function(ms)
return a.sync(function()
a.wait(M.sleep(ms))
end)
end
M.id = a.sync(function(...)
return ...
end)
M.thread_loop = function(thread, callback)
local idle = uv.new_idle()
idle:start(function()
local success = co.resume(thread)
assert(success, "Coroutine failed")
if co.status(thread) == "dead" then
idle:stop()
callback()
end
end)
end
M.thread_loop_async = a.wrap(M.thread_loop)
M.yield_now = a.sync(function()
a.wait(M.id())
end)
local Condvar = {}
Condvar.__index = Condvar
function Condvar.new()
return setmetatable({handles = {}}, Condvar)
end
--- async function
--- blocks the thread until a notification is received
Condvar.wait = a.wrap(function(self, callback)
-- not calling the callback will block the coroutine
table.insert(self.handles, callback)
end)
--- not an async function
function Condvar:notify_all()
for _, callback in ipairs(self.handles) do
callback()
end
self.handles = {} -- reset all handles as they have been used up
end
--- not an async function
function Condvar:notify_one()
if #self.handles == 0 then return end
local idx = math.random(#self.handles)
self.handles[idx]()
table.remove(self.handles, idx)
end
M.Condvar = Condvar
M.channel = {}
---comment
---@return function
---@return any
M.channel.oneshot = function()
local val = nil
local saved_callback = nil
--- sender is not async
--- sends a value
local sender = function(t)
if val ~= nil then
error('Oneshot channel can only send one value!')
end
val = t
saved_callback(val)
end
--- receiver is async
--- blocks until a value is received
local receiver = a.wrap(function(callback)
if callback ~= nil then
error('Oneshot channel can only receive one value!')
end
saved_callback = callback
end)
return sender, receiver
end
M.channel.mpsc = function()
end
return M