lua-users home
lua-l archive

Is it possible to yield/resume the main thread?

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


Hello,
is it possible to yield and resume the main thread, even if the
yielding function runs in another coroutine?
(related: http://lua-users.org/lists/lua-l/2019-05/msg00081.html )
My Lua script runs in an event-driven environment and I need to
halt it to until an external resource is ready. This works really
nice as long as the state is started with lua_resume and the
C callbacks yield back to the "ground" layer of C.
But when the script calls these functions in a coroutine, they just
yield the script's coroutine and don't stop the execution of Lua.
I tried to yield the main thread directly, but resuming it continues
execution at the wrong point:
print 'A'
cb() --> lua_yield(main thread) / Should pause the script
print 'B'
coroutine.resume(coroutine.create(function()
 print ' X'
 cb() --> lua_yield(main thread) / Should pause the script
 print ' Y'
end))
print 'C'
Prints (Y is missing):
[Resume state]
A
[Yielded]
[Resume state]
B
 X
[Yielded]
[Resume state]
C
[Finished]
Now my questions are:
A) Can a CFunction call lua_yield with anything other than the
 lua_State passed as argument?
B) If not, can the entire script be yielded/resumed directly in
 standard Lua?
I'm sorry for the naive questions, but I couldn't find a direct
statement in the manual.
Here is the C test program:
// gcc -Wall -Ilua-5.4.0/src main.c lua-5.4.0/src/liblua.a -ldl -lm
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
lua_State* L;
int luacb(lua_State* T)
{
 return lua_yield(L, 0);
}
int main()
{
 L = luaL_newstate();
 luaL_openlibs(L);
 lua_register(L, "cb", luacb);
 const char script[] =
 "print 'A'\n"
 "cb()\n"
 "print 'B'\n"
 "coroutine.resume(coroutine.create(function()\n"
 " print ' X'\n"
 " cb()\n"
 " print ' Y'\n"
 "end))\n"
 "print 'C'\n";
 if (luaL_loadbufferx (L, script, sizeof script - 1, "script", "t")
!= LUA_OK) {
 printf("[Error] %s\n", lua_tostring(L, -1));
 goto close_state;
 }
 for (;;) {
 printf("[Resume state]\n");
 int nresults = 0;
 int lr = lua_resume(L, NULL, 0, &nresults);
 switch (lr) {
 case LUA_OK:
 lua_pop(L, nresults);
 printf("[Finished]\n");
 goto close_state;
 case LUA_YIELD:
 lua_pop(L, nresults);
 printf("[Yielded]\n");
 continue;
 default: {
 printf("[Error] %s\n", lua_tostring(L, -1));
 goto close_state;
 }
 }
 }
close_state:
 lua_close(L);
}

AltStyle によって変換されたページ (->オリジナル) /