aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/launch.json2
-rw-r--r--Makefile4
-rw-r--r--tests/basic.lua33
-rw-r--r--unit_tests/UnitTests.vcxproj1
-rw-r--r--unit_tests/UnitTests.vcxproj.filters3
-rw-r--r--unit_tests/lane_tests.cpp2
-rw-r--r--unit_tests/scripts/lane/tasking_cancelling.lua89
-rw-r--r--unit_tests/scripts/lane/tasking_cancelling_with_hook.lua68
8 files changed, 120 insertions, 82 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index c4de37e..a2781fd 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -10,7 +10,7 @@
10 "args": [ 10 "args": [
11 //"--list-tests", 11 //"--list-tests",
12 "--rng-seed 0", 12 "--rng-seed 0",
13 "-s scripted_tests.legacy.basic" 13 "-s scripted_tests.lane.tasking_cancelling"
14 ], 14 ],
15 "stopAtEntry": true, 15 "stopAtEntry": true,
16 "cwd": "${workspaceFolder}", 16 "cwd": "${workspaceFolder}",
diff --git a/Makefile b/Makefile
index 2d7694c..98fa1ac 100644
--- a/Makefile
+++ b/Makefile
@@ -80,12 +80,12 @@ build_DUE:
80run_unit_tests: build_lanes build_unit_tests build_DUE 80run_unit_tests: build_lanes build_unit_tests build_DUE
81 @echo ========================================================================================= 81 @echo =========================================================================================
82 $(_PREFIX) $(_UNITTEST_TARGET) --list-tests 82 $(_PREFIX) $(_UNITTEST_TARGET) --list-tests
83 $(_PREFIX) $(_UNITTEST_TARGET) --rng-seed 0 -s 83 $(_PREFIX) $(_UNITTEST_TARGET) --rng-seed 0 -s scripted_tests.lane.tasking_cancelling
84 84
85debug_unit_tests: build_lanes build_unit_tests build_DUE 85debug_unit_tests: build_lanes build_unit_tests build_DUE
86 @echo ========================================================================================= 86 @echo =========================================================================================
87 $(_PREFIX) $(_UNITTEST_TARGET) --list-tests 87 $(_PREFIX) $(_UNITTEST_TARGET) --list-tests
88 $(_PREFIX) gdb --args $(_UNITTEST_TARGET) --list-tests --rng-seed 0 -s "scripted_tests.legacy.basic" 88 $(_PREFIX) gdb --args $(_UNITTEST_TARGET) --rng-seed 0 -s scripted_tests.lane.tasking_cancelling
89 89
90clean: 90clean:
91 cd src && $(MAKE) -f Lanes.makefile clean 91 cd src && $(MAKE) -f Lanes.makefile clean
diff --git a/tests/basic.lua b/tests/basic.lua
index 068dc25..170e821 100644
--- a/tests/basic.lua
+++ b/tests/basic.lua
@@ -173,29 +173,38 @@ for k, v in pairs(limited:dump()) do
173end 173end
174local wait_send = function() 174local wait_send = function()
175 local a,b 175 local a,b
176 set_finalizer(function() print("wait_send", a, b) end) 176 set_finalizer(function(err, stack_tbl) print("wait_send", a, b, " -> ", tostring(err)) end)
177 print("in wait_send")
177 a,b = limited:send("key", "bybye") -- infinite timeout, returns only when lane is cancelled 178 a,b = limited:send("key", "bybye") -- infinite timeout, returns only when lane is cancelled
178end 179end
179 180
180local wait_send_lane = lanes.gen("*", { name = 'auto' }, wait_send)() 181local wait_send_lane = lanes.gen("*", { name = 'auto' }, wait_send)()
181repeat until wait_send_lane.status == "waiting" 182repeat
182print "wait_send_lane is waiting" 183 io.stderr:write('!')
184 -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled)
185 lanes.sleep(0.1)
186until wait_send_lane.status == "waiting"
187PRINT "wait_send_lane is waiting"
183wait_send_lane:cancel() -- hard cancel, 0 timeout 188wait_send_lane:cancel() -- hard cancel, 0 timeout
184repeat until wait_send_lane.status == "cancelled" 189repeat until wait_send_lane.status == "cancelled"
185print "wait_send_lane is cancelled" 190PRINT "wait_send_lane is cancelled"
186--################################################]] 191--################################################]]
187local wait_receive = function() 192local wait_receive = function()
188 local k, v 193 local k, v
189 set_finalizer(function() print("wait_receive", k, v) end) 194 set_finalizer(function(err, stack_tbl) print("wait_receive", k, v, " -> ", tostring(err)) end)
190 k, v = limited:receive("dummy") -- infinite timeout, returns only when lane is cancelled 195 k, v = limited:receive("dummy") -- infinite timeout, returns only when lane is cancelled
191end 196end
192 197
193local wait_receive_lane = lanes.gen("*", { name = 'auto' }, wait_receive)() 198local wait_receive_lane = lanes.gen("*", { name = 'auto' }, wait_receive)()
194repeat until wait_receive_lane.status == "waiting" 199repeat
195print "wait_receive_lane is waiting" 200 io.stderr:write('!')
201 -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled)
202 lanes.sleep(0.1)
203until wait_receive_lane.status == "waiting"
204PRINT "wait_receive_lane is waiting"
196wait_receive_lane:cancel() -- hard cancel, 0 timeout 205wait_receive_lane:cancel() -- hard cancel, 0 timeout
197repeat until wait_receive_lane.status == "cancelled" 206repeat until wait_receive_lane.status == "cancelled"
198print "wait_receive_lane is cancelled" 207PRINT "wait_receive_lane is cancelled"
199--################################################]] 208--################################################]]
200local wait_receive_batched = function() 209local wait_receive_batched = function()
201 local k, v1, v2 210 local k, v1, v2
@@ -205,10 +214,10 @@ end
205 214
206local wait_receive_batched_lane = lanes.gen("*", { name = 'auto' }, wait_receive_batched)() 215local wait_receive_batched_lane = lanes.gen("*", { name = 'auto' }, wait_receive_batched)()
207repeat until wait_receive_batched_lane.status == "waiting" 216repeat until wait_receive_batched_lane.status == "waiting"
208print "wait_receive_batched_lane is waiting" 217PRINT "wait_receive_batched_lane is waiting"
209wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout 218wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout
210repeat until wait_receive_batched_lane.status == "cancelled" 219repeat until wait_receive_batched_lane.status == "cancelled"
211print "wait_receive_batched_lane is cancelled" 220PRINT "wait_receive_batched_lane is cancelled"
212--################################################]] 221--################################################]]
213 222
214-- ################################################################################################## 223-- ##################################################################################################
@@ -437,7 +446,7 @@ local function chunk2(linda)
437 assert(config.strip_functions and info.short_src=="?" or string.match(info.short_src, "^.*basic.lua$"), "bad info.short_src") 446 assert(config.strip_functions and info.short_src=="?" or string.match(info.short_src, "^.*basic.lua$"), "bad info.short_src")
438 -- These vary so let's not be picky (they're there..) 447 -- These vary so let's not be picky (they're there..)
439 -- 448 --
440 assert(info.linedefined == 422, "bad linedefined") -- start of 'chunk2' 449 assert(info.linedefined == 431, "bad linedefined") -- start of 'chunk2'
441 assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo' 450 assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo'
442 assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2' 451 assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2'
443 local k,func= linda:receive("down") 452 local k,func= linda:receive("down")
@@ -460,7 +469,7 @@ linda:send("down", function(linda) linda:send("up", "ready!") end,
460-- 469--
461local k,s= linda:receive(1, "up") 470local k,s= linda:receive(1, "up")
462if t2.status == "error" then 471if t2.status == "error" then
463 print("t2 error: " , t2:join()) 472 PRINT("t2 error: " , t2:join())
464end 473end
465PRINT(s) 474PRINT(s)
466assert(s=="ready!") 475assert(s=="ready!")
diff --git a/unit_tests/UnitTests.vcxproj b/unit_tests/UnitTests.vcxproj
index e78e32a..e1370c3 100644
--- a/unit_tests/UnitTests.vcxproj
+++ b/unit_tests/UnitTests.vcxproj
@@ -967,6 +967,7 @@
967 </ItemGroup> 967 </ItemGroup>
968 <ItemGroup> 968 <ItemGroup>
969 <None Include="..\.runsettings" /> 969 <None Include="..\.runsettings" />
970 <None Include="scripts\lane\tasking_cancelling_with_hook.lua" />
970 <None Include="UnitTests.makefile" /> 971 <None Include="UnitTests.makefile" />
971 <None Include="scripts\coro\basics.lua" /> 972 <None Include="scripts\coro\basics.lua" />
972 <None Include="scripts\coro\error_handling.lua" /> 973 <None Include="scripts\coro\error_handling.lua" />
diff --git a/unit_tests/UnitTests.vcxproj.filters b/unit_tests/UnitTests.vcxproj.filters
index 3b45009..b0ce216 100644
--- a/unit_tests/UnitTests.vcxproj.filters
+++ b/unit_tests/UnitTests.vcxproj.filters
@@ -113,5 +113,8 @@
113 <None Include="..\.runsettings"> 113 <None Include="..\.runsettings">
114 <Filter>Catch2</Filter> 114 <Filter>Catch2</Filter>
115 </None> 115 </None>
116 <None Include="scripts\lane\tasking_cancelling_with_hook.lua">
117 <Filter>Scripts\lane</Filter>
118 </None>
116 </ItemGroup> 119 </ItemGroup>
117</Project> \ No newline at end of file 120</Project> \ No newline at end of file
diff --git a/unit_tests/lane_tests.cpp b/unit_tests/lane_tests.cpp
index 0a392d8..1367ae5 100644
--- a/unit_tests/lane_tests.cpp
+++ b/unit_tests/lane_tests.cpp
@@ -332,6 +332,7 @@ MAKE_TEST_CASE(lane, cooperative_shutdown, AssertNoLuaError)
332MAKE_TEST_CASE(lane, uncooperative_shutdown, AssertWarns) 332MAKE_TEST_CASE(lane, uncooperative_shutdown, AssertWarns)
333#endif // LUA_VERSION_NUM 333#endif // LUA_VERSION_NUM
334MAKE_TEST_CASE(lane, tasking_basic, AssertNoLuaError) 334MAKE_TEST_CASE(lane, tasking_basic, AssertNoLuaError)
335MAKE_TEST_CASE(lane, tasking_cancelling_with_hook, AssertNoLuaError)
335MAKE_TEST_CASE(lane, tasking_cancelling, AssertNoLuaError) 336MAKE_TEST_CASE(lane, tasking_cancelling, AssertNoLuaError)
336MAKE_TEST_CASE(lane, tasking_comms_criss_cross, AssertNoLuaError) 337MAKE_TEST_CASE(lane, tasking_comms_criss_cross, AssertNoLuaError)
337MAKE_TEST_CASE(lane, tasking_communications, AssertNoLuaError) 338MAKE_TEST_CASE(lane, tasking_communications, AssertNoLuaError)
@@ -352,6 +353,7 @@ TEST_CASE("lanes.scripted_tests")
352 FileRunnerParam{ PUC_LUA_ONLY("lane/cooperative_shutdown"), TestType::AssertNoLuaError }, // 0 353 FileRunnerParam{ PUC_LUA_ONLY("lane/cooperative_shutdown"), TestType::AssertNoLuaError }, // 0
353 FileRunnerParam{ "lane/uncooperative_shutdown", TestType::AssertWarns }, 354 FileRunnerParam{ "lane/uncooperative_shutdown", TestType::AssertWarns },
354 FileRunnerParam{ "lane/tasking_basic", TestType::AssertNoLuaError }, // 2 355 FileRunnerParam{ "lane/tasking_basic", TestType::AssertNoLuaError }, // 2
356 FileRunnerParam{ "lane/tasking_cancelling_with_hook", TestType::AssertNoLuaError }, // 3
355 FileRunnerParam{ "lane/tasking_cancelling", TestType::AssertNoLuaError }, // 3 357 FileRunnerParam{ "lane/tasking_cancelling", TestType::AssertNoLuaError }, // 3
356 FileRunnerParam{ "lane/tasking_comms_criss_cross", TestType::AssertNoLuaError }, // 4 358 FileRunnerParam{ "lane/tasking_comms_criss_cross", TestType::AssertNoLuaError }, // 4
357 FileRunnerParam{ "lane/tasking_communications", TestType::AssertNoLuaError }, 359 FileRunnerParam{ "lane/tasking_communications", TestType::AssertNoLuaError },
diff --git a/unit_tests/scripts/lane/tasking_cancelling.lua b/unit_tests/scripts/lane/tasking_cancelling.lua
index 85600ab..8bee3a6 100644
--- a/unit_tests/scripts/lane/tasking_cancelling.lua
+++ b/unit_tests/scripts/lane/tasking_cancelling.lua
@@ -15,69 +15,12 @@ local lanes_linda = assert(lanes.linda)
15-- ################################################################################################## 15-- ##################################################################################################
16-- ################################################################################################## 16-- ##################################################################################################
17 17
18local function task(a, b, c)
19 lane_threadname("task("..a..","..b..","..c..")")
20 --error "111" -- testing error messages
21 assert(hey)
22 local v=0
23 for i=a,b,c do
24 v= v+i
25 end
26 return v, hey
27end
28
29local gc_cb = function(name_, status_)
30 PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'")
31end
32
33-- ##################################################################################################
34-- ##################################################################################################
35-- ##################################################################################################
36
37PRINT("\n\n", "---=== Tasking (cancelling) ===---", "\n\n")
38
39local task_launch2 = lanes_gen("", { name = 'auto', globals={hey=true}, gc_cb = gc_cb }, task)
40
41local N=999999999
42local lane9= task_launch2(1,N,1) -- huuuuuuge...
43
44-- Wait until state changes "pending"->"running"
45--
46local st
47local t0= os.time()
48while os.time()-t0 < 5 do
49 st= lane9.status
50 io.stderr:write((i==1) and st.." " or '.')
51 if st~="pending" then break end
52end
53PRINT(" "..st)
54
55if st=="error" then
56 local _= lane9[0] -- propagate the error here
57end
58if st=="done" then
59 error("Looping to "..N.." was not long enough (cannot test cancellation)")
60end
61assert(st=="running", "st == " .. st)
62
63-- when running under luajit, the function is JIT-ed, and the instruction count isn't hit, so we need a different hook
64lane9:cancel(jit and "line" or "count", 100) -- 0 timeout, hook triggers cancelslation when reaching the specified count
65
66local t0= os.time()
67while os.time()-t0 < 5 do
68 st= lane9.status
69 io.stderr:write((i==1) and st.." " or '.')
70 if st~="running" then break end
71end
72PRINT(" "..st)
73assert(st == "cancelled", "st is '" .. st .. "' instead of 'cancelled'")
74
75-- cancellation of lanes waiting on a linda 18-- cancellation of lanes waiting on a linda
76local limited = lanes_linda("limited") 19local limited = lanes_linda("limited")
77assert.fails(function() limited:limit("key", -1) end) 20assert.fails(function() limited:limit("key", -1) end)
78assert.failsnot(function() limited:limit("key", 1) end) 21assert.failsnot(function() limited:limit("key", 1) end)
79-- [[################################################ 22-- [[################################################
80limited:send("key", "hello") -- saturate linda 23limited:send("key", "hello") -- saturate linda, so that subsequent sends will block
81for k, v in pairs(limited:dump()) do 24for k, v in pairs(limited:dump()) do
82 PRINT("limited[" .. tostring(k) .. "] = " .. tostring(v)) 25 PRINT("limited[" .. tostring(k) .. "] = " .. tostring(v))
83end 26end
@@ -88,11 +31,15 @@ local wait_send = function()
88end 31end
89 32
90local wait_send_lane = lanes_gen("*", { name = 'auto' }, wait_send)() 33local wait_send_lane = lanes_gen("*", { name = 'auto' }, wait_send)()
91repeat until wait_send_lane.status == "waiting" 34repeat
92print "wait_send_lane is waiting" 35 io.stderr:write('!')
36 -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled)
37 lanes.sleep(0.1)
38until wait_send_lane.status == "waiting"
39PRINT "wait_send_lane is waiting"
93wait_send_lane:cancel() -- hard cancel, 0 timeout 40wait_send_lane:cancel() -- hard cancel, 0 timeout
94repeat until wait_send_lane.status == "cancelled" 41repeat until wait_send_lane.status == "cancelled"
95print "wait_send_lane is cancelled" 42PRINT "wait_send_lane is cancelled"
96--################################################]] 43--################################################]]
97local wait_receive = function() 44local wait_receive = function()
98 local k, v 45 local k, v
@@ -101,11 +48,15 @@ local wait_receive = function()
101end 48end
102 49
103local wait_receive_lane = lanes_gen("*", { name = 'auto' }, wait_receive)() 50local wait_receive_lane = lanes_gen("*", { name = 'auto' }, wait_receive)()
104repeat until wait_receive_lane.status == "waiting" 51repeat
105print "wait_receive_lane is waiting" 52 io.stderr:write('!')
53 -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled)
54 lanes.sleep(0.1)
55until wait_receive_lane.status == "waiting"
56PRINT "wait_receive_lane is waiting"
106wait_receive_lane:cancel() -- hard cancel, 0 timeout 57wait_receive_lane:cancel() -- hard cancel, 0 timeout
107repeat until wait_receive_lane.status == "cancelled" 58repeat until wait_receive_lane.status == "cancelled"
108print "wait_receive_lane is cancelled" 59PRINT "wait_receive_lane is cancelled"
109--################################################]] 60--################################################]]
110local wait_receive_batched = function() 61local wait_receive_batched = function()
111 local k, v1, v2 62 local k, v1, v2
@@ -114,9 +65,13 @@ local wait_receive_batched = function()
114end 65end
115 66
116local wait_receive_batched_lane = lanes_gen("*", { name = 'auto' }, wait_receive_batched)() 67local wait_receive_batched_lane = lanes_gen("*", { name = 'auto' }, wait_receive_batched)()
117repeat until wait_receive_batched_lane.status == "waiting" 68repeat
118print "wait_receive_batched_lane is waiting" 69 io.stderr:write('!')
70 -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled)
71 lanes.sleep(0.1)
72until wait_receive_batched_lane.status == "waiting"
73PRINT "wait_receive_batched_lane is waiting"
119wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout 74wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout
120repeat until wait_receive_batched_lane.status == "cancelled" 75repeat until wait_receive_batched_lane.status == "cancelled"
121print "wait_receive_batched_lane is cancelled" 76PRINT "wait_receive_batched_lane is cancelled"
122--################################################]] 77--################################################]]
diff --git a/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua b/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua
new file mode 100644
index 0000000..56b934f
--- /dev/null
+++ b/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua
@@ -0,0 +1,68 @@
1local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure(config).configure()
2print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2)
3local lanes = require_lanes_result_1
4
5local require_assert_result_1, require_assert_result_2 = require "_assert"
6print("require_assert_result:", require_assert_result_1, require_assert_result_2)
7
8local utils = lanes.require "_utils"
9local PRINT = utils.MAKE_PRINT()
10
11-- ##################################################################################################
12-- ##################################################################################################
13-- ##################################################################################################
14
15local function task(a, b, c)
16 lane_threadname("task("..a..","..b..","..c..")")
17 --error "111" -- testing error messages
18 assert(hey)
19 local v=0
20 for i=a,b,c do
21 v= v+i
22 end
23 return v, hey
24end
25
26local gc_cb = function(name_, status_)
27 PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'")
28end
29
30-- ##################################################################################################
31-- ##################################################################################################
32-- ##################################################################################################
33
34local generator = lanes.gen("", { name = 'auto', globals={hey=true}, gc_cb = gc_cb }, task)
35
36local N = 999999999
37local lane_h = generator(1,N,1) -- huuuuuuge...
38
39-- Wait until state changes "pending"->"running"
40--
41local st
42local t0 = os.time()
43while os.time()-t0 < 5 do
44 st = lane_h.status
45 io.stderr:write((i==1) and st.." " or '.')
46 if st~="pending" then break end
47end
48PRINT(" "..st)
49
50if st == "error" then
51 local _ = lane_h[0] -- propagate the error here
52end
53if st == "done" then
54 error("Looping to "..N.." was not long enough (cannot test cancellation)")
55end
56assert(st == "running", "st == " .. st)
57
58-- when running under luajit, the function is JIT-ed, and the instruction count isn't hit, so we need a different hook
59lane_h:cancel(jit and "line" or "count", 100) -- 0 timeout, hook triggers cancelslation when reaching the specified count
60
61local t0 = os.time()
62while os.time()-t0 < 5 do
63 st = lane_h.status
64 io.stderr:write((i==1) and st.." " or '.')
65 if st~="running" then break end
66end
67PRINT(" "..st)
68assert(st == "cancelled", "st is '" .. st .. "' instead of 'cancelled'")