Overhaul of thread handling to support blocking functions other than wait

This commit is contained in:
2022-04-25 17:17:41 -04:00
parent bd389c7815
commit 9aec7c5299
15 changed files with 144 additions and 88 deletions

View File

@@ -294,23 +294,40 @@ LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere",
LuaDefine(wait, "nticks",
"|Wait the specified number of ticks.") {
if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) {
luaL_error(L, "Argument to wait must be a number.");
World *w = World::fetch_global_pointer(L);
LuaArg seconds;
LuaStack LS(L, seconds);
int64_t n = LS.ckinteger(seconds);
if ((n < 0) || (n > 1000000)) {
luaL_error(L, "Argument to wait must be between 0 and 1000000");
return LS.result();
}
if (!lua_isyieldable(L)) {
// in a probe, wait throws an error.
luaL_error(L, "cannot wait in a probe.");
return LS.result();
} else if (!w->is_authoritative()) {
// in a nonauth model, yield is converted to nopredict.
lua_yield(L, 0);
return LS.result();
} else {
// in an authoritative model, wait schedules a continuation.
w->thread_sched_.add(w->clock_ + n, w->lthread_thread_id_, w->lthread_place_id_);
lua_yield(L, 0);
return LS.result();
}
return lua_yield(L, 1);
}
LuaDefine(tangible_nopredict, "",
LuaDefine(nopredict, "",
"|Stop predictive execution of this thread.") {
if (lua_gettop(L) != 0) {
luaL_error(L, "tangible.nopredict takes no arguments");
}
World *w = World::fetch_global_pointer(L);
if (util::world_type_authoritative(w->world_type_)) {
return 0;
} else {
if (lua_isyieldable(L) && !w->is_authoritative()) {
return lua_yield(L, 0);
}
return 0;
}
LuaDefine(math_random, "(args...)",