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
|