summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-06-18 13:13:39 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-06-18 13:13:39 -0400
commite26727e03bb02d26b3f0d83f748dbd8eb88e4940 (patch)
tree22f0592fde6ef683f251b50d0e93adf5bef9f204
parent5cc4b42a3001be120e22f745460dbb76d8d8d018 (diff)
Remove special-case ~LuaState() code to call fiber.run().
Instead, make fiber.lua call LL.atexit(fiber.run) to schedule that final run() call at ~LuaState() time using the generic mechanism. Append an explicit fiber.run() call to a specific test in llluamanager_test.cpp because the test code wants to interact with multiple Lua fibers *before* we destroy the LuaState.
-rw-r--r--indra/llcommon/lua_function.cpp52
-rw-r--r--indra/newview/scripts/lua/require/fiber.lua6
-rw-r--r--indra/newview/tests/llluamanager_test.cpp6
3 files changed, 12 insertions, 52 deletions
diff --git a/indra/llcommon/lua_function.cpp b/indra/llcommon/lua_function.cpp
index 7894c7b96a..7c5a939d8a 100644
--- a/indra/llcommon/lua_function.cpp
+++ b/indra/llcommon/lua_function.cpp
@@ -627,58 +627,6 @@ std::pair<int, LLSD> LuaState::expr(const std::string& desc, const std::string&
}
// pop everything
lua_settop(mState, 0);
-
- // If we ran a script that loaded the fiber module, finish up with a call
- // to fiber.run(). That allows a script to kick off some number of fibers,
- // do some work on the main thread and then fall off the end of the script
- // without explicitly appending a call to fiber.run(). run() ensures the
- // rest of the fibers run to completion (or error).
- luaL_checkstack(mState, 4, nullptr);
- // Push _MODULES table on stack
- luaL_findtable(mState, LUA_REGISTRYINDEX, "_MODULES", 1);
- int index = lua_gettop(mState);
- bool found = false;
- // Did this chunk already require('fiber')? To find out, we must search
- // the _MODULES table, because our require() implementation uses the
- // pathname of the module file as the key. Push nil key to start.
- lua_pushnil(mState);
- while (lua_next(mState, index) != 0)
- {
- // key is at index -2, value at index -1
- // "While traversing a table, do not call lua_tolstring directly on a
- // key, unless you know that the key is actually a string. Recall that
- // lua_tolstring changes the value at the given index; this confuses
- // the next call to lua_next."
- // https://www.lua.org/manual/5.1/manual.html#lua_next
- if (lua_type(mState, -2) == LUA_TSTRING &&
- fsyspath(lua_tostdstring(mState, -2)).stem() == "fiber")
- {
- found = true;
- break;
- }
- // pop value so key is at top for lua_next()
- lua_pop(mState, 1);
- }
- if (found)
- {
- // okay, index -1 is a table loaded from a file 'fiber.xxx' --
- // does it have a function named 'run'?
- auto run_type{ lua_getfield(mState, -1, "run") };
- if (run_type == LUA_TFUNCTION)
- {
- // there's a fiber.run() function sitting on the top of the stack
- // -- call it with no arguments, discarding anything it returns
- LL_INFOS("Lua") << desc << " p.s. fiber.run()" << LL_ENDL;
- if (! checkLua(desc, lua_pcall(mState, 0, 0, 0)))
- {
- LL_WARNS("Lua") << desc << " p.s. fiber.run() error: " << mError << LL_ENDL;
- return { -1, mError };
- }
- LL_INFOS("Lua") << desc << " p.s. done." << LL_ENDL;
- }
- }
- // pop everything again
- lua_settop(mState, 0);
return result;
}
diff --git a/indra/newview/scripts/lua/require/fiber.lua b/indra/newview/scripts/lua/require/fiber.lua
index cae27b936b..b3c684dd67 100644
--- a/indra/newview/scripts/lua/require/fiber.lua
+++ b/indra/newview/scripts/lua/require/fiber.lua
@@ -337,4 +337,10 @@ function fiber.run()
return idle_done
end
+-- Make sure we finish up with a call to run(). That allows a consuming script
+-- to kick off some number of fibers, do some work on the main thread and then
+-- fall off the end of the script without explicitly calling fiber.run().
+-- run() ensures the rest of the fibers run to completion (or error).
+LL.atexit(fiber.run)
+
return fiber
diff --git a/indra/newview/tests/llluamanager_test.cpp b/indra/newview/tests/llluamanager_test.cpp
index 2d525f7913..206dbd9e71 100644
--- a/indra/newview/tests/llluamanager_test.cpp
+++ b/indra/newview/tests/llluamanager_test.cpp
@@ -385,6 +385,12 @@ namespace tut
"fiber.launch('catch_special', drain, catch_special)\n"
"fiber.launch('requester(a)', requester, 'a')\n"
"fiber.launch('requester(b)', requester, 'b')\n"
+ // A script can normally count on an implicit fiber.run() call
+ // because fiber.lua calls LL.atexit(fiber.run). But atexit()
+ // functions are called by ~LuaState(), which (in the code below)
+ // won't be called until *after* we expect to interact with the
+ // various fibers. So make an explicit call for test purposes.
+ "fiber.run()\n"
);
LLSD requests;