Channel = {}
Channel.__index = Channel
function Channel.new()
self = {}
setmetatable(self, Channel)
self._senders = {}
self._receivers = {}
return self
end
function Channel:send(value)
if #self._receivers > 0 then
receiver = table.remove(self._receivers, math.random(#self._receivers))
coroutine.resume(receiver, value)
else
table.insert(self._senders, coroutine.running())
coroutine.yield()
coroutine.yield(value)
end
end
function Channel:receive()
if #self._senders > 0 then
sender = table.remove(self._senders, math.random(#self._senders))
status, value = coroutine.resume(sender)
return value
else
table.insert(self._receivers, coroutine.running())
return coroutine.yield()
end
end
channel = Channel.new()
function test()
co1 = coroutine.create(function()
print("co1: Sending 1...")
channel:send(1)
print("co1: Sent 1!")
end)
co2 = coroutine.create(function()
print("co2: Sending 2...")
channel:send(2)
print("co2: Sent 2!")
end)
co3 = coroutine.create(function()
print("co3: Receiving...")
value = channel:receive()
print("co3: Received " .. value .. "!")
end)
co4 = coroutine.create(function()
print("co4: Receiving...")
value = channel:receive()
print("co4: Received " .. value .. "!")
end)
return co1, co2, co3, co4
end
print("Scenario 1: send, then receive")
co1, co2, co3, co4 = test()
coroutine.resume(co1)
coroutine.resume(co2)
coroutine.resume(co1)
coroutine.resume(co2)
print("Scenario 2: receive, then send")
co1, co2, co3, co4 = test()
coroutine.resume(co3)
coroutine.resume(co1)
coroutine.resume(co3)
coroutine.resume(co1)
print("Scenario 3: receive, receive, then send")
co1, co2, co3, co4 = test()
coroutine.resume(co3)
coroutine.resume(co4)
coroutine.resume(co1)
coroutine.resume(co3)
coroutine.resume(co4)
coroutine.resume(co1)
print("Scenario 4: send, receive, then receive")
co1, co2, co3, co4 = test()
coroutine.resume(co1)
coroutine.resume(co3)
coroutine.resume(co4)
coroutine.resume(co1)
coroutine.resume(co3)
coroutine.resume(co4)
print("Scenario 5: send, send, receive, then receive")
co1, co2, co3, co4 = test()
coroutine.resume(co1)
coroutine.resume(co2)
coroutine.resume(co3)
coroutine.resume(co4)
coroutine.resume(co1)
coroutine.resume(co2)
coroutine.resume(co3)
coroutine.resume(co4)
print("Scenario 6: receive, receive, send, then send")
co1, co2, co3, co4 = test()
coroutine.resume(co3)
coroutine.resume(co4)
coroutine.resume(co1)
coroutine.resume(co2)
coroutine.resume(co3)
coroutine.resume(co4)
coroutine.resume(co1)
coroutine.resume(co2)
Q2hhbm5lbCA9IHt9CkNoYW5uZWwuX19pbmRleCA9IENoYW5uZWwKCmZ1bmN0aW9uIENoYW5uZWwubmV3KCkKCXNlbGYgPSB7fQoJc2V0bWV0YXRhYmxlKHNlbGYsIENoYW5uZWwpCglzZWxmLl9zZW5kZXJzID0ge30KCXNlbGYuX3JlY2VpdmVycyA9IHt9CglyZXR1cm4gc2VsZgplbmQKCmZ1bmN0aW9uIENoYW5uZWw6c2VuZCh2YWx1ZSkKCWlmICNzZWxmLl9yZWNlaXZlcnMgPiAwIHRoZW4KCQlyZWNlaXZlciA9IHRhYmxlLnJlbW92ZShzZWxmLl9yZWNlaXZlcnMsIG1hdGgucmFuZG9tKCNzZWxmLl9yZWNlaXZlcnMpKQoJCWNvcm91dGluZS5yZXN1bWUocmVjZWl2ZXIsIHZhbHVlKQoJZWxzZQoJCXRhYmxlLmluc2VydChzZWxmLl9zZW5kZXJzLCBjb3JvdXRpbmUucnVubmluZygpKQoJCWNvcm91dGluZS55aWVsZCgpCgkJY29yb3V0aW5lLnlpZWxkKHZhbHVlKQoJZW5kCmVuZAoKZnVuY3Rpb24gQ2hhbm5lbDpyZWNlaXZlKCkKCWlmICNzZWxmLl9zZW5kZXJzID4gMCB0aGVuCgkJc2VuZGVyID0gdGFibGUucmVtb3ZlKHNlbGYuX3NlbmRlcnMsIG1hdGgucmFuZG9tKCNzZWxmLl9zZW5kZXJzKSkKCQlzdGF0dXMsIHZhbHVlID0gY29yb3V0aW5lLnJlc3VtZShzZW5kZXIpCgkJcmV0dXJuIHZhbHVlCgllbHNlCgkJdGFibGUuaW5zZXJ0KHNlbGYuX3JlY2VpdmVycywgY29yb3V0aW5lLnJ1bm5pbmcoKSkKCQlyZXR1cm4gY29yb3V0aW5lLnlpZWxkKCkKCWVuZAplbmQKCmNoYW5uZWwgPSBDaGFubmVsLm5ldygpCgpmdW5jdGlvbiB0ZXN0KCkKCWNvMSA9IGNvcm91dGluZS5jcmVhdGUoZnVuY3Rpb24oKQoJCXByaW50KCJjbzE6IFNlbmRpbmcgMS4uLiIpCgkJY2hhbm5lbDpzZW5kKDEpCgkJcHJpbnQoImNvMTogU2VudCAxISIpCgllbmQpCgoJY28yID0gY29yb3V0aW5lLmNyZWF0ZShmdW5jdGlvbigpCgkJcHJpbnQoImNvMjogU2VuZGluZyAyLi4uIikKCQljaGFubmVsOnNlbmQoMikKCQlwcmludCgiY28yOiBTZW50IDIhIikKCWVuZCkKCgljbzMgPSBjb3JvdXRpbmUuY3JlYXRlKGZ1bmN0aW9uKCkKCQlwcmludCgiY28zOiBSZWNlaXZpbmcuLi4iKQoJCXZhbHVlID0gY2hhbm5lbDpyZWNlaXZlKCkKCQlwcmludCgiY28zOiBSZWNlaXZlZCAiIC4uIHZhbHVlIC4uICIhIikKCWVuZCkKCgljbzQgPSBjb3JvdXRpbmUuY3JlYXRlKGZ1bmN0aW9uKCkKCQlwcmludCgiY280OiBSZWNlaXZpbmcuLi4iKQoJCXZhbHVlID0gY2hhbm5lbDpyZWNlaXZlKCkKCQlwcmludCgiY280OiBSZWNlaXZlZCAiIC4uIHZhbHVlIC4uICIhIikKCWVuZCkKCglyZXR1cm4gY28xLCBjbzIsIGNvMywgY280CmVuZAoKcHJpbnQoIlNjZW5hcmlvIDE6IHNlbmQsIHRoZW4gcmVjZWl2ZSIpCmNvMSwgY28yLCBjbzMsIGNvNCA9IHRlc3QoKQpjb3JvdXRpbmUucmVzdW1lKGNvMSkKY29yb3V0aW5lLnJlc3VtZShjbzIpCmNvcm91dGluZS5yZXN1bWUoY28xKQpjb3JvdXRpbmUucmVzdW1lKGNvMikKCnByaW50KCJTY2VuYXJpbyAyOiByZWNlaXZlLCB0aGVuIHNlbmQiKQpjbzEsIGNvMiwgY28zLCBjbzQgPSB0ZXN0KCkKY29yb3V0aW5lLnJlc3VtZShjbzMpCmNvcm91dGluZS5yZXN1bWUoY28xKQpjb3JvdXRpbmUucmVzdW1lKGNvMykKY29yb3V0aW5lLnJlc3VtZShjbzEpCgpwcmludCgiU2NlbmFyaW8gMzogcmVjZWl2ZSwgcmVjZWl2ZSwgdGhlbiBzZW5kIikKY28xLCBjbzIsIGNvMywgY280ID0gdGVzdCgpCmNvcm91dGluZS5yZXN1bWUoY28zKQpjb3JvdXRpbmUucmVzdW1lKGNvNCkKY29yb3V0aW5lLnJlc3VtZShjbzEpCmNvcm91dGluZS5yZXN1bWUoY28zKQpjb3JvdXRpbmUucmVzdW1lKGNvNCkKY29yb3V0aW5lLnJlc3VtZShjbzEpCgpwcmludCgiU2NlbmFyaW8gNDogc2VuZCwgcmVjZWl2ZSwgdGhlbiByZWNlaXZlIikKY28xLCBjbzIsIGNvMywgY280ID0gdGVzdCgpCmNvcm91dGluZS5yZXN1bWUoY28xKQpjb3JvdXRpbmUucmVzdW1lKGNvMykKY29yb3V0aW5lLnJlc3VtZShjbzQpCmNvcm91dGluZS5yZXN1bWUoY28xKQpjb3JvdXRpbmUucmVzdW1lKGNvMykKY29yb3V0aW5lLnJlc3VtZShjbzQpCgpwcmludCgiU2NlbmFyaW8gNTogc2VuZCwgc2VuZCwgcmVjZWl2ZSwgdGhlbiByZWNlaXZlIikKY28xLCBjbzIsIGNvMywgY280ID0gdGVzdCgpCmNvcm91dGluZS5yZXN1bWUoY28xKQpjb3JvdXRpbmUucmVzdW1lKGNvMikKY29yb3V0aW5lLnJlc3VtZShjbzMpCmNvcm91dGluZS5yZXN1bWUoY280KQpjb3JvdXRpbmUucmVzdW1lKGNvMSkKY29yb3V0aW5lLnJlc3VtZShjbzIpCmNvcm91dGluZS5yZXN1bWUoY28zKQpjb3JvdXRpbmUucmVzdW1lKGNvNCkKCnByaW50KCJTY2VuYXJpbyA2OiByZWNlaXZlLCByZWNlaXZlLCBzZW5kLCB0aGVuIHNlbmQiKQpjbzEsIGNvMiwgY28zLCBjbzQgPSB0ZXN0KCkKY29yb3V0aW5lLnJlc3VtZShjbzMpCmNvcm91dGluZS5yZXN1bWUoY280KQpjb3JvdXRpbmUucmVzdW1lKGNvMSkKY29yb3V0aW5lLnJlc3VtZShjbzIpCmNvcm91dGluZS5yZXN1bWUoY28zKQpjb3JvdXRpbmUucmVzdW1lKGNvNCkKY29yb3V0aW5lLnJlc3VtZShjbzEpCmNvcm91dGluZS5yZXN1bWUoY28yKQo=