diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-11 15:14:52 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-11 15:14:52 +0200 |
commit | adaa36dbec1ce9aaafd61873b9d3d898a8c240cf (patch) | |
tree | 4c81e8f5983c3d696a636e2cc433ce7c0a9c3dd8 /tests/cancel.lua | |
parent | 1d310e6ecb6e156598337612f16573d9cd284f5e (diff) | |
download | lanes-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.lua | 212 |
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 @@ | |||
1 | local lanes = require "lanes" .configure{ with_timers = false} | 1 | local which_tests, remaining_tests = {}, {} |
2 | 2 | for k,v in ipairs{...} do | |
3 | local linda = lanes.linda() | 3 | print("got arg:", type(v), tostring(v)) |
4 | which_tests[v] = true | ||
5 | remaining_tests[v] = true | ||
6 | end | ||
4 | 7 | ||
5 | --#################################################################### | 8 | --#################################################################### |
6 | print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" | ||
7 | |||
8 | -- get a lock and a atomic operator | ||
9 | local lock = lanes.genlock( linda, "lock", 1) | ||
10 | local atomic = lanes.genatomic( linda, "atomic") | ||
11 | |||
12 | -- check that cancelled lindas give cancel_error as they should | ||
13 | linda:cancel() | ||
14 | assert( linda:get( "empty") == lanes.cancel_error) | ||
15 | assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error) | ||
16 | assert( lanes.genatomic( linda, "any") == lanes.cancel_error) | ||
17 | |||
18 | -- check that lock and atomic functions return cancel_error if the linda was cancelled | ||
19 | assert( lock( 1) == lanes.cancel_error) | ||
20 | assert( lock( -1) == lanes.cancel_error) | ||
21 | assert( atomic( 1) == lanes.cancel_error) | ||
22 | |||
23 | -- reset the linda so that the other tests work | ||
24 | linda:cancel( "none") | ||
25 | linda:limit( "lock", -1) | ||
26 | linda:set( "lock") | ||
27 | linda:limit( "atomic", -1) | ||
28 | linda:set( "atomic") | ||
29 | 9 | ||
10 | local lanes = require "lanes" .configure{ with_timers = false} | ||
11 | |||
12 | local linda = lanes.linda() | ||
30 | -- a numeric value to read | 13 | -- a numeric value to read |
31 | linda:set( "val", 33.0) | 14 | linda:set( "val", 33.0) |
32 | 15 | ||
33 | print "test OK" | 16 | --#################################################################### |
17 | if 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" | ||
44 | end | ||
34 | --#################################################################### | 45 | --#################################################################### |
35 | 46 | ||
36 | local waitCancellation = function( h, expected_status) | 47 | local waitCancellation = function( h, expected_status) |
@@ -119,92 +130,115 @@ end | |||
119 | --#################################################################### | 130 | --#################################################################### |
120 | --#################################################################### | 131 | --#################################################################### |
121 | 132 | ||
122 | print "\n\n####################################################################\nbegin linda cancel test\n" | 133 | if not next(which_tests) or which_tests.linda then |
123 | h = 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" | |
125 | print "wait 1s" | 136 | h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda |
126 | linda:receive( 1, "yeah") | ||
127 | |||
128 | -- linda cancel: linda:receive() returns cancel_error immediately | ||
129 | linda:cancel( "both") | ||
130 | 137 | ||
131 | -- wait until cancellation is effective. | 138 | print "wait 1s" |
132 | waitCancellation( 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 |
135 | linda:cancel( "none") | 142 | print "cancelling" |
143 | linda:cancel( "both") | ||
136 | 144 | ||
137 | print "\n\n####################################################################\nbegin soft cancel test\n" | 145 | -- wait until cancellation is effective. |
138 | h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda | 146 | waitCancellation( h, "done") |
139 | 147 | ||
140 | print "wait 1s" | 148 | -- reset the linda so that the other tests work |
141 | linda:receive( 1, "yeah") | 149 | linda:cancel( "none") |
150 | end | ||
142 | 151 | ||
143 | -- soft cancel, no awakening of waiting linda operations, should timeout | 152 | if not next(which_tests) or which_tests.soft then |
144 | local 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" |
146 | assert( a == false and b == "timeout") | 155 | h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda |
147 | waitCancellation( h, "waiting") | ||
148 | 156 | ||
149 | -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. | 157 | print "wait 1s" |
150 | h: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 |
153 | waitCancellation( 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 | ||
157 | print "\n\n####################################################################\nbegin hook cancel test\n" | 170 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message |
158 | h = lanes.gen( "*", protectedBody)( "get", 300000) | 171 | waitCancellation( h, "done") |
159 | print "wait 2s" | 172 | end |
160 | linda:receive( 2, "yeah") | ||
161 | 173 | ||
162 | -- count hook cancel after 3 instructions | 174 | if not next(which_tests) or which_tests.hook then |
163 | h: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 |
166 | waitCancellation( h, "cancelled") | 182 | print "cancelling" |
183 | h:cancel( "line", 300, 5.0) | ||
167 | 184 | ||
168 | print "\n\n####################################################################\nbegin hard cancel test\n" | 185 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message |
169 | h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout | 186 | waitCancellation( h, "cancelled") |
187 | end | ||
170 | 188 | ||
171 | -- wait 2s before cancelling the lane | 189 | if not next(which_tests) or which_tests.hard then |
172 | print "wait 2s" | 190 | remaining_tests.hard = nil |
173 | linda: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 |
176 | h: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 |
179 | waitCancellation( h, "cancelled") | 199 | print "cancelling" |
200 | h:cancel() | ||
180 | 201 | ||
181 | print "\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 |
182 | h = lanes.gen( "*", laneBody)( "receive", nil) | 203 | waitCancellation( h, "cancelled") |
204 | end | ||
183 | 205 | ||
184 | -- wait 2s before cancelling the lane | 206 | if not next(which_tests) or which_tests.hard_unprotected then |
185 | print "wait 2s" | 207 | remaining_tests.hard_unprotected = nil |
186 | linda: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 |
189 | h: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 |
192 | waitCancellation( h, "cancelled") | 216 | print "cancelling" |
217 | h:cancel() | ||
193 | 218 | ||
194 | print "\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 |
195 | h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane | 220 | waitCancellation( h, "cancelled") |
221 | end | ||
196 | 222 | ||
197 | -- wait 1/3s before cancelling the lane, before the busy loop can finish | 223 | if not next(which_tests) or which_tests.kill then |
198 | print "wait 0.3s" | 224 | remaining_tests.kill = nil |
199 | linda: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 |
202 | h: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 |
205 | waitCancellation( 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") | ||
238 | end | ||
207 | --#################################################################### | 239 | --#################################################################### |
208 | 240 | ||
209 | print "\ndone" | 241 | local unknown_test, val = next(remaining_tests) |
242 | assert(not unknown_test, tostring(unknown_test) .. " test is unknown") | ||
210 | 243 | ||
244 | print "\nTHE END" | ||