aboutsummaryrefslogtreecommitdiff
path: root/tests/cancel.lua
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-04-11 15:14:52 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-04-11 15:14:52 +0200
commitadaa36dbec1ce9aaafd61873b9d3d898a8c240cf (patch)
tree4c81e8f5983c3d696a636e2cc433ce7c0a9c3dd8 /tests/cancel.lua
parent1d310e6ecb6e156598337612f16573d9cd284f5e (diff)
downloadlanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.tar.gz
lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.tar.bz2
lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.zip
Bring all interesting fixes from the C++ implementation back into the C implementation
Diffstat (limited to 'tests/cancel.lua')
-rw-r--r--tests/cancel.lua212
1 files changed, 123 insertions, 89 deletions
diff --git a/tests/cancel.lua b/tests/cancel.lua
index 0d9d143..4e57184 100644
--- a/tests/cancel.lua
+++ b/tests/cancel.lua
@@ -1,36 +1,47 @@
1local lanes = require "lanes" .configure{ with_timers = false} 1local which_tests, remaining_tests = {}, {}
2 2for k,v in ipairs{...} do
3local linda = lanes.linda() 3 print("got arg:", type(v), tostring(v))
4 which_tests[v] = true
5 remaining_tests[v] = true
6end
4 7
5--#################################################################### 8--####################################################################
6print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n"
7
8-- get a lock and a atomic operator
9local lock = lanes.genlock( linda, "lock", 1)
10local atomic = lanes.genatomic( linda, "atomic")
11
12-- check that cancelled lindas give cancel_error as they should
13linda:cancel()
14assert( linda:get( "empty") == lanes.cancel_error)
15assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error)
16assert( lanes.genatomic( linda, "any") == lanes.cancel_error)
17
18-- check that lock and atomic functions return cancel_error if the linda was cancelled
19assert( lock( 1) == lanes.cancel_error)
20assert( lock( -1) == lanes.cancel_error)
21assert( atomic( 1) == lanes.cancel_error)
22
23-- reset the linda so that the other tests work
24linda:cancel( "none")
25linda:limit( "lock", -1)
26linda:set( "lock")
27linda:limit( "atomic", -1)
28linda:set( "atomic")
29 9
10local lanes = require "lanes" .configure{ with_timers = false}
11
12local linda = lanes.linda()
30-- a numeric value to read 13-- a numeric value to read
31linda:set( "val", 33.0) 14linda:set( "val", 33.0)
32 15
33print "test OK" 16--####################################################################
17if not next(which_tests) or which_tests.genlock then
18 remaining_tests.genlock = nil
19 print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n"
20
21 -- get a lock and a atomic operator
22 local lock = lanes.genlock( linda, "lock", 1)
23 local atomic = lanes.genatomic( linda, "atomic")
24
25 -- check that cancelled lindas give cancel_error as they should
26 linda:cancel()
27 assert( linda:get( "empty") == lanes.cancel_error)
28 assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error)
29 assert( lanes.genatomic( linda, "any") == lanes.cancel_error)
30
31 -- check that lock and atomic functions return cancel_error if the linda was cancelled
32 assert( lock( 1) == lanes.cancel_error)
33 assert( lock( -1) == lanes.cancel_error)
34 assert( atomic( 1) == lanes.cancel_error)
35
36 -- reset the linda so that the other tests work
37 linda:cancel( "none")
38 linda:limit( "lock", -1)
39 linda:set( "lock")
40 linda:limit( "atomic", -1)
41 linda:set( "atomic")
42
43 print "test OK"
44end
34--#################################################################### 45--####################################################################
35 46
36local waitCancellation = function( h, expected_status) 47local waitCancellation = function( h, expected_status)
@@ -119,92 +130,115 @@ end
119--#################################################################### 130--####################################################################
120--#################################################################### 131--####################################################################
121 132
122print "\n\n####################################################################\nbegin linda cancel test\n" 133if not next(which_tests) or which_tests.linda then
123h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda 134 remaining_tests.linda = nil
124 135 print "\n\n####################################################################\nbegin linda cancel test\n"
125print "wait 1s" 136 h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda
126linda:receive( 1, "yeah")
127
128-- linda cancel: linda:receive() returns cancel_error immediately
129linda:cancel( "both")
130 137
131-- wait until cancellation is effective. 138 print "wait 1s"
132waitCancellation( h, "done") 139 linda:receive( 1, "yeah")
133 140
134-- reset the linda so that the other tests work 141 -- linda cancel: linda:receive() returns cancel_error immediately
135linda:cancel( "none") 142 print "cancelling"
143 linda:cancel( "both")
136 144
137print "\n\n####################################################################\nbegin soft cancel test\n" 145 -- wait until cancellation is effective.
138h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda 146 waitCancellation( h, "done")
139 147
140print "wait 1s" 148 -- reset the linda so that the other tests work
141linda:receive( 1, "yeah") 149 linda:cancel( "none")
150end
142 151
143-- soft cancel, no awakening of waiting linda operations, should timeout 152if not next(which_tests) or which_tests.soft then
144local a, b = h:cancel( "soft", 1, false) 153 remaining_tests.soft = nil
145-- cancellation should fail as the lane is still waiting on its linda 154 print "\n\n####################################################################\nbegin soft cancel test\n"
146assert( a == false and b == "timeout") 155 h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda
147waitCancellation( h, "waiting")
148 156
149-- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. 157 print "wait 1s"
150h:cancel( "soft", true) 158 linda:receive( 1, "yeah")
151 159
152-- wait until cancellation is effective. the lane will interrupt its loop and print the exit message 160 -- soft cancel, no awakening of waiting linda operations, should timeout
153waitCancellation( h, "done") 161 local a, b = h:cancel( "soft", 1, false)
162 -- cancellation should fail as the lane is still waiting on its linda
163 assert( a == false and b == "timeout")
164 waitCancellation( h, "waiting")
154 165
155-- do return end 166 -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout.
167 print "cancelling"
168 h:cancel( "soft", true)
156 169
157print "\n\n####################################################################\nbegin hook cancel test\n" 170 -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message
158h = lanes.gen( "*", protectedBody)( "get", 300000) 171 waitCancellation( h, "done")
159print "wait 2s" 172end
160linda:receive( 2, "yeah")
161 173
162-- count hook cancel after 3 instructions 174if not next(which_tests) or which_tests.hook then
163h:cancel( "count", 300, 5.0) 175 remaining_tests.hook = nil
176 print "\n\n####################################################################\nbegin hook cancel test\n"
177 h = lanes.gen( "*", protectedBody)( "get", 300000)
178 print "wait 2s"
179 linda:receive( 2, "yeah")
164 180
165-- wait until cancellation is effective. the lane will interrupt its loop and print the exit message 181 -- count hook cancel after some instruction instructions
166waitCancellation( h, "cancelled") 182 print "cancelling"
183 h:cancel( "line", 300, 5.0)
167 184
168print "\n\n####################################################################\nbegin hard cancel test\n" 185 -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message
169h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout 186 waitCancellation( h, "cancelled")
187end
170 188
171-- wait 2s before cancelling the lane 189if not next(which_tests) or which_tests.hard then
172print "wait 2s" 190 remaining_tests.hard = nil
173linda:receive( 2, "yeah") 191 print "\n\n####################################################################\nbegin hard cancel test\n"
192 h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout
174 193
175-- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it 194 -- wait 2s before cancelling the lane
176h:cancel() 195 print "wait 2s"
196 linda:receive( 2, "yeah")
177 197
178-- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error 198 -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it
179waitCancellation( h, "cancelled") 199 print "cancelling"
200 h:cancel()
180 201
181print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" 202 -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error
182h = lanes.gen( "*", laneBody)( "receive", nil) 203 waitCancellation( h, "cancelled")
204end
183 205
184-- wait 2s before cancelling the lane 206if not next(which_tests) or which_tests.hard_unprotected then
185print "wait 2s" 207 remaining_tests.hard_unprotected = nil
186linda:receive( 2, "yeah") 208 print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n"
209 h = lanes.gen( "*", laneBody)( "receive", nil)
187 210
188-- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it 211 -- wait 2s before cancelling the lane
189h:cancel() 212 print "wait 2s"
213 linda:receive( 2, "yeah")
190 214
191-- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error 215 -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it
192waitCancellation( h, "cancelled") 216 print "cancelling"
217 h:cancel()
193 218
194print "\n\n####################################################################\nbegin kill cancel test\n" 219 -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error
195h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane 220 waitCancellation( h, "cancelled")
221end
196 222
197-- wait 1/3s before cancelling the lane, before the busy loop can finish 223if not next(which_tests) or which_tests.kill then
198print "wait 0.3s" 224 remaining_tests.kill = nil
199linda:receive( 0.3, "yeah") 225 print "\n\n####################################################################\nbegin kill cancel test\n"
226 h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane
200 227
201-- hard cancel with kill: the lane thread will be forcefully terminated 228 -- wait 1/3s before cancelling the lane, before the busy loop can finish
202h:cancel( true) 229 print "wait 0.3s"
230 linda:receive( 0.3, "yeah")
203 231
204-- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error 232 -- hard cancel with kill: the lane thread will be forcefully terminated. kill timeout is pthread-specific
205waitCancellation( h, "killed") 233 print "cancelling"
234 h:cancel( true, 1.0)
206 235
236 -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error
237 waitCancellation( h, "killed")
238end
207--#################################################################### 239--####################################################################
208 240
209print "\ndone" 241local unknown_test, val = next(remaining_tests)
242assert(not unknown_test, tostring(unknown_test) .. " test is unknown")
210 243
244print "\nTHE END"