diff options
Diffstat (limited to '')
-rw-r--r-- | src/keeper.cpp | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index 937d190..0aea18e 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
@@ -627,7 +627,7 @@ void close_keepers(Universe* U) | |||
627 | } | 627 | } |
628 | for (int i = 0; i < nbKeepers; ++i) | 628 | for (int i = 0; i < nbKeepers; ++i) |
629 | { | 629 | { |
630 | MUTEX_FREE(&U->keepers->keeper_array[i].keeper_cs); | 630 | U->keepers->keeper_array[i].~Keeper(); |
631 | } | 631 | } |
632 | // free the keeper bookkeeping structure | 632 | // free the keeper bookkeeping structure |
633 | U->internal_allocator.free(U->keepers, sizeof(Keepers) + (nbKeepers - 1) * sizeof(Keeper)); | 633 | U->internal_allocator.free(U->keepers, sizeof(Keepers) + (nbKeepers - 1) * sizeof(Keeper)); |
@@ -673,9 +673,14 @@ void init_keepers(Universe* U, lua_State* L) | |||
673 | { | 673 | { |
674 | std::ignore = luaL_error(L, "init_keepers() failed while creating keeper array; out of memory"); | 674 | std::ignore = luaL_error(L, "init_keepers() failed while creating keeper array; out of memory"); |
675 | } | 675 | } |
676 | memset(U->keepers, 0, bytes); | 676 | U->keepers->Keepers::Keepers(); |
677 | U->keepers->gc_threshold = keepers_gc_threshold; | 677 | U->keepers->gc_threshold = keepers_gc_threshold; |
678 | U->keepers->nb_keepers = nb_keepers; | 678 | U->keepers->nb_keepers = nb_keepers; |
679 | |||
680 | for (int i = 0; i < nb_keepers; ++i) | ||
681 | { | ||
682 | U->keepers->keeper_array[i].Keeper::Keeper(); | ||
683 | } | ||
679 | } | 684 | } |
680 | for (int i = 0; i < nb_keepers; ++i) // keepersUD | 685 | for (int i = 0; i < nb_keepers; ++i) // keepersUD |
681 | { | 686 | { |
@@ -687,10 +692,6 @@ void init_keepers(Universe* U, lua_State* L) | |||
687 | } | 692 | } |
688 | 693 | ||
689 | U->keepers->keeper_array[i].L = K; | 694 | U->keepers->keeper_array[i].L = K; |
690 | // we can trigger a GC from inside keeper_call(), where a keeper is acquired | ||
691 | // from there, GC can collect a linda, which would acquire the keeper again, and deadlock the thread. | ||
692 | // therefore, we need a recursive mutex. | ||
693 | MUTEX_RECURSIVE_INIT(&U->keepers->keeper_array[i].keeper_cs); | ||
694 | 695 | ||
695 | if (U->keepers->gc_threshold >= 0) | 696 | if (U->keepers->gc_threshold >= 0) |
696 | { | 697 | { |
@@ -772,8 +773,7 @@ Keeper* keeper_acquire(Keepers* keepers_, uintptr_t magic_) | |||
772 | */ | 773 | */ |
773 | unsigned int i = (unsigned int)((magic_ >> KEEPER_MAGIC_SHIFT) % nbKeepers); | 774 | unsigned int i = (unsigned int)((magic_ >> KEEPER_MAGIC_SHIFT) % nbKeepers); |
774 | Keeper* K = &keepers_->keeper_array[i]; | 775 | Keeper* K = &keepers_->keeper_array[i]; |
775 | 776 | K->m_mutex.lock(); | |
776 | MUTEX_LOCK( &K->keeper_cs); | ||
777 | //++ K->count; | 777 | //++ K->count; |
778 | return K; | 778 | return K; |
779 | } | 779 | } |
@@ -787,7 +787,7 @@ void keeper_release(Keeper* K) | |||
787 | //-- K->count; | 787 | //-- K->count; |
788 | if (K) | 788 | if (K) |
789 | { | 789 | { |
790 | MUTEX_UNLOCK(&K->keeper_cs); | 790 | K->m_mutex.unlock(); |
791 | } | 791 | } |
792 | } | 792 | } |
793 | 793 | ||
@@ -843,7 +843,6 @@ int keeper_call(Universe* U, lua_State* K, keeper_api_t func_, lua_State* L, voi | |||
843 | if ((args == 0) || luaG_inter_copy(U, L, K, args, LookupMode::ToKeeper) == 0) // L->K | 843 | if ((args == 0) || luaG_inter_copy(U, L, K, args, LookupMode::ToKeeper) == 0) // L->K |
844 | { | 844 | { |
845 | lua_call(K, 1 + args, LUA_MULTRET); | 845 | lua_call(K, 1 + args, LUA_MULTRET); |
846 | |||
847 | retvals = lua_gettop(K) - Ktos; | 846 | retvals = lua_gettop(K) - Ktos; |
848 | // note that this can raise a luaL_error while the keeper state (and its mutex) is acquired | 847 | // note that this can raise a luaL_error while the keeper state (and its mutex) is acquired |
849 | // this may interrupt a lane, causing the destruction of the underlying OS thread | 848 | // this may interrupt a lane, causing the destruction of the underlying OS thread |