opus/sys/apis/sync.lua

62 lines
1.2 KiB
Lua
Raw Normal View History

2018-10-31 23:38:09 +00:00
local Sync = {
syncLocks = { }
}
2016-12-11 19:24:52 +00:00
2017-10-08 21:45:01 +00:00
local os = _G.os
2018-10-31 23:38:09 +00:00
function Sync.sync(obj, fn)
2016-12-11 19:24:52 +00:00
local key = tostring(obj)
2018-10-31 23:38:09 +00:00
if Sync.syncLocks[key] then
2016-12-11 19:24:52 +00:00
local cos = tostring(coroutine.running())
2018-10-31 23:38:09 +00:00
table.insert(Sync.syncLocks[key], cos)
2016-12-11 19:24:52 +00:00
repeat
local _, co = os.pullEvent('sync_lock')
until co == cos
else
2018-10-31 23:38:09 +00:00
Sync.syncLocks[key] = { }
2016-12-11 19:24:52 +00:00
end
local s, m = pcall(fn)
2018-10-31 23:38:09 +00:00
local co = table.remove(Sync.syncLocks[key], 1)
2016-12-11 19:24:52 +00:00
if co then
os.queueEvent('sync_lock', co)
else
2018-10-31 23:38:09 +00:00
Sync.syncLocks[key] = nil
2016-12-11 19:24:52 +00:00
end
if not s then
error(m)
end
end
2018-10-31 23:38:09 +00:00
function Sync.lock(obj)
local key = tostring(obj)
if Sync.syncLocks[key] then
local cos = tostring(coroutine.running())
table.insert(Sync.syncLocks[key], cos)
repeat
local _, co = os.pullEvent('sync_lock')
until co == cos
else
Sync.syncLocks[key] = { }
end
end
function Sync.release(obj)
local key = tostring(obj)
if not Sync.syncLocks[key] then
error('Sync.release: Lock was not obtained', 2)
end
local co = table.remove(Sync.syncLocks[key], 1)
if co then
os.queueEvent('sync_lock', co)
else
Sync.syncLocks[key] = nil
end
end
function Sync.isLocked(obj)
local key = tostring(obj)
return not not Sync.syncLocks[key]
end
return Sync