Skip to content

Instantly share code, notes, and snippets.

@bassosimone
Last active July 5, 2016 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bassosimone/7121899bba4fad0928c18e3ee3b905e6 to your computer and use it in GitHub Desktop.
Save bassosimone/7121899bba4fad0928c18e3ee3b905e6 to your computer and use it in GitHub Desktop.
mk_runtime = (function ()
local self = {}
self.coroutines = {}
self.async = function (func)
self.coroutines[coroutine.create(func)] = {
status = "running",
func = func
}
end
self.suspend = function ()
coro, _ = coroutine.running()
self.coroutines[coro].status = "suspended"
--[[
Here: pass to C++ coroutine and arguments, then C++ does:
1. unmarshalling of coroutine and arguments from the stack
2. call_soon
3. the call_soon would then call the real function
4. whose callback would marshal results
5. store them on the coroutine record
6. set coroutine status again as running
]]
print("suspend", coro)
coroutine.yield()
-- Here we read the result from coroutine record and return it
end
-- This is not actually needed when the coroutine would be resume
-- by C/C++ code as was described above
self.resume_all = function ()
for coro, record in pairs(self.coroutines) do
if record.status == "suspended" then
record.status = "running"
print("resume", coro)
end
end
end
self.loop = function ()
repeat
local new_running = {}
local count = 0
for coro, record in pairs(self.coroutines) do
if record.status == "running" then
coroutine.resume(coro)
if coroutine.status(coro) ~= "dead" then
new_running[coro] = record
count = count + 1
end
end
end
self.running = new_running
until count <= 0
end
return self
end)()
-- Shows that use can used nested coroutines without harm if you wish
local gimme_antani = coroutine.wrap(function ()
while (true) do
coroutine.yield("antani...")
end
end)
function antani()
print("i want antani...")
print(gimme_antani())
print("i got antani...")
-- This is the point where we emulate a sync function in lua triggering
-- async behavior in C++. This should instead be something like:
-- `local result = dns_query( ... )`
local result = mk_runtime.suspend({
"dns_query", "IN", "A", "www.google.com", {
["dns/nameserver"] = "8.8.8.8"
}
})
coroutine.yield()
end
mk_runtime.async(function ()
for _ = 1, 1024 do
antani()
end
end)
mk_runtime.async(function ()
for _ = 1, 6 do
print("second coroutine")
coroutine.yield()
end
print("before resume")
-- This is here to resume because resume in C++ is not yet implemented
mk_runtime.resume_all()
print("after resume")
end)
mk_runtime.async(function ()
print ("aaa")
coroutine.yield()
end)
-- Emulates the MK loop that runs forever
mk_runtime.async(function ()
while (true) do
coroutine.yield()
end
end)
mk_runtime.loop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment