Refactor code to make it easier to do 'nopredict' inside of any function without having a dependency on world model.

This commit is contained in:
2023-03-01 16:07:13 -05:00
parent aa77480fb5
commit 9ce34d950b
15 changed files with 86 additions and 49 deletions

View File

@@ -29,12 +29,12 @@ World *World::fetch_global_pointer(lua_State *L) {
World::~World() {
}
World::World(util::WorldType wt) {
World::World(WorldType wt) {
// Master world model by default.
world_type_ = wt;
// Initialize the ID allocator in master mode.
if (wt == util::WORLD_TYPE_MASTER || wt == util::WORLD_TYPE_STANDALONE) {
if (is_authoritative()) {
id_global_pool_.init_master();
} else {
id_global_pool_.init_synch();
@@ -63,11 +63,12 @@ World::World(util::WorldType wt) {
// Create the tangibles table in the registry.
LS.rawset(LuaRegistry, "tangibles", LuaNewTable);
// Store the world type in the registry.
LS.rawset(LuaRegistry, "worldtype", wt);
// Create the globaldb and oncedb in the registry.
if ((wt == util::WORLD_TYPE_MASTER) || (wt == util::WORLD_TYPE_STANDALONE)) {
LS.rawset(LuaRegistry, "globaldb", LuaNewTable);
LS.rawset(LuaRegistry, "oncedb", LuaNewTable);
}
LS.rawset(LuaRegistry, "globaldb", LuaNewTable);
LS.rawset(LuaRegistry, "oncedb", LuaNewTable);
// Initialize the SourceDB. At this stage, the sourcedb is
// empty, so it's just populating the lua builtins.
@@ -788,12 +789,12 @@ void World::invoke_lua_source(int64_t actor_id, int64_t place_id, const eng::str
void World::guard_blockable(lua_State *L, const char *fn) {
if (lthread_thread_id_ == 0) {
// in a probe, http.get throws an error.
// in a probe, blocking functions like http.get throw an error.
luaL_error(L, "cannot %s in a probe", fn);
assert(false);
}
if (!is_authoritative()) {
// in a nonauth model, http.get is converted to nopredict.
// in a nonauth model, blocking functions like http.get are converted to nopredict.
lua_yield(L, 0);
luaL_error(L, "unexplained nopredict failure in %s", fn);
assert(false);
@@ -801,6 +802,8 @@ void World::guard_blockable(lua_State *L, const char *fn) {
}
void World::guard_nopredict(lua_State *L, const char *fn) {
// Caution: this code must be equivalent to the
// code in LuaStack::guard_nopredict.
if (lthread_thread_id_ == 0) {
return;
}
@@ -883,7 +886,10 @@ void World::run_scheduled_threads() {
LS.rawset(thinfo, "isnew", false);
LS.rawset(thinfo, "useppool", false);
} else {
// In a nonauth model, a yield is converted to a 'nopredict'.
// When a nonauthoritative model yields, for any reason,
// the thread is discarded. This is also used as a way to implement
// nopredict: the thread that wants to 'nopredict' just yields,
// knowing that this will cause it to be killed.
LS.rawset(threads, sched.thread_id(), LuaNil);
}
} else {