From e26727e03bb02d26b3f0d83f748dbd8eb88e4940 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 18 Jun 2024 13:13:39 -0400 Subject: 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. --- indra/llcommon/lua_function.cpp | 52 ----------------------------- indra/newview/scripts/lua/require/fiber.lua | 6 ++++ indra/newview/tests/llluamanager_test.cpp | 6 ++++ 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 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; -- cgit v1.2.3