summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-03-27 15:53:48 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-03-27 15:53:48 -0400
commitc618758c7c91917905b1075e29944ef70e7e9b33 (patch)
tree18336f315261801787643a53c7cea3b699d12c23 /indra
parent5b04ae7812e6cb0d0c9895aec6db6a206d4e09e8 (diff)
Run loaded `require()` module on Lua's main thread.
The problem with running a `require()` module on a Lua coroutine is that it prohibits calling `leap.request()` at module load time. When a coroutine calls `leap.request()`, it must yield back to Lua's main thread -- but a `require()` module is forbidden from yielding. Running on Lua's main thread means that (after potentially giving time slices to other ready coroutines) `fiber.lua` will request the response event from the viewer, and continue processing the loaded module without having to yield.
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llluamanager.cpp19
1 files changed, 13 insertions, 6 deletions
diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp
index c65f062fd7..aed6aee239 100644
--- a/indra/newview/llluamanager.cpp
+++ b/indra/newview/llluamanager.cpp
@@ -508,12 +508,14 @@ void LLRequireResolver::runModule(const std::string& desc, const std::string& co
// Module needs to run in a new thread, isolated from the rest.
// Note: we create ML on main thread so that it doesn't inherit environment of L.
lua_State *GL = lua_mainthread(L);
- lua_State *ML = lua_newthread(GL);
+// lua_State *ML = lua_newthread(GL);
+ // Try loading modules on Lua's main thread instead.
+ lua_State *ML = GL;
// lua_newthread() pushed the new thread object on GL's stack. Move to L's.
- lua_xmove(GL, L, 1);
+// lua_xmove(GL, L, 1);
// new thread needs to have the globals sandboxed
- luaL_sandboxthread(ML);
+// luaL_sandboxthread(ML);
{
// If loadstring() returns (! LUA_OK) then there's an error message on
@@ -523,7 +525,9 @@ void LLRequireResolver::runModule(const std::string& desc, const std::string& co
{
// luau uses Lua 5.3's version of lua_resume():
// run the coroutine on ML, "from" L, passing no arguments.
- int status = lua_resume(ML, L, 0);
+// int status = lua_resume(ML, L, 0);
+ // we expect one return value
+ int status = lua_pcall(ML, 0, 1, 0);
if (status == LUA_OK)
{
@@ -545,9 +549,12 @@ void LLRequireResolver::runModule(const std::string& desc, const std::string& co
}
// There's now a return value (string error message or module) on top of ML.
// Move return value to L's stack.
- lua_xmove(ML, L, 1);
+ if (ML != L)
+ {
+ lua_xmove(ML, L, 1);
+ }
// remove ML from L's stack
- lua_remove(L, -2);
+// lua_remove(L, -2);
// // DON'T call lua_close(ML)! Since ML is only a thread of L, corrupts L too!
// lua_close(ML);
}