lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Am 03.07.2020 um 18:49 schrieb Francisco Olarte:
> Although you maay be able to yield from the main thread I do not think
> this is totally supported given:
> 
> "coroutine.isyieldable ()
> Returns true when the running coroutine can yield.
> A running coroutine is yieldable if ***it is not the main thread****
> and it is not inside a non-yieldable C function. "

Hmm.. this doesn't seem to be correct. Here is a test program[1] that
loads und runs the following buffer in the main thread:

print(coroutine.isyieldable(),coroutine.isyieldable(coroutine.running()))

With Lua 5.3.5:
lua_call   --> false false
lua_callk  --> false false
lua_pcall  --> false false
lua_pcallk --> false false
lua_resume --> true true

With Lua 5.4.0:
lua_call   --> false false
lua_callk  --> true true
lua_pcall  --> false false
lua_pcallk --> true true
lua_resume --> true true

The same program, with another script:

if coroutine.isyieldable() then coroutine.yield('hi') end

With Lua 5.3.5:
lua_call   --> (nothing)
lua_callk  --> (nothing)
lua_pcall  --> LUA_OK
lua_pcallk --> LUA_OK
lua_resume --> LUA_YIELD

With Lua 5.4.0:
lua_call   --> (nothing)
lua_callk  --> PANIC: unprotected error in call to Lua API (hi)
lua_pcall  --> LUA_OK
lua_pcallk --> PANIC: unprotected error in call to Lua API (hi)
lua_resume --> LUA_YIELD

Just yielding:

coroutine.yield('hi')

With Lua 5.3.5:
lua_call   --> PANIC: unprotected error in call to Lua API (attempt to
yield from outside a coroutine)
lua_callk  --> PANIC: unprotected error in call to Lua API (attempt to
yield from outside a coroutine)
lua_pcall  --> Error: attempt to yield from outside a coroutine
lua_pcallk --> Error: attempt to yield from outside a coroutine
lua_resume --> LUA_YIELD

With Lua 5.4.0:
lua_call   --> PANIC: unprotected error in call to Lua API (attempt to
yield from outside a coroutine)
lua_callk  --> PANIC: unprotected error in call to Lua API (hi)
lua_pcall  --> Error: attempt to yield from outside a coroutine
lua_pcallk --> PANIC: unprotected error in call to Lua API (hi)
lua_resume --> LUA_YIELD


What is going on?!


[1] Test program, comments toggled

gcc (Debian 9.3.0-14) 9.3.0

gcc -Wall -Wextra -Wno-unused -Ilua/lua-5.4.0/src main2.c
lua/lua-5.4.0/src/liblua.a -ldl -lm && ./a.out

gcc -Wall -Wextra -Wno-unused -Ilua/lua-5.3.5/src main2.c
lua/lua-5.3.5/src/liblua.a -ldl -lm && ./a.out

#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

static int k(lua_State *L, int status, lua_KContext ctx) { (void)L;
(void)status; (void)ctx; return 0; }

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    const char script[] = "coroutine.yield('hi')";
    if (luaL_loadbufferx(L, script, sizeof script - 1, "script", "t") !=
LUA_OK) {
        printf("Error: %s\n", lua_tostring(L, -1));
        return 2;
    }
    int nres;
    lua_call(L, 0, 0);
    // lua_callk(L, 0, 0, (lua_KContext)0, k);
    // switch (lua_pcall(L, 0, 0, 0))
    // switch (lua_pcallk(L, 0, 0, 0, (lua_KContext)0, k))
    // switch (lua_resume(L, NULL, 0, &nres)) /* Lua 5.4.0 */
    // switch (lua_resume(L, NULL, 0))  /* Lua 5.3.5 */
    // {
        // case LUA_OK:
            // printf("LUA_OK\n");
            // return 0;
        // case LUA_YIELD:
            // printf("LUA_YIELD\n");
            // return 1;
        // default: {
            // printf("Error: %s\n", lua_tostring(L, -1));
            // return 2;
        // }
    // }
}