coroutineInherited from Lua 5.1's standard library.
LuaAdded by Luau: coroutine.close, coroutine.isyieldable
Luau
coroutine.close, coroutine.isyieldableA thread is a coroutine, not an operating system thread
Coroutines are interleaving (async) primitives and aren't for true parallelism (os multithreading). Coroutines can't use more than one CPU core.
Hosts that want real OS multithreading should expose an API that runs separate Luwu VMs per OS thread and facilitate communication via shared memory or message passing.
The coroutine library creates coroutines, resumes and yields them, and checks their state.
A coroutine is a function that can pause itself. It runs until it calls coroutine.yield and hands values back to the code that resumed it. The next coroutine.resume continues from the same point with every local variable intact. Each coroutine has a separate stack (it's a thread value) and only one coroutine runs at a time.
Coroutines turn a loop into a generator that produces one value per call. Hosts use them to run scripts that wait: a task scheduler resumes a coroutine once the thing it waited for is ready.
Summary
Creating and closing
function coroutine.create<A..., R...>(f: (A...) -> R...): threadcoroutine.createInherited from Lua 5.1's standard library.
Lua- Creates a coroutine that runs a function
function coroutine.wrap<A..., R...>(f: (A...) -> R...): (A...) -> R...coroutine.wrapInherited from Lua 5.1's standard library.
Lua- Creates a coroutine and returns a function that resumes it
function coroutine.close(co: thread): (boolean, unknown?)coroutine.closeBackported from Lua 5.4 by Luau 0.505.
Luau- Closes a suspended or dead coroutine
Resuming and yielding
function coroutine.resume<A..., R...>(co: thread, ...: A...): (boolean, R...)coroutine.resumeInherited from Lua 5.1's standard library.
Lua- Starts or continues a coroutine
function coroutine.yield<A..., R...>(...: A...): R...coroutine.yieldInherited from Lua 5.1's standard library.
Lua- Pauses the running coroutine and hands values to its resumer
Checking state
function coroutine.running(): thread?coroutine.runningInherited from Lua 5.1's standard library.
Lua- Returns the coroutine that's running
function coroutine.status(co: thread): "running" | "suspended" | "normal" | "dead"coroutine.statusInherited from Lua 5.1's standard library.
Lua- Returns the status of a coroutine
function coroutine.isyieldable(): booleancoroutine.isyieldableBackported from Lua 5.3 by Luau 0.501 or earlier.
Luau- Checks whether the running code can yield
Creating and closing
coroutine.createInherited from Lua 5.1's standard library.
Lua
function coroutine.create<A..., R...>(f: (A...) -> R...): threadReturns a new coroutine that runs f when it's first resumed. The coroutine starts out "suspended" and the arguments of the first coroutine.resume become the arguments of f.
coroutine.wrapInherited from Lua 5.1's standard library.
Lua
function coroutine.wrap<A..., R...>(f: (A...) -> R...): (A...) -> R...Creates a coroutine and returns a function that resumes it. Calling the function passes its arguments to the coroutine and returns what the coroutine yields or returns. Unlike coroutine.resume, there's no status boolean. The call raises any error from inside the coroutine again and puts the location of the call in front of a string message.
const next_id = coroutine.wrap(function()
local id = 0
while true do
id += 1
coroutine.yield(id)
end
end)
print(next_id())
print(next_id())
print(next_id())1 2 3
coroutine.closeBackported from Lua 5.4 by Luau 0.505.
Luau
function coroutine.close(co: thread): (boolean, unknown?)Closes co and empties its stack. The coroutine becomes "dead" and can't be resumed. Only a suspended or dead coroutine can be closed: closing a running or normal one raises an error. close returns true, or false and the error object when the coroutine had died from an error.
Luau's coroutine.finally isn't part of Luwu's coroutine library.
Resuming and yielding
coroutine.resumeInherited from Lua 5.1's standard library.
Lua
function coroutine.resume<A..., R...>(co: thread, ...: A...): (boolean, R...)Starts or continues co and passes the remaining arguments to it. They become the arguments of the coroutine's function on the first resume and the results of coroutine.yield after that. When the coroutine yields or returns, resume returns true followed by those values. When it raises an error, resume returns false and the error object like pcall does. Resuming a coroutine that isn't suspended returns false and a message such as "cannot resume dead coroutine".
const doubler = coroutine.create(function(first: number)
local value = first
while true do
value = coroutine.yield(value * 2)
end
end)
const _, a = coroutine.resume(doubler, 5)
const _, b = coroutine.resume(doubler, 21)
print(`{a} {b}`)
print(coroutine.status(doubler))10 42 suspended
coroutine.yieldInherited from Lua 5.1's standard library.
Lua
function coroutine.yield<A..., R...>(...: A...): R...Pauses the running coroutine and passes its arguments to the code that resumed it. The coroutine becomes "suspended". When it's resumed again, yield returns the arguments passed to that resume.
Checking state
coroutine.runningInherited from Lua 5.1's standard library.
Lua
function coroutine.running(): thread?Returns the coroutine that's running or nil when the main thread is running. Some hosts run every script inside a coroutine and never use the main thread for script code. Luwu's type definitions declare the result as thread without the nil.
coroutine.statusInherited from Lua 5.1's standard library.
Lua
function coroutine.status(co: thread): "running" | "suspended" | "normal" | "dead""running":cois the coroutine callingstatus."suspended":cohasn't started yet or is paused incoroutine.yield. It can be resumed."normal":coresumed another coroutine and is waiting for it to yield or finish."dead":coreturned, raised an error or was closed. A dead coroutine can't be resumed. The garbage collector keeps it while anything refers to it.
coroutine.isyieldableBackported from Lua 5.3 by Luau 0.501 or earlier.
Luau
function coroutine.isyieldable(): booleanReturns whether the running code can call coroutine.yield. The main thread can't yield. Inside a coroutine, yielding also fails from a metamethod like __index and from a callback that a C function calls, like table.sort's comparison function. pcall and xpcall are the exception: code inside them can yield.