aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/universe.cpp33
1 files changed, 18 insertions, 15 deletions
diff --git a/src/universe.cpp b/src/universe.cpp
index 06f7f21..3255c7f 100644
--- a/src/universe.cpp
+++ b/src/universe.cpp
@@ -227,9 +227,9 @@ static int luaG_provide_protected_allocator(lua_State* const L_)
227 227
228// ################################################################################################# 228// #################################################################################################
229 229
230// already called under protection of selfdestructMutex
230void Universe::flagDanglingLanes() const 231void Universe::flagDanglingLanes() const
231{ 232{
232 std::lock_guard<std::mutex> _guard{ selfdestructMutex };
233 Lane* _lane{ selfdestructFirst }; 233 Lane* _lane{ selfdestructFirst };
234 while (_lane != SELFDESTRUCT_END) { 234 while (_lane != SELFDESTRUCT_END) {
235 _lane->flaggedAfterUniverseGC.store(true, std::memory_order_relaxed); 235 _lane->flaggedAfterUniverseGC.store(true, std::memory_order_relaxed);
@@ -460,22 +460,25 @@ int Universe::UniverseGC(lua_State* const L_)
460 } 460 }
461 STACK_CHECK(L_, 2); 461 STACK_CHECK(L_, 2);
462 462
463 // now, all remaining lanes are flagged. if they crash because we remove keepers and the Universe from under them, it is their fault 463 {
464 bool const _detectedUncooperativeLanes{ _U->selfdestructFirst != SELFDESTRUCT_END }; 464 std::lock_guard<std::mutex> _guard{ _U->selfdestructMutex };
465 if (_detectedUncooperativeLanes) { 465 // now, all remaining lanes are flagged. if they crash because we remove keepers and the Universe from under them, it is their fault
466 _U->flagDanglingLanes(); 466 bool const _detectedUncooperativeLanes{ _U->selfdestructFirst != SELFDESTRUCT_END };
467 if (luaG_tostring(L_, kIdxTop) == "freeze") { 467 if (_detectedUncooperativeLanes) {
468 std::this_thread::sleep_until(std::chrono::time_point<std::chrono::steady_clock>::max()); 468 _U->flagDanglingLanes();
469 if (luaG_tostring(L_, kIdxTop) == "freeze") {
470 std::this_thread::sleep_until(std::chrono::time_point<std::chrono::steady_clock>::max());
471 } else {
472 // take the value returned by the finalizer (or our default message) and throw it as an error
473 // since we are inside Lua's GCTM, it will be propagated through the warning system (Lua 5.4) or swallowed silently
474 // IMPORTANT: lua_error() is used here instead of the wrapper raise_lua_error() to circumvent what looks like a MSVC compiler bug
475 // that manifests as a crash inside ntdll!longjmp() function, in optimized builds only
476 lua_error(L_);
477 }
469 } else { 478 } else {
470 // take the value returned by the finalizer (or our default message) and throw it as an error 479 // we didn't use the error message, let's keep a clean stack
471 // since we are inside Lua's GCTM, it will be propagated through the warning system (Lua 5.4) or swallowed silently 480 lua_pop(L_, 1); // L_: U
472 // IMPORTANT: lua_error() is used here instead of the wrapper raise_lua_error() to circumvent what looks like a MSVC compiler bug
473 // that manifests as a crash inside ntdll!longjmp() function, in optimized builds only
474 lua_error(L_);
475 } 481 }
476 } else {
477 // we didn't use the error message, let's keep a clean stack
478 lua_pop(L_, 1); // L_: U
479 } 482 }
480 STACK_CHECK(L_, 1); 483 STACK_CHECK(L_, 1);
481 484