diff options
Diffstat (limited to 'src/linda.cpp')
-rw-r--r-- | src/linda.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/linda.cpp b/src/linda.cpp index 37a74b0..5ee4768 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
@@ -885,15 +885,22 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
885 | { | 885 | { |
886 | Linda* const linda{ lua_tolightuserdata<Linda>(L, 1) }; | 886 | Linda* const linda{ lua_tolightuserdata<Linda>(L, 1) }; |
887 | ASSERT_L(linda); | 887 | ASSERT_L(linda); |
888 | 888 | Keeper* const myK{ which_keeper(linda->U->keepers, linda->hashSeed()) }; | |
889 | // Clean associated structures in the keeper state. | 889 | // if collected after the universe, keepers are already destroyed, and there is nothing to clear |
890 | Keeper* const K{ keeper_acquire(linda->U->keepers, linda->hashSeed()) }; | 890 | if (myK) |
891 | if (K && K->L) // can be nullptr if this happens during main state shutdown (lanes is GC'ed -> no keepers -> no need to cleanup) | ||
892 | { | 891 | { |
892 | // if collected from my own keeper, we can't acquire/release it | ||
893 | // because we are already inside a protected area, and trying to do so would deadlock! | ||
894 | bool const need_acquire_release{ myK->L != L }; | ||
895 | // Clean associated structures in the keeper state. | ||
896 | Keeper* const K{ need_acquire_release ? keeper_acquire(linda->U->keepers, linda->hashSeed()) : myK }; | ||
893 | // hopefully this won't ever raise an error as we would jump to the closest pcall site while forgetting to release the keeper mutex... | 897 | // hopefully this won't ever raise an error as we would jump to the closest pcall site while forgetting to release the keeper mutex... |
894 | keeper_call(linda->U, K->L, KEEPER_API(clear), L, linda, 0); | 898 | keeper_call(linda->U, K->L, KEEPER_API(clear), L, linda, 0); |
899 | if (need_acquire_release) | ||
900 | { | ||
901 | keeper_release(K); | ||
902 | } | ||
895 | } | 903 | } |
896 | keeper_release(K); | ||
897 | 904 | ||
898 | delete linda; // operator delete overload ensures things go as expected | 905 | delete linda; // operator delete overload ensures things go as expected |
899 | return nullptr; | 906 | return nullptr; |