aboutsummaryrefslogtreecommitdiff
path: root/testes/coroutine.lua
diff options
context:
space:
mode:
Diffstat (limited to 'testes/coroutine.lua')
-rw-r--r--testes/coroutine.lua65
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
289end 288end
290 289
291 290
291do 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
338end
339
340
292-- yielding across C boundaries 341-- yielding across C boundaries
293 342
294local co = coroutine.wrap(function() 343local co = coroutine.wrap(function()