diff options
Diffstat (limited to 'src/keeper.cpp')
-rw-r--r-- | src/keeper.cpp | 36 |
1 files changed, 11 insertions, 25 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index cad9207..c8c470f 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
@@ -811,22 +811,6 @@ KeeperCallResult keeper_call(KeeperState const K_, keeper_api_t const func_, lua | |||
811 | // ################################################################################################# | 811 | // ################################################################################################# |
812 | // ################################################################################################# | 812 | // ################################################################################################# |
813 | 813 | ||
814 | void* Keeper::operator new[](size_t size_, Universe* U_) noexcept | ||
815 | { | ||
816 | // size_ is the memory for the element count followed by the elements themselves | ||
817 | return U_->internalAllocator.alloc(size_); | ||
818 | } | ||
819 | |||
820 | // ################################################################################################# | ||
821 | |||
822 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | ||
823 | void Keeper::operator delete[](void* p_, Universe* U_) | ||
824 | { | ||
825 | U_->internalAllocator.free(p_, *static_cast<size_t*>(p_) * sizeof(Keeper) + sizeof(size_t)); | ||
826 | } | ||
827 | |||
828 | // ################################################################################################# | ||
829 | |||
830 | // only used by linda:dump() and linda:__towatch() for debugging purposes | 814 | // only used by linda:dump() and linda:__towatch() for debugging purposes |
831 | // table is populated as follows: | 815 | // table is populated as follows: |
832 | // { | 816 | // { |
@@ -927,7 +911,7 @@ void Keepers::DeleteKV::operator()(Keeper* const k_) const | |||
927 | for (auto& _k : std::span<Keeper>(k_, count)) { | 911 | for (auto& _k : std::span<Keeper>(k_, count)) { |
928 | _k.~Keeper(); | 912 | _k.~Keeper(); |
929 | } | 913 | } |
930 | U->internalAllocator.free(k_, count * sizeof(Keeper)); | 914 | U.internalAllocator.free(k_, count * sizeof(Keeper)); |
931 | } | 915 | } |
932 | 916 | ||
933 | // ################################################################################################# | 917 | // ################################################################################################# |
@@ -959,8 +943,8 @@ void Keepers::collectGarbage() | |||
959 | // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists | 943 | // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists |
960 | // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success | 944 | // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success |
961 | // which is early-outed with a keepers->nbKeepers null-check | 945 | // which is early-outed with a keepers->nbKeepers null-check |
962 | for (size_t const _i : std::ranges::iota_view{ size_t{ 0 }, _kv.nbKeepers }) { | 946 | for (Keeper& _k : std::span<Keeper>{ _kv.keepers.get(), _kv.nbKeepers }) { |
963 | _gcOneKeeper(_kv.keepers[_i]); | 947 | _gcOneKeeper(_k); |
964 | } | 948 | } |
965 | } | 949 | } |
966 | } | 950 | } |
@@ -996,9 +980,8 @@ void Keepers::close() | |||
996 | // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists | 980 | // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists |
997 | // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success | 981 | // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success |
998 | // which is early-outed with a keepers->nbKeepers null-check | 982 | // which is early-outed with a keepers->nbKeepers null-check |
999 | size_t const _nbKeepers{ std::exchange(_kv.nbKeepers, size_t{ 0 }) }; | 983 | for (Keeper& _k : std::span<Keeper>{ _kv.keepers.get(), std::exchange(_kv.nbKeepers, size_t{ 0 }) }) { |
1000 | for (size_t const _i : std::ranges::iota_view{ size_t{ 0 }, _nbKeepers }) { | 984 | if (!_closeOneKeeper(_k)) { |
1001 | if (!_closeOneKeeper(_kv.keepers[_i])) { | ||
1002 | // detected partial init: destroy only the mutexes that got initialized properly | 985 | // detected partial init: destroy only the mutexes that got initialized properly |
1003 | break; | 986 | break; |
1004 | } | 987 | } |
@@ -1137,11 +1120,14 @@ void Keepers::initialize(Universe& U_, lua_State* L_, size_t const nbKeepers_, i | |||
1137 | 1120 | ||
1138 | default: | 1121 | default: |
1139 | KV& _kv = keeper_array.emplace<KV>( | 1122 | KV& _kv = keeper_array.emplace<KV>( |
1140 | std::unique_ptr<Keeper[], DeleteKV>{ new(&U_) Keeper[nbKeepers_], DeleteKV{ &U_, nbKeepers_ } }, | 1123 | std::unique_ptr<Keeper, DeleteKV>{ static_cast<Keeper*>(U_.internalAllocator.alloc(sizeof(Keeper) * nbKeepers_)), DeleteKV{ U_, nbKeepers_ } }, |
1141 | nbKeepers_ | 1124 | nbKeepers_ |
1142 | ); | 1125 | ); |
1143 | for (size_t const _i : std::ranges::iota_view{ size_t{ 0 }, nbKeepers_ }) { | 1126 | // fak. std::ranges::views::enumerate is c++23 (would help having item and index iterated over simultaneously) |
1144 | _initOneKeeper(_kv.keepers[_i], static_cast<int>(_i)); | 1127 | int _i{}; |
1128 | for (Keeper& _k : std::span<Keeper>{ _kv.keepers.get(), nbKeepers_ }) { | ||
1129 | new (&_k) Keeper{}; | ||
1130 | _initOneKeeper(_k, _i++); | ||
1145 | } | 1131 | } |
1146 | } | 1132 | } |
1147 | } | 1133 | } |