diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/keeper.cpp | 9 | ||||
| -rw-r--r-- | src/keeper.hpp | 2 | ||||
| -rw-r--r-- | src/lane.cpp | 12 | ||||
| -rw-r--r-- | src/universe.cpp | 12 |
4 files changed, 23 insertions, 12 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index c8c470f..ca2a80d 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
| @@ -952,15 +952,15 @@ void Keepers::collectGarbage() | |||
| 952 | // ################################################################################################# | 952 | // ################################################################################################# |
| 953 | 953 | ||
| 954 | 954 | ||
| 955 | void Keepers::close() | 955 | bool Keepers::close() |
| 956 | { | 956 | { |
| 957 | if (isClosing.test_and_set(std::memory_order_release)) { | 957 | if (isClosing.test_and_set(std::memory_order_release)) { |
| 958 | assert(false); // should never close more than once in practice | 958 | return false; // should never close more than once in practice |
| 959 | return; | ||
| 960 | } | 959 | } |
| 961 | 960 | ||
| 961 | // We may have not initialized the keepers if an error was raised in Universe::Create because of bad settings | ||
| 962 | if (std::holds_alternative<std::monostate>(keeper_array)) { | 962 | if (std::holds_alternative<std::monostate>(keeper_array)) { |
| 963 | return; | 963 | return true; |
| 964 | } | 964 | } |
| 965 | 965 | ||
| 966 | auto _closeOneKeeper = [](Keeper& keeper_) { | 966 | auto _closeOneKeeper = [](Keeper& keeper_) { |
| @@ -989,6 +989,7 @@ void Keepers::close() | |||
| 989 | } | 989 | } |
| 990 | 990 | ||
| 991 | keeper_array.emplace<std::monostate>(); | 991 | keeper_array.emplace<std::monostate>(); |
| 992 | return true; | ||
| 992 | } | 993 | } |
| 993 | 994 | ||
| 994 | // ################################################################################################# | 995 | // ################################################################################################# |
diff --git a/src/keeper.hpp b/src/keeper.hpp index f1083b3..0aa44f2 100644 --- a/src/keeper.hpp +++ b/src/keeper.hpp | |||
| @@ -68,7 +68,7 @@ struct Keepers | |||
| 68 | 68 | ||
| 69 | Keepers() = default; | 69 | Keepers() = default; |
| 70 | void collectGarbage(); | 70 | void collectGarbage(); |
| 71 | void close(); | 71 | bool close(); |
| 72 | [[nodiscard]] | 72 | [[nodiscard]] |
| 73 | Keeper* getKeeper(KeeperIndex idx_); | 73 | Keeper* getKeeper(KeeperIndex idx_); |
| 74 | [[nodiscard]] | 74 | [[nodiscard]] |
diff --git a/src/lane.cpp b/src/lane.cpp index 5cebdfa..e6ea2e5 100644 --- a/src/lane.cpp +++ b/src/lane.cpp | |||
| @@ -783,10 +783,14 @@ static void lane_main(Lane* const lane_) | |||
| 783 | if (lane_->selfdestructRemove()) { // check and remove (under lock!) | 783 | if (lane_->selfdestructRemove()) { // check and remove (under lock!) |
| 784 | // We're a free-running thread and no-one is there to clean us up. | 784 | // We're a free-running thread and no-one is there to clean us up. |
| 785 | lane_->closeState(); | 785 | lane_->closeState(); |
| 786 | lane_->U->selfdestructMutex.lock(); | 786 | |
| 787 | // done with lua_close(), terminal shutdown sequence may proceed | 787 | // let's try not to crash if the lane didn't terminate gracefully and the Universe met its end |
| 788 | lane_->U->selfdestructingCount.fetch_sub(1, std::memory_order_release); | 788 | if (!lane_->flaggedAfterUniverseGC.load(std::memory_order_relaxed)) { |
| 789 | lane_->U->selfdestructMutex.unlock(); | 789 | lane_->U->selfdestructMutex.lock(); |
| 790 | // done with lua_close(), terminal shutdown sequence may proceed | ||
| 791 | lane_->U->selfdestructingCount.fetch_sub(1, std::memory_order_release); | ||
| 792 | lane_->U->selfdestructMutex.unlock(); | ||
| 793 | } | ||
| 790 | 794 | ||
| 791 | // we destroy ourselves, therefore our thread member too, from inside the thread body | 795 | // we destroy ourselves, therefore our thread member too, from inside the thread body |
| 792 | // detach so that we don't try to join, as this doesn't seem a good idea | 796 | // detach so that we don't try to join, as this doesn't seem a good idea |
diff --git a/src/universe.cpp b/src/universe.cpp index 335f056..0f41585 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
| @@ -178,8 +178,8 @@ Universe* Universe::Create(lua_State* const L_) | |||
| 178 | 178 | ||
| 179 | // Linked chains handling | 179 | // Linked chains handling |
| 180 | _U->selfdestructFirst = SELFDESTRUCT_END; | 180 | _U->selfdestructFirst = SELFDESTRUCT_END; |
| 181 | _U->initializeAllocatorFunction(L_); | 181 | _U->initializeAllocatorFunction(L_); // this can raise an error |
| 182 | _U->initializeOnStateCreate(L_); | 182 | _U->initializeOnStateCreate(L_); // this can raise an error |
| 183 | _U->keepers.initialize(*_U, L_, static_cast<size_t>(_nbUserKeepers), _keepers_gc_threshold); | 183 | _U->keepers.initialize(*_U, L_, static_cast<size_t>(_nbUserKeepers), _keepers_gc_threshold); |
| 184 | STACK_CHECK(L_, 0); | 184 | STACK_CHECK(L_, 0); |
| 185 | 185 | ||
| @@ -463,7 +463,11 @@ int Universe::UniverseGC(lua_State* const L_) | |||
| 463 | // that manifests as a crash inside ntdll!longjmp() function, in optimized builds only | 463 | // that manifests as a crash inside ntdll!longjmp() function, in optimized builds only |
| 464 | lua_error(L_); | 464 | lua_error(L_); |
| 465 | } | 465 | } |
| 466 | } else { | ||
| 467 | // we didn't use the error message, let's keep a clean stack | ||
| 468 | lua_pop(L_, 1); // L_: U | ||
| 466 | } | 469 | } |
| 470 | STACK_CHECK(L_, 1); | ||
| 467 | 471 | ||
| 468 | // --------------------------------------------------------- | 472 | // --------------------------------------------------------- |
| 469 | // we don't reach that point if some lanes are still running | 473 | // we don't reach that point if some lanes are still running |
| @@ -472,7 +476,9 @@ int Universe::UniverseGC(lua_State* const L_) | |||
| 472 | // no need to mutex-protect this as all lanes in the universe are gone at that point | 476 | // no need to mutex-protect this as all lanes in the universe are gone at that point |
| 473 | Linda::DeleteTimerLinda(L_, std::exchange(_U->timerLinda, nullptr), PK); | 477 | Linda::DeleteTimerLinda(L_, std::exchange(_U->timerLinda, nullptr), PK); |
| 474 | 478 | ||
| 475 | _U->keepers.close(); | 479 | if (!_U->keepers.close()) { |
| 480 | raise_luaL_error(L_, "INTERNAL ERROR: Keepers closed more than once"); | ||
| 481 | } | ||
| 476 | 482 | ||
| 477 | // remove the protected allocator, if any | 483 | // remove the protected allocator, if any |
| 478 | _U->protectedAllocator.removeFrom(L_); | 484 | _U->protectedAllocator.removeFrom(L_); |
