diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2025-06-26 09:18:54 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2025-06-26 09:18:54 +0200 |
| commit | d7d756e30680bcff036118b47ac45b740e020ea2 (patch) | |
| tree | 3e2a26409154760d66092e6e04a9fcb4ad4ed02a /unit_tests/scripts/coro/basics.lua | |
| parent | 4f5fa626c0279f5aefac477a29702c43a6754c5a (diff) | |
| download | lanes-d7d756e30680bcff036118b47ac45b740e020ea2.tar.gz lanes-d7d756e30680bcff036118b47ac45b740e020ea2.tar.bz2 lanes-d7d756e30680bcff036118b47ac45b740e020ea2.zip | |
Preparation for lane:close() and correct to-be-closed variables
* lane:join() can no longer be used to read yielded values
* same with lane indexing
* stub for lane:close(), similar to coroutine.close() (not implemented yet)
* preparing tests for to-be-closed variables in yielded coroutine lanes
* yielded lanes unlock and terminate properly at Lanes shutdown
Diffstat (limited to 'unit_tests/scripts/coro/basics.lua')
| -rw-r--r-- | unit_tests/scripts/coro/basics.lua | 99 |
1 files changed, 0 insertions, 99 deletions
diff --git a/unit_tests/scripts/coro/basics.lua b/unit_tests/scripts/coro/basics.lua deleted file mode 100644 index c0b7a36..0000000 --- a/unit_tests/scripts/coro/basics.lua +++ /dev/null | |||
| @@ -1,99 +0,0 @@ | |||
| 1 | local lanes = require "lanes" | ||
| 2 | |||
| 3 | local fixture = require "fixture" | ||
| 4 | lanes.finally(fixture.throwing_finalizer) | ||
| 5 | |||
| 6 | local utils = lanes.require "_utils" | ||
| 7 | local PRINT = utils.MAKE_PRINT() | ||
| 8 | |||
| 9 | if true then | ||
| 10 | -- a lane body that just returns some value | ||
| 11 | local lane = function(msg_) | ||
| 12 | local utils = lanes.require "_utils" | ||
| 13 | local PRINT = utils.MAKE_PRINT() | ||
| 14 | PRINT "In lane" | ||
| 15 | assert(msg_ == "hi") | ||
| 16 | return "bye" | ||
| 17 | end | ||
| 18 | |||
| 19 | -- the generator | ||
| 20 | local g1 = lanes.coro("*", {name = "auto"}, lane) | ||
| 21 | |||
| 22 | -- launch lane | ||
| 23 | local h1 = g1("hi") | ||
| 24 | |||
| 25 | local r = h1[1] | ||
| 26 | assert(r == "bye") | ||
| 27 | end | ||
| 28 | |||
| 29 | -- a lane coroutine that yields back what got in, one element at a time | ||
| 30 | local yielder = function(...) | ||
| 31 | local utils = lanes.require "_utils" | ||
| 32 | local PRINT = utils.MAKE_PRINT() | ||
| 33 | PRINT "In lane" | ||
| 34 | for _i = 1, select('#', ...) do | ||
| 35 | local _val = select(_i, ...) | ||
| 36 | PRINT("yielding #", _i, _val) | ||
| 37 | local _ack = coroutine.yield(_val) | ||
| 38 | assert(_ack == _i) | ||
| 39 | end | ||
| 40 | return "done!" | ||
| 41 | end | ||
| 42 | |||
| 43 | if true then | ||
| 44 | -- if we start a non-coroutine lane with a yielding function, we should get an error, right? | ||
| 45 | local fun_g = lanes.gen("*", { name = 'auto' }, yielder) | ||
| 46 | local h = fun_g("hello", "world", "!") | ||
| 47 | local err, status, stack = h:join() | ||
| 48 | PRINT(err, status, stack) | ||
| 49 | -- the actual error message is not the same for Lua 5.1 | ||
| 50 | -- of course, it also has to be different for LuaJIT as well | ||
| 51 | -- also, LuaJIT prepends a file:line to the actual error message, which Lua5.1 does not. | ||
| 52 | local msgs = { | ||
| 53 | ["Lua 5.1"] = jit and "attempt to yield across C-call boundary" or "attempt to yield across metamethod/C-call boundary", | ||
| 54 | ["Lua 5.2"] = "attempt to yield from outside a coroutine", | ||
| 55 | ["Lua 5.3"] = "attempt to yield from outside a coroutine", | ||
| 56 | ["Lua 5.4"] = "attempt to yield from outside a coroutine" | ||
| 57 | } | ||
| 58 | local expected_msg = msgs[_VERSION] | ||
| 59 | PRINT("expected_msg = " .. expected_msg) | ||
| 60 | assert(err == nil and string.find(status, expected_msg, 1, true) and stack == nil, "status = " .. status) | ||
| 61 | end | ||
| 62 | |||
| 63 | -- the generator | ||
| 64 | local coro_g = lanes.coro("*", {name = "auto"}, yielder) | ||
| 65 | |||
| 66 | if true then | ||
| 67 | -- launch coroutine lane | ||
| 68 | local h2 = coro_g("hello", "world", "!") | ||
| 69 | -- read the yielded values, sending back the expected index | ||
| 70 | assert(h2:resume(1) == "hello") | ||
| 71 | assert(h2:resume(2) == "world") | ||
| 72 | assert(h2:resume(3) == "!") | ||
| 73 | -- the lane return value is available as usual | ||
| 74 | local r = h2[1] | ||
| 75 | assert(r == "done!") | ||
| 76 | end | ||
| 77 | |||
| 78 | if true then | ||
| 79 | -- another coroutine lane | ||
| 80 | local h3 = coro_g("hello", "world", "!") | ||
| 81 | |||
| 82 | -- yielded values are available as regular return values | ||
| 83 | assert(h3[1] == "hello" and h3.status == "suspended") | ||
| 84 | -- since we consumed the returned values, they should not be here when we resume | ||
| 85 | assert(h3:resume(1) == nil) | ||
| 86 | |||
| 87 | -- similarly, we can get them with join() | ||
| 88 | local r3, ret3 = h3:join() | ||
| 89 | assert(r3 == true and ret3 == "world" and h3.status == "suspended") | ||
| 90 | -- since we consumed the returned values, they should not be here when we resume | ||
| 91 | assert(h3:resume(2) == nil) | ||
| 92 | |||
| 93 | -- the rest should work as usual | ||
| 94 | assert(h3:resume(3) == "!") | ||
| 95 | |||
| 96 | -- the final return value of the lane body remains to be read | ||
| 97 | local r3, ret3 = h3:join() | ||
| 98 | assert(r3 == true and ret3 == "done!" and h3.status == "done") | ||
| 99 | end | ||
