Lua

Coco changes the semantics of several standard API functions and provides a few API extensions for Lua.

By default all your coroutines get an associated C stack. If you want to be more selective, see below.

Lua API extensions

All coroutine.* functions should be fully upwards compatible.

coroutine.coco

This field is true when Coco is present (nil otherwise).

coro = coroutine.create(f [, cstacksize])
func = coroutine.wrap(f [, cstacksize])

The optional argument cstacksize specifies the size of the C stack to allocate for the coroutine:

Important notice for LuaJIT: JIT compiled functions cannot yield if a coroutine does not have a dedicated C stack.

olddefault = coroutine.cstacksize([newdefault])

Returns the current default C stack size (may be 0 if the underlying context switch method has its own default). Sets a new default C stack size if newdefault is present. Use 0 to reset it to the default C stack size. Any other value is rounded up to the minimum size.

C API extensions

All C API functions are either unchanged or upwards compatible.

int lua_yield(lua_State *L, int nresults)

The semantics for lua_yield() have changed slightly. Existing programs should work fine as long as they follow the usage conventions from the Lua manual:

return lua_yield(L, nresults);

Previously lua_yield() returned a 'magic' value (-1) that indicated a yield. Your C function had to pass this value on to the Lua core and was not called again.

Now, if the current coroutine has an associated C stack, lua_yield() returns the number of arguments passed back from the resume. This just happens to be the right convention for returning them as a result from a C function. I.e. if you used the above convention, you'll never notice the change.

But the results are on the Lua stack when lua_yield() returns. So the C function can just continue and process them or retry an I/O operation etc. And your whole C stack frame (local variables etc.) is still there, too. You can yield from anywhere in your C program, even several call levels deeper.

Of course all of this only works with Lua+Coco and not with standard Lua.

lua_State *lua_newcthread(lua_State *L, int cstacksize)

This is an (optional) new function that allows you to create a coroutine with an associated C stack directly from the C API. Other than that it works the same as lua_newthread(L).

You have to declare this function as extern yourself, since it's not part of the official Lua API. This means that a C module that uses this call cannot be loaded with standard Lua. This may be intentional.

If you want your C module to work with both standard Lua and Lua+Coco you can check whether Coco is available with:

  lua_getfield(L, LUA_GLOBALSINDEX, "coroutine");
  lua_getfield(L, -1, "coco");
  coco_available = lua_toboolean(L, -1);
  lua_pop(L, 2);

You can create coroutines with a C stack by calling the Lua function coroutine.create() from C, too.