diff options
Diffstat (limited to 'testes/coroutine.lua')
-rw-r--r-- | testes/coroutine.lua | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 17f6ceba..4881d964 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -156,12 +156,12 @@ do | |||
156 | st, msg = coroutine.close(co) | 156 | st, msg = coroutine.close(co) |
157 | assert(st and msg == nil) | 157 | assert(st and msg == nil) |
158 | 158 | ||
159 | local main = coroutine.running() | ||
159 | 160 | ||
160 | -- cannot close the running coroutine | 161 | -- cannot close 'main' |
161 | local st, msg = pcall(coroutine.close, coroutine.running()) | 162 | local st, msg = pcall(coroutine.close, main); |
162 | assert(not st and string.find(msg, "running")) | 163 | assert(not st and string.find(msg, "main")) |
163 | 164 | ||
164 | local main = coroutine.running() | ||
165 | 165 | ||
166 | -- cannot close a "normal" coroutine | 166 | -- cannot close a "normal" coroutine |
167 | ;(coroutine.wrap(function () | 167 | ;(coroutine.wrap(function () |
@@ -169,20 +169,19 @@ do | |||
169 | assert(not st and string.find(msg, "normal")) | 169 | assert(not st and string.find(msg, "normal")) |
170 | end))() | 170 | end))() |
171 | 171 | ||
172 | -- cannot close a coroutine while closing it | 172 | do -- close a coroutine while closing it |
173 | do | ||
174 | local co | 173 | local co |
175 | co = coroutine.create( | 174 | co = coroutine.create( |
176 | function() | 175 | function() |
177 | local x <close> = func2close(function() | 176 | local x <close> = func2close(function() |
178 | coroutine.close(co) -- try to close it again | 177 | coroutine.close(co) -- close it again |
179 | end) | 178 | end) |
180 | coroutine.yield(20) | 179 | coroutine.yield(20) |
181 | end) | 180 | end) |
182 | local st, msg = coroutine.resume(co) | 181 | local st, msg = coroutine.resume(co) |
183 | assert(st and msg == 20) | 182 | assert(st and msg == 20) |
184 | st, msg = coroutine.close(co) | 183 | st, msg = coroutine.close(co) |
185 | assert(not st and string.find(msg, "running coroutine")) | 184 | assert(st and msg == nil) |
186 | end | 185 | end |
187 | 186 | ||
188 | -- to-be-closed variables in coroutines | 187 | -- to-be-closed variables in coroutines |
@@ -289,6 +288,56 @@ do | |||
289 | end | 288 | end |
290 | 289 | ||
291 | 290 | ||
291 | do print("coroutines closing itself") | ||
292 | global <const> coroutine, string, os | ||
293 | global <const> assert, error, pcall | ||
294 | |||
295 | local X = nil | ||
296 | |||
297 | local function new () | ||
298 | return coroutine.create(function (what) | ||
299 | |||
300 | local <close>var = func2close(function (t, err) | ||
301 | if what == "yield" then | ||
302 | coroutine.yield() | ||
303 | elseif what == "error" then | ||
304 | error(200) | ||
305 | else | ||
306 | X = "Ok" | ||
307 | return X | ||
308 | end | ||
309 | end) | ||
310 | |||
311 | -- do an unprotected call so that coroutine becomes non-yieldable | ||
312 | string.gsub("a", "a", function () | ||
313 | assert(not coroutine.isyieldable()) | ||
314 | -- do protected calls while non-yieldable, to add recovery | ||
315 | -- entries (setjmp) to the stack | ||
316 | assert(pcall(pcall, function () | ||
317 | -- 'close' works even while non-yieldable | ||
318 | coroutine.close() -- close itself | ||
319 | os.exit(false) -- not reacheable | ||
320 | end)) | ||
321 | end) | ||
322 | end) | ||
323 | end | ||
324 | |||
325 | local co = new() | ||
326 | local st, msg = coroutine.resume(co, "ret") | ||
327 | assert(st and msg == nil) | ||
328 | assert(X == "Ok") | ||
329 | |||
330 | local co = new() | ||
331 | local st, msg = coroutine.resume(co, "error") | ||
332 | assert(not st and msg == 200) | ||
333 | |||
334 | local co = new() | ||
335 | local st, msg = coroutine.resume(co, "yield") | ||
336 | assert(not st and string.find(msg, "attempt to yield")) | ||
337 | |||
338 | end | ||
339 | |||
340 | |||
292 | -- yielding across C boundaries | 341 | -- yielding across C boundaries |
293 | 342 | ||
294 | local co = coroutine.wrap(function() | 343 | local co = coroutine.wrap(function() |