aboutsummaryrefslogtreecommitdiff
path: root/tests/cancel.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cancel.lua')
-rw-r--r--tests/cancel.lua93
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 @@
1local lanes = require "lanes" .configure{ with_timers = false}
2
3local linda = lanes.linda()
4
5local 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"
25end
26
27local 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
44end
45
46--####################################################################
47
48print "####################################################################\nbegin soft cancel test\n"
49h = lanes.gen("*", protectedBody)( 0.666)
50print "wait 3s"
51linda:receive( 3, "yeah")
52
53-- soft cancel
54print "soft cancel with awakening"
55h:cancel( -1, true)
56
57-- wait 10s: the lane will interrupt its loop and print the exit message
58print "wait 2s"
59linda:receive( 2, "yeah")
60
61--####################################################################
62
63print "\n\n####################################################################\nbegin hard cancel test\n"
64h = lanes.gen("*", protectedBody)()
65
66-- wait 3s before cancelling the lane
67print "wait 3s"
68linda: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
71print "hard cancel (always awakens)"
72h:cancel()
73
74print "wait 5s"
75linda:receive( 5, "yeah")
76
77--####################################################################
78
79print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n"
80h = lanes.gen("*", laneBody)()
81
82-- wait 3s before cancelling the lane
83print "wait 3s"
84linda: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
87print "hard cancel (always awakens)"
88h:cancel()
89
90print "wait 5s"
91linda:receive( 5, "yeah")
92
93print "\ndone" \ No newline at end of file