From a29b16db27c0cd3c6cf1d1a4d8551174282bd296 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 1 Jul 2024 09:31:48 +0200 Subject: lanes.finally() handler decides whether to thow or freeze --- src/universe.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/universe.cpp b/src/universe.cpp index 5fda29a..04db10f 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -427,22 +427,24 @@ LUAG_FUNC(universe_gc) kFinalizerRegKey.pushValue(L_); // L_: U finalizer|nil if (!lua_isnil(L_, -1)) { lua_pushboolean(L_, _allLanesTerminated); // L_: U finalizer bool - lua_pcall(L_, 1, 0, 0); // L_: U - // discard any error that might have occured - lua_settop(L_, 1); - } else { - lua_pop(L_, 1); // L_: U + // no protection. Lua rules for errors in finalizers apply normally + lua_call(L_, 1, 1); // L_: U ret|error } - // in case of error, the message is pushed on the stack - STACK_CHECK(L_, 1); + STACK_CHECK(L_, 2); + + // if some lanes are still running here, we have no other choice than crashing or freezing and let the client figure out what's wrong + bool const _throw{ luaG_tostring(L_, -1) == "throw" }; + lua_pop(L_, 1); // L_: U - // if some lanes are still running here, we have no other choice than crashing and let the client figure out what's wrong while (_U->selfdestructFirst != SELFDESTRUCT_END) { - throw std::logic_error{ "Some lanes are still running at shutdown" }; - //std::this_thread::yield(); + if (_throw) { + throw std::logic_error{ "Some lanes are still running at shutdown" }; + } else { + std::this_thread::yield(); + } } - // no need to mutex-protect this as all threads in the universe are gone at that point + // no need to mutex-protect this as all lanes in the universe are gone at that point if (_U->timerLinda != nullptr) { // test in case some early internal error prevented Lanes from creating the deep timer [[maybe_unused]] int const _prev_ref_count{ _U->timerLinda->refcount.fetch_sub(1, std::memory_order_relaxed) }; LUA_ASSERT(L_, _prev_ref_count == 1); // this should be the last reference -- cgit v1.2.3-55-g6feb