diff options
Diffstat (limited to 'tests/cancel.lua')
-rw-r--r-- | tests/cancel.lua | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/tests/cancel.lua b/tests/cancel.lua new file mode 100644 index 0000000..0aab341 --- /dev/null +++ b/tests/cancel.lua | |||
@@ -0,0 +1,93 @@ | |||
1 | local lanes = require "lanes" .configure{ with_timers = false} | ||
2 | |||
3 | local linda = lanes.linda() | ||
4 | |||
5 | local laneBody = function( timeout_) | ||
6 | set_finalizer( function( err, stk) | ||
7 | if err == lanes.cancel_error then | ||
8 | -- note that we don't get the cancel_error when running wrapped inside a protected call if it doesn't rethrow it | ||
9 | print( " laneBody after cancel" ) | ||
10 | elseif err then | ||
11 | print( " laneBody error: "..tostring(err)) | ||
12 | else | ||
13 | print(" laneBody finalized") | ||
14 | end | ||
15 | end) | ||
16 | |||
17 | print( " entering lane with " .. tostring( timeout_) .. " timeout") | ||
18 | repeat | ||
19 | -- block-wait to be hard-cancelled | ||
20 | print " lane calling receive()" | ||
21 | local key, val = linda:receive( timeout_, "boob") | ||
22 | print( " receive() -> ", lanes.cancel_error == key and "cancel_error" or tostring( key), tostring( val)) | ||
23 | until cancel_test() -- soft cancel self test | ||
24 | print " shutting down after breaking out of loop" | ||
25 | end | ||
26 | |||
27 | local protectedBody = function( ...) | ||
28 | local ce = lanes.cancel_error | ||
29 | local errorHandler = function( _msg) | ||
30 | -- forward the message to the main thread that will display it with a popup | ||
31 | print( " error handler got ", ce == _msg and "cancel_error"or tostring( _msg)) | ||
32 | return _msg | ||
33 | end | ||
34 | -- Lua 5.1 doesn't pass additional xpcall arguments to the called function | ||
35 | -- therefore we need to create a closure that has no arguments but pulls everything from its upvalue | ||
36 | local params = {...} | ||
37 | local paramLessClosure = function() laneBody(table.unpack( params)) end | ||
38 | local status, message = xpcall( paramLessClosure, errorHandler) | ||
39 | if status == false then | ||
40 | print( " error handler rethrowing '" .. (ce == message and "cancel_error"or tostring( message)) .. "'") | ||
41 | -- if the error isn't rethrown, the lane's finalizer won't get it | ||
42 | error( message) | ||
43 | end | ||
44 | end | ||
45 | |||
46 | --#################################################################### | ||
47 | |||
48 | print "####################################################################\nbegin soft cancel test\n" | ||
49 | h = lanes.gen("*", protectedBody)( 0.666) | ||
50 | print "wait 3s" | ||
51 | linda:receive( 3, "yeah") | ||
52 | |||
53 | -- soft cancel | ||
54 | print "soft cancel with awakening" | ||
55 | h:cancel( -1, true) | ||
56 | |||
57 | -- wait 10s: the lane will interrupt its loop and print the exit message | ||
58 | print "wait 2s" | ||
59 | linda:receive( 2, "yeah") | ||
60 | |||
61 | --#################################################################### | ||
62 | |||
63 | print "\n\n####################################################################\nbegin hard cancel test\n" | ||
64 | h = lanes.gen("*", protectedBody)() | ||
65 | |||
66 | -- wait 3s before cancelling the lane | ||
67 | print "wait 3s" | ||
68 | linda:receive( 3, "yeah") | ||
69 | |||
70 | -- hard cancel and wait 10s: the lane will be interrupted from inside its current linda:receive() and won't return from it | ||
71 | print "hard cancel (always awakens)" | ||
72 | h:cancel() | ||
73 | |||
74 | print "wait 5s" | ||
75 | linda:receive( 5, "yeah") | ||
76 | |||
77 | --#################################################################### | ||
78 | |||
79 | print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" | ||
80 | h = lanes.gen("*", laneBody)() | ||
81 | |||
82 | -- wait 3s before cancelling the lane | ||
83 | print "wait 3s" | ||
84 | linda:receive( 3, "yeah") | ||
85 | |||
86 | -- hard cancel and wait 10s: the lane will be interrupted from inside its current linda:receive() and won't return from it | ||
87 | print "hard cancel (always awakens)" | ||
88 | h:cancel() | ||
89 | |||
90 | print "wait 5s" | ||
91 | linda:receive( 5, "yeah") | ||
92 | |||
93 | print "\ndone" \ No newline at end of file | ||