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