diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/cancel.lua | 112 |
1 files changed, 56 insertions, 56 deletions
diff --git a/tests/cancel.lua b/tests/cancel.lua index e65d794..9b65ad3 100644 --- a/tests/cancel.lua +++ b/tests/cancel.lua | |||
@@ -24,7 +24,7 @@ end | |||
24 | 24 | ||
25 | local linda = lanes.linda() | 25 | local linda = lanes.linda() |
26 | -- a numeric value to read | 26 | -- a numeric value to read |
27 | linda:set( "val", 33.0) | 27 | linda:set("val", 33.0) |
28 | 28 | ||
29 | -- so that we can easily swap between lanes.gen and lanes.coro, to try stuff | 29 | -- so that we can easily swap between lanes.gen and lanes.coro, to try stuff |
30 | local generator = lanes.coro | 30 | local generator = lanes.coro |
@@ -36,27 +36,27 @@ if not next(which_tests) or which_tests.genlock then | |||
36 | print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" | 36 | print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" |
37 | 37 | ||
38 | -- get a lock and a atomic operator | 38 | -- get a lock and a atomic operator |
39 | local lock = lanes.genlock( linda, "lock", 1) | 39 | local lock = lanes.genlock(linda, "lock", 1) |
40 | local atomic = lanes.genatomic( linda, "atomic") | 40 | local atomic = lanes.genatomic(linda, "atomic") |
41 | 41 | ||
42 | local check_returned_cancel_error = function(_status, _err) | 42 | local check_returned_cancel_error = function(_status, _err) |
43 | assert(_status == nil and _err == lanes.cancel_error) | 43 | assert(_status == nil and _err == lanes.cancel_error) |
44 | end | 44 | end |
45 | -- check that cancelled lindas give cancel_error as they should | 45 | -- check that cancelled lindas give cancel_error as they should |
46 | linda:cancel() | 46 | linda:cancel() |
47 | check_returned_cancel_error(linda:set( "empty", 42)) | 47 | check_returned_cancel_error(linda:set("empty", 42)) |
48 | check_returned_cancel_error(linda:get( "empty")) | 48 | check_returned_cancel_error(linda:get("empty")) |
49 | check_returned_cancel_error(linda:send( "empty", 42)) | 49 | check_returned_cancel_error(linda:send("empty", 42)) |
50 | check_returned_cancel_error(linda:receive( "empty")) | 50 | check_returned_cancel_error(linda:receive("empty")) |
51 | check_returned_cancel_error(linda:limit( "empty", 5)) | 51 | check_returned_cancel_error(linda:limit("empty", 5)) |
52 | check_returned_cancel_error(linda:restrict( "empty", "set/get")) | 52 | check_returned_cancel_error(linda:restrict("empty", "set/get")) |
53 | assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error) | 53 | assert(lanes.genlock(linda, "any", 1) == lanes.cancel_error) |
54 | assert( lanes.genatomic( linda, "any") == lanes.cancel_error) | 54 | assert(lanes.genatomic(linda, "any") == lanes.cancel_error) |
55 | 55 | ||
56 | -- check that lock and atomic functions return cancel_error if the linda was cancelled | 56 | -- check that lock and atomic functions return cancel_error if the linda was cancelled |
57 | assert( lock( 1) == lanes.cancel_error) | 57 | assert(lock(1) == lanes.cancel_error) |
58 | assert( lock( -1) == lanes.cancel_error) | 58 | assert(lock(-1) == lanes.cancel_error) |
59 | assert( atomic( 1) == lanes.cancel_error) | 59 | assert(atomic(1) == lanes.cancel_error) |
60 | 60 | ||
61 | -- reset the linda so that the other tests work | 61 | -- reset the linda so that the other tests work |
62 | linda:cancel("none") | 62 | linda:cancel("none") |
@@ -70,62 +70,62 @@ end | |||
70 | 70 | ||
71 | -- ################################################################################################## | 71 | -- ################################################################################################## |
72 | 72 | ||
73 | local waitCancellation = function( h, expected_status) | 73 | local waitCancellation = function(h, expected_status) |
74 | local l = lanes.linda() | 74 | local l = lanes.linda() |
75 | if expected_status ~= "running" then | 75 | if expected_status ~= "running" then |
76 | repeat | 76 | repeat |
77 | -- print( "lane status:", h.status) | 77 | -- print("lane status:", h.status) |
78 | SLEEP(0.1) -- wait a bit | 78 | SLEEP(0.1) -- wait a bit |
79 | until h.status ~= "running" | 79 | until h.status ~= "running" |
80 | end | 80 | end |
81 | print( "lane status:", h.status) | 81 | print("lane status:", h.status) |
82 | assert( h.status == expected_status, "lane status " .. h.status .. " (actual) ~= " .. expected_status .. " (expected)") | 82 | assert(h.status == expected_status, "lane status " .. h.status .. " (actual) ~= " .. expected_status .. " (expected)") |
83 | print "test OK" | 83 | print "test OK" |
84 | end | 84 | end |
85 | 85 | ||
86 | local laneBody = function( mode_, payload_) | 86 | local laneBody = function(mode_, payload_) |
87 | local name = "laneBody("..tostring(mode_)..","..tostring(payload_)..")" | 87 | local name = "laneBody("..tostring(mode_)..","..tostring(payload_)..")" |
88 | lane_threadname(name) | 88 | lane_threadname(name) |
89 | 89 | ||
90 | set_finalizer( function( err, stk) | 90 | set_finalizer(function(err, stk) |
91 | if err == lanes.cancel_error then | 91 | if err == lanes.cancel_error then |
92 | -- note that we don't get the cancel_error when running wrapped inside a protected call if it doesn't rethrow it | 92 | -- note that we don't get the cancel_error when running wrapped inside a protected call if it doesn't rethrow it |
93 | print( " laneBody after cancel" ) | 93 | print(" laneBody after cancel" ) |
94 | elseif err then | 94 | elseif err then |
95 | print( " laneBody error: "..tostring(err)) | 95 | print(" laneBody error: "..tostring(err)) |
96 | else | 96 | else |
97 | print(" laneBody finalized") | 97 | print(" laneBody finalized") |
98 | end | 98 | end |
99 | end) | 99 | end) |
100 | 100 | ||
101 | print( " entering " , name) | 101 | print(" entering " , name) |
102 | repeat | 102 | repeat |
103 | if mode_ == "receive" then | 103 | if mode_ == "receive" then |
104 | -- linda mode | 104 | -- linda mode |
105 | io.stdout:write( " lane calling receive() ... ") | 105 | io.stdout:write(" lane calling receive() ... ") |
106 | local key, val = linda:receive( payload_, "boob") | 106 | local key, val = linda:receive(payload_, "boob") |
107 | print(tostring(key), val == lanes.cancel_error and "cancel_error" or tostring(val)) | 107 | print(tostring(key), val == lanes.cancel_error and "cancel_error" or tostring(val)) |
108 | if val == lanes.cancel_error then | 108 | if val == lanes.cancel_error then |
109 | break -- gracefully abort loop | 109 | break -- gracefully abort loop |
110 | end | 110 | end |
111 | elseif mode_ == "get" then | 111 | elseif mode_ == "get" then |
112 | -- busy wait mode getting data from the linda | 112 | -- busy wait mode getting data from the linda |
113 | io.stdout:write( " lane busy waiting ... ") | 113 | io.stdout:write(" lane busy waiting ... ") |
114 | for i = 1, payload_ do | 114 | for i = 1, payload_ do |
115 | -- force a non-jitable call | 115 | -- force a non-jitable call |
116 | local _, a = linda:get( "val") | 116 | local _, a = linda:get("val") |
117 | a = a * 2 | 117 | a = a * 2 |
118 | end | 118 | end |
119 | print( "again?") | 119 | print("again?") |
120 | elseif mode_ == "busy" then | 120 | elseif mode_ == "busy" then |
121 | -- busy wait mode in pure Lua code | 121 | -- busy wait mode in pure Lua code |
122 | io.stdout:write( " lane busy waiting ... ") | 122 | io.stdout:write(" lane busy waiting ... ") |
123 | local _, a = linda:get( "val") | 123 | local _, a = linda:get("val") |
124 | for i = 1, payload_ do | 124 | for i = 1, payload_ do |
125 | a = a * 2 | 125 | a = a * 2 |
126 | a = math.sin( a) * math.sin( a) + math.cos( a) * math.cos( a) -- aka 1 | 126 | a = math.sin(a) * math.sin(a) + math.cos(a) * math.cos(a) -- aka 1 |
127 | end | 127 | end |
128 | print( "again?") | 128 | print("again?") |
129 | else | 129 | else |
130 | error "no mode: raise an error" | 130 | error "no mode: raise an error" |
131 | end | 131 | end |
@@ -133,23 +133,23 @@ local laneBody = function( mode_, payload_) | |||
133 | print " lane shutting down after breaking out of loop" | 133 | print " lane shutting down after breaking out of loop" |
134 | end | 134 | end |
135 | 135 | ||
136 | local protectedBody = function( ...) | 136 | local protectedBody = function(...) |
137 | local ce = lanes.cancel_error | 137 | local ce = lanes.cancel_error |
138 | local errorHandler = function( _msg) | 138 | local errorHandler = function(_msg) |
139 | -- forward the message to the main thread that will display it with a popup | 139 | -- forward the message to the main thread that will display it with a popup |
140 | print( " error handler got ", ce == _msg and "cancel_error"or tostring( _msg)) | 140 | print(" error handler got ", ce == _msg and "cancel_error" or tostring(_msg)) |
141 | return _msg | 141 | return _msg |
142 | end | 142 | end |
143 | -- Lua 5.1 doesn't pass additional xpcall arguments to the called function | 143 | -- Lua 5.1 doesn't pass additional xpcall arguments to the called function |
144 | -- therefore we need to create a closure that has no arguments but pulls everything from its upvalue | 144 | -- therefore we need to create a closure that has no arguments but pulls everything from its upvalue |
145 | local params = {...} | 145 | local params = {...} |
146 | local unpack = table.unpack or unpack -- unpack for 5.1, table.unpack for 5.2+ | 146 | local unpack = table.unpack or unpack -- unpack for 5.1, table.unpack for 5.2+ |
147 | local paramLessClosure = function() laneBody(unpack( params)) end | 147 | local paramLessClosure = function() laneBody(unpack(params)) end |
148 | local status, message = xpcall( paramLessClosure, errorHandler) | 148 | local status, message = xpcall(paramLessClosure, errorHandler) |
149 | if status == false then | 149 | if status == false then |
150 | print( " error handler rethrowing '" .. (ce == message and "cancel_error"or tostring( message)) .. "'") | 150 | print(" error handler rethrowing '" .. (ce == message and "cancel_error"or tostring(message)) .. "'") |
151 | -- if the error isn't rethrown, the lane's finalizer won't get it | 151 | -- if the error isn't rethrown, the lane's finalizer won't get it |
152 | error( message) | 152 | error(message) |
153 | end | 153 | end |
154 | end | 154 | end |
155 | 155 | ||
@@ -159,20 +159,20 @@ end | |||
159 | if not next(which_tests) or which_tests.linda then | 159 | if not next(which_tests) or which_tests.linda then |
160 | remaining_tests.linda = nil | 160 | remaining_tests.linda = nil |
161 | print "\n\n####################################################################\nbegin linda cancel test\n" | 161 | print "\n\n####################################################################\nbegin linda cancel test\n" |
162 | h = generator( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda | 162 | h = generator("*", laneBody)("receive", nil) -- start an infinite wait on the linda |
163 | 163 | ||
164 | print "wait 1s" | 164 | print "wait 1s" |
165 | SLEEP(1) | 165 | SLEEP(1) |
166 | 166 | ||
167 | -- linda cancel: linda:receive() returns nil,cancel_error immediately | 167 | -- linda cancel: linda:receive() returns nil,cancel_error immediately |
168 | print "cancelling" | 168 | print "cancelling" |
169 | linda:cancel( "both") | 169 | linda:cancel("both") |
170 | 170 | ||
171 | -- wait until cancellation is effective. | 171 | -- wait until cancellation is effective. |
172 | waitCancellation( h, "done") | 172 | waitCancellation(h, "done") |
173 | 173 | ||
174 | -- reset the linda so that the other tests work | 174 | -- reset the linda so that the other tests work |
175 | linda:cancel( "none") | 175 | linda:cancel("none") |
176 | end | 176 | end |
177 | 177 | ||
178 | -- ################################################################################################## | 178 | -- ################################################################################################## |
@@ -180,23 +180,23 @@ end | |||
180 | if not next(which_tests) or which_tests.soft then | 180 | if not next(which_tests) or which_tests.soft then |
181 | remaining_tests.soft = nil | 181 | remaining_tests.soft = nil |
182 | print "\n\n####################################################################\nbegin soft cancel test\n" | 182 | print "\n\n####################################################################\nbegin soft cancel test\n" |
183 | h = generator( "*", protectedBody)( "receive") -- start an infinite wait on the linda | 183 | h = generator("*", protectedBody)("receive") -- start an infinite wait on the linda |
184 | 184 | ||
185 | print "wait 1s" | 185 | print "wait 1s" |
186 | SLEEP(1) | 186 | SLEEP(1) |
187 | 187 | ||
188 | -- soft cancel, no awakening of waiting linda operations, should timeout | 188 | -- soft cancel, no awakening of waiting linda operations, should timeout |
189 | local a, b = h:cancel( "soft", 1, false) | 189 | local a, b = h:cancel("soft", 1, false) |
190 | -- cancellation should fail as the lane is still waiting on its linda | 190 | -- cancellation should fail as the lane is still waiting on its linda |
191 | assert( a == false and b == "timeout") | 191 | assert(a == false and b == "timeout") |
192 | waitCancellation( h, "waiting") | 192 | waitCancellation(h, "waiting") |
193 | 193 | ||
194 | -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. | 194 | -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. |
195 | print "cancelling" | 195 | print "cancelling" |
196 | h:cancel( "soft", true) | 196 | h:cancel("soft", true) |
197 | 197 | ||
198 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message | 198 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message |
199 | waitCancellation( h, "done") | 199 | waitCancellation(h, "done") |
200 | end | 200 | end |
201 | 201 | ||
202 | -- ################################################################################################## | 202 | -- ################################################################################################## |
@@ -204,16 +204,16 @@ end | |||
204 | if not next(which_tests) or which_tests.hook then | 204 | if not next(which_tests) or which_tests.hook then |
205 | remaining_tests.hook = nil | 205 | remaining_tests.hook = nil |
206 | print "\n\n####################################################################\nbegin hook cancel test\n" | 206 | print "\n\n####################################################################\nbegin hook cancel test\n" |
207 | h = generator( "*", protectedBody)( "get", 300000) | 207 | h = generator("*", protectedBody)("get", 300000) |
208 | print "wait 2s" | 208 | print "wait 2s" |
209 | SLEEP(2) | 209 | SLEEP(2) |
210 | 210 | ||
211 | -- count hook cancel after some instruction instructions | 211 | -- count hook cancel after some instruction instructions |
212 | print "cancelling" | 212 | print "cancelling" |
213 | h:cancel( "line", 300, 5.0) | 213 | h:cancel("line", 300, 5.0) |
214 | 214 | ||
215 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message | 215 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message |
216 | waitCancellation( h, "cancelled") | 216 | waitCancellation(h, "cancelled") |
217 | end | 217 | end |
218 | 218 | ||
219 | -- ################################################################################################## | 219 | -- ################################################################################################## |
@@ -221,7 +221,7 @@ end | |||
221 | if not next(which_tests) or which_tests.hard then | 221 | if not next(which_tests) or which_tests.hard then |
222 | remaining_tests.hard = nil | 222 | remaining_tests.hard = nil |
223 | print "\n\n####################################################################\nbegin hard cancel test\n" | 223 | print "\n\n####################################################################\nbegin hard cancel test\n" |
224 | h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout | 224 | h = lanes.gen("*", protectedBody)("receive", nil) -- infinite timeout |
225 | 225 | ||
226 | -- wait 2s before cancelling the lane | 226 | -- wait 2s before cancelling the lane |
227 | print "wait 2s" | 227 | print "wait 2s" |
@@ -232,7 +232,7 @@ if not next(which_tests) or which_tests.hard then | |||
232 | h:cancel() | 232 | h:cancel() |
233 | 233 | ||
234 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | 234 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error |
235 | waitCancellation( h, "cancelled") | 235 | waitCancellation(h, "cancelled") |
236 | end | 236 | end |
237 | 237 | ||
238 | -- ################################################################################################## | 238 | -- ################################################################################################## |
@@ -240,7 +240,7 @@ end | |||
240 | if not next(which_tests) or which_tests.hard_unprotected then | 240 | if not next(which_tests) or which_tests.hard_unprotected then |
241 | remaining_tests.hard_unprotected = nil | 241 | remaining_tests.hard_unprotected = nil |
242 | print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" | 242 | print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" |
243 | h = generator( "*", laneBody)( "receive", nil) | 243 | h = generator("*", laneBody)("receive", nil) |
244 | 244 | ||
245 | -- wait 2s before cancelling the lane | 245 | -- wait 2s before cancelling the lane |
246 | print "wait 2s" | 246 | print "wait 2s" |
@@ -251,7 +251,7 @@ if not next(which_tests) or which_tests.hard_unprotected then | |||
251 | h:cancel() | 251 | h:cancel() |
252 | 252 | ||
253 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | 253 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error |
254 | waitCancellation( h, "cancelled") | 254 | waitCancellation(h, "cancelled") |
255 | end | 255 | end |
256 | 256 | ||
257 | -- ################################################################################################## | 257 | -- ################################################################################################## |