aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.runsettings8
-rw-r--r--Makefile8
-rw-r--r--deep_userdata_example/deep_userdata_example.cpp16
-rw-r--r--src/intercopycontext.cpp4
-rw-r--r--src/keeper.cpp36
-rw-r--r--src/keeper.hpp13
-rw-r--r--src/threading.cpp4
-rw-r--r--unit_tests/UnitTests.vcxproj40
-rw-r--r--unit_tests/init_and_shutdown.cpp76
9 files changed, 101 insertions, 104 deletions
diff --git a/.runsettings b/.runsettings
index 8114d6a..e349e01 100644
--- a/.runsettings
+++ b/.runsettings
@@ -8,10 +8,10 @@
8 <!-- The whole setup relies on Lua Binaries and headers to be located in a folder $(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName) 8 <!-- The whole setup relies on Lua Binaries and headers to be located in a folder $(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)
9 this is also true for linker input folders, the folder where lanes.lua is copied by the custom build operation, etc. 9 this is also true for linker input folders, the folder where lanes.lua is copied by the custom build operation, etc.
10 --> 10 -->
11 <Environment> 11 <!-- Environment>
12 <LUA_PATH value="$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)" /> 12 <LUA_PATH>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)</LUA_PATH>
13 <LUA_CPATH value="$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)" /> 13 <LUA_CPATH>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)</LUA_CPATH>
14 </Environment> 14 </Environment -->
15 15
16 <!-- Executable Filename 16 <!-- Executable Filename
17 Discover filenames with ... (must not include the .exe extension) 17 Discover filenames with ... (must not include the .exe extension)
diff --git a/Makefile b/Makefile
index c0f08b4..5b5d27a 100644
--- a/Makefile
+++ b/Makefile
@@ -79,7 +79,13 @@ build_DUE:
79# also run a test that shows whether lanes is successfully loaded or not 79# also run a test that shows whether lanes is successfully loaded or not
80run_unit_tests: build_lanes build_unit_tests build_DUE 80run_unit_tests: build_lanes build_unit_tests build_DUE
81 @echo ========================================================================================= 81 @echo =========================================================================================
82 $(_PREFIX) $(_UNITTEST_TARGET) "lanes.require 'lanes'" 82 $(_PREFIX) $(_UNITTEST_TARGET) --list-tests
83 $(_PREFIX) $(_UNITTEST_TARGET) --rng-seed 0 -s
84
85debug_unit_tests: build_lanes build_unit_tests build_DUE
86 @echo =========================================================================================
87 $(_PREFIX) $(_UNITTEST_TARGET) --list-tests
88 $(_PREFIX) gdb --args $(_UNITTEST_TARGET) --rng-seed 0 -s "lanes.configure.nb_user_keepers"
83 89
84clean: 90clean:
85 cd src && $(MAKE) -f Lanes.makefile clean 91 cd src && $(MAKE) -f Lanes.makefile clean
diff --git a/deep_userdata_example/deep_userdata_example.cpp b/deep_userdata_example/deep_userdata_example.cpp
index a45cc7f..075cfbe 100644
--- a/deep_userdata_example/deep_userdata_example.cpp
+++ b/deep_userdata_example/deep_userdata_example.cpp
@@ -261,21 +261,21 @@ static int clonable_gc(lua_State* const L_)
261 261
262// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code. 262// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code.
263[[nodiscard]] 263[[nodiscard]]
264static int clonable_lanesclone(lua_State* L) 264static int clonable_lanesclone(lua_State* const L_)
265{ 265{
266 switch (lua_gettop(L)) { 266 switch (lua_gettop(L_)) {
267 case 3: 267 case 3:
268 { 268 {
269 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); 269 MyClonableUserdata* const _self = static_cast<MyClonableUserdata*>(lua_touserdata(L_, 1));
270 MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2)); 270 MyClonableUserdata* const _from = static_cast<MyClonableUserdata*>(lua_touserdata(L_, 2));
271 size_t len = lua_tointeger(L, 3); 271 auto const _len{ static_cast<size_t>(lua_tointeger(L_, 3)) }; // make 32-bits builds happy
272 assert(len == sizeof(MyClonableUserdata)); 272 assert(_len == sizeof(MyClonableUserdata));
273 *self = *from; 273 *_self = *_from;
274 } 274 }
275 return 0; 275 return 0;
276 276
277 default: 277 default:
278 raise_luaL_error(L, "Lanes called clonable_lanesclone with unexpected arguments"); 278 raise_luaL_error(L_, "Lanes called clonable_lanesclone with unexpected arguments");
279 } 279 }
280 return 0; 280 return 0;
281} 281}
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp
index d6716a3..93a8160 100644
--- a/src/intercopycontext.cpp
+++ b/src/intercopycontext.cpp
@@ -770,7 +770,7 @@ bool InterCopyContext::tryCopyClonable() const
770 // we need to copy over the uservalues of the userdata as well 770 // we need to copy over the uservalues of the userdata as well
771 { 771 {
772 StackIndex const _mt{ luaG_absindex(L1, StackIndex{ -2 }) }; // L1: ... mt __lanesclone 772 StackIndex const _mt{ luaG_absindex(L1, StackIndex{ -2 }) }; // L1: ... mt __lanesclone
773 size_t const userdata_size{ lua_rawlen(L1, _L1_i) }; 773 auto const userdata_size{ static_cast<size_t>(lua_rawlen(L1, _L1_i)) }; // make 32-bits builds happy
774 // extract all the uservalues, but don't transfer them yet 774 // extract all the uservalues, but don't transfer them yet
775 UserValueCount const _nuv{ luaG_getalluservalues(L1, _L1_i) }; // L1: ... mt __lanesclone [uv]* 775 UserValueCount const _nuv{ luaG_getalluservalues(L1, _L1_i) }; // L1: ... mt __lanesclone [uv]*
776 // create the clone userdata with the required number of uservalue slots 776 // create the clone userdata with the required number of uservalue slots
@@ -930,7 +930,7 @@ bool InterCopyContext::interCopyFunction() const
930 _source = lua_touserdata(L1, -1); 930 _source = lua_touserdata(L1, -1);
931 void* _clone{ nullptr }; 931 void* _clone{ nullptr };
932 // get the number of bytes to allocate for the clone 932 // get the number of bytes to allocate for the clone
933 size_t const _userdata_size{ lua_rawlen(L1, kIdxTop) }; 933 auto const _userdata_size{ static_cast<size_t>(lua_rawlen(L1, kIdxTop)) }; // make 32-bits builds happy
934 { 934 {
935 // extract uservalues (don't transfer them yet) 935 // extract uservalues (don't transfer them yet)
936 UserValueCount const _nuv{ luaG_getalluservalues(L1, source_i) }; // L1: ... u [uv]* 936 UserValueCount const _nuv{ luaG_getalluservalues(L1, source_i) }; // L1: ... u [uv]*
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
814void* 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
823void 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}
diff --git a/src/keeper.hpp b/src/keeper.hpp
index 5cebe07..f1083b3 100644
--- a/src/keeper.hpp
+++ b/src/keeper.hpp
@@ -26,12 +26,6 @@ struct Keeper
26 std::mutex mutex; 26 std::mutex mutex;
27 KeeperState K{ static_cast<lua_State*>(nullptr) }; 27 KeeperState K{ static_cast<lua_State*>(nullptr) };
28 28
29 [[nodiscard]]
30 static void* operator new[](size_t size_, Universe* U_) noexcept;
31 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception
32 static void operator delete[](void* p_, Universe* U_);
33
34
35 ~Keeper() = default; 29 ~Keeper() = default;
36 Keeper() = default; 30 Keeper() = default;
37 // non-copyable, non-movable 31 // non-copyable, non-movable
@@ -51,14 +45,15 @@ struct Keepers
51 private: 45 private:
52 struct DeleteKV 46 struct DeleteKV
53 { 47 {
54 Universe* U{}; 48 Universe& U;
55 size_t count{}; 49 size_t count{};
56 void operator()(Keeper* k_) const; 50 void operator()(Keeper* k_) const;
57 }; 51 };
58 // can't use std::vector<Keeper> because Keeper contains a mutex, so we need a raw memory buffer 52 // can't use std::unique_ptr<Keeper[]> because of interactions with placement new and custom deleters
53 // and I'm not using std::vector<Keeper> because I don't have an allocator to plug on the Universe (yet)
59 struct KV 54 struct KV
60 { 55 {
61 std::unique_ptr<Keeper[], DeleteKV> keepers; 56 std::unique_ptr<Keeper, DeleteKV> keepers;
62 size_t nbKeepers{}; 57 size_t nbKeepers{};
63 }; 58 };
64 std::variant<std::monostate, Keeper, KV> keeper_array; 59 std::variant<std::monostate, Keeper, KV> keeper_array;
diff --git a/src/threading.cpp b/src/threading.cpp
index 3e594ff..3435075 100644
--- a/src/threading.cpp
+++ b/src/threading.cpp
@@ -449,7 +449,9 @@ void THREAD_SETNAME(std::string_view const& name_)
449{ 449{
450 // exact API to set the thread name is platform-dependant 450 // exact API to set the thread name is platform-dependant
451 // if you need to fix the build, or if you know how to fill a hole, tell me (bnt.germain@gmail.com) so that I can submit the fix in github. 451 // if you need to fix the build, or if you know how to fill a hole, tell me (bnt.germain@gmail.com) so that I can submit the fix in github.
452#if defined PLATFORM_BSD && !defined __NetBSD__ 452#if defined PLATFORM_MINGW
453 pthread_setname_np(pthread_self(), name_.data());
454#elif defined PLATFORM_BSD && !defined __NetBSD__
453 pthread_set_name_np(pthread_self(), name_.data()); 455 pthread_set_name_np(pthread_self(), name_.data());
454#elif defined PLATFORM_BSD && defined __NetBSD__ 456#elif defined PLATFORM_BSD && defined __NetBSD__
455 pthread_setname_np(pthread_self(), "%s", (void*) name_.data()); 457 pthread_setname_np(pthread_self(), "%s", (void*) name_.data());
diff --git a/unit_tests/UnitTests.vcxproj b/unit_tests/UnitTests.vcxproj
index 6ff1eb1..e78e32a 100644
--- a/unit_tests/UnitTests.vcxproj
+++ b/unit_tests/UnitTests.vcxproj
@@ -155,103 +155,103 @@
155 <ImportGroup Label="PropertySheets" /> 155 <ImportGroup Label="PropertySheets" />
156 <PropertyGroup Label="UserMacros" /> 156 <PropertyGroup Label="UserMacros" />
157 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'"> 157 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">
158 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 158 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
159 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 159 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
160 <LinkIncremental>false</LinkIncremental> 160 <LinkIncremental>false</LinkIncremental>
161 </PropertyGroup> 161 </PropertyGroup>
162 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'"> 162 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">
163 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 163 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
164 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 164 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
165 <LinkIncremental>false</LinkIncremental> 165 <LinkIncremental>false</LinkIncremental>
166 </PropertyGroup> 166 </PropertyGroup>
167 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'"> 167 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">
168 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 168 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
169 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 169 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
170 <LinkIncremental>false</LinkIncremental> 170 <LinkIncremental>false</LinkIncremental>
171 </PropertyGroup> 171 </PropertyGroup>
172 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'"> 172 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'">
173 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 173 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
174 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 174 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
175 <LinkIncremental>false</LinkIncremental> 175 <LinkIncremental>false</LinkIncremental>
176 </PropertyGroup> 176 </PropertyGroup>
177 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.2|Win32'"> 177 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.2|Win32'">
178 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 178 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
179 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 179 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
180 <LinkIncremental>false</LinkIncremental> 180 <LinkIncremental>false</LinkIncremental>
181 </PropertyGroup> 181 </PropertyGroup>
182 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Win32'"> 182 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Win32'">
183 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 183 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
184 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 184 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
185 <LinkIncremental>false</LinkIncremental> 185 <LinkIncremental>false</LinkIncremental>
186 </PropertyGroup> 186 </PropertyGroup>
187 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.1|Win32'"> 187 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.1|Win32'">
188 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 188 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
189 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 189 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
190 <LinkIncremental>false</LinkIncremental> 190 <LinkIncremental>false</LinkIncremental>
191 </PropertyGroup> 191 </PropertyGroup>
192 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'"> 192 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'">
193 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 193 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
194 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 194 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
195 <LinkIncremental>false</LinkIncremental> 195 <LinkIncremental>false</LinkIncremental>
196 </PropertyGroup> 196 </PropertyGroup>
197 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'"> 197 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'">
198 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 198 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
199 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 199 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
200 <LinkIncremental>false</LinkIncremental> 200 <LinkIncremental>false</LinkIncremental>
201 </PropertyGroup> 201 </PropertyGroup>
202 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'"> 202 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'">
203 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 203 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
204 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 204 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
205 <LinkIncremental>false</LinkIncremental> 205 <LinkIncremental>false</LinkIncremental>
206 </PropertyGroup> 206 </PropertyGroup>
207 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'"> 207 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">
208 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 208 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
209 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 209 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
210 <LinkIncremental>false</LinkIncremental> 210 <LinkIncremental>false</LinkIncremental>
211 </PropertyGroup> 211 </PropertyGroup>
212 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'" /> 212 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'" />
213 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'"> 213 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">
214 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 214 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
215 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 215 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
216 <LinkIncremental>false</LinkIncremental> 216 <LinkIncremental>false</LinkIncremental>
217 </PropertyGroup> 217 </PropertyGroup>
218 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'"> 218 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'">
219 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 219 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
220 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 220 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
221 <LinkIncremental>false</LinkIncremental> 221 <LinkIncremental>false</LinkIncremental>
222 </PropertyGroup> 222 </PropertyGroup>
223 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'"> 223 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'">
224 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 224 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
225 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 225 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
226 <LinkIncremental>false</LinkIncremental> 226 <LinkIncremental>false</LinkIncremental>
227 </PropertyGroup> 227 </PropertyGroup>
228 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.2|x64'"> 228 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.2|x64'">
229 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 229 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
230 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 230 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
231 <LinkIncremental>false</LinkIncremental> 231 <LinkIncremental>false</LinkIncremental>
232 </PropertyGroup> 232 </PropertyGroup>
233 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'"> 233 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'">
234 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 234 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
235 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 235 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
236 <LinkIncremental>false</LinkIncremental> 236 <LinkIncremental>false</LinkIncremental>
237 </PropertyGroup> 237 </PropertyGroup>
238 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.1|x64'"> 238 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.1|x64'">
239 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 239 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
240 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 240 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
241 <LinkIncremental>false</LinkIncremental> 241 <LinkIncremental>false</LinkIncremental>
242 </PropertyGroup> 242 </PropertyGroup>
243 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|x64'"> 243 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|x64'">
244 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 244 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
245 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 245 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
246 <LinkIncremental>false</LinkIncremental> 246 <LinkIncremental>false</LinkIncremental>
247 </PropertyGroup> 247 </PropertyGroup>
248 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|x64'"> 248 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|x64'">
249 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 249 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
250 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 250 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
251 <LinkIncremental>false</LinkIncremental> 251 <LinkIncremental>false</LinkIncremental>
252 </PropertyGroup> 252 </PropertyGroup>
253 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'"> 253 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'">
254 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 254 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
255 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 255 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
256 <LinkIncremental>false</LinkIncremental> 256 <LinkIncremental>false</LinkIncremental>
257 </PropertyGroup> 257 </PropertyGroup>
diff --git a/unit_tests/init_and_shutdown.cpp b/unit_tests/init_and_shutdown.cpp
index b8174fd..384af43 100644
--- a/unit_tests/init_and_shutdown.cpp
+++ b/unit_tests/init_and_shutdown.cpp
@@ -289,58 +289,66 @@ TEST_CASE("lanes.configure.keepers_gc_threshold")
289 289
290// ################################################################################################# 290// #################################################################################################
291 291
292TEST_CASE("lanes.configure.the rest") 292TEST_CASE("lanes.configure.nb_user_keepers")
293{ 293{
294 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 294 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
295 295
296
297 // ---------------------------------------------------------------------------------------------
298 // nb_user_keepers should be a number in [0, 100] 296 // nb_user_keepers should be a number in [0, 100]
299 297
300 SECTION("nb_user_keepers") 298 SECTION("nb_user_keepers = <table>")
301 { 299 {
302 SECTION("nb_user_keepers = <table>") 300 L.requireFailure("require 'lanes'.configure{nb_user_keepers = {}}");
303 { 301 }
304 L.requireFailure("require 'lanes'.configure{nb_user_keepers = {}}");
305 }
306 302
307 // ----------------------------------------------------------------------------------------- 303 // -----------------------------------------------------------------------------------------
308 304
309 SECTION("nb_user_keepers = <string>") 305 SECTION("nb_user_keepers = <string>")
310 { 306 {
311 L.requireFailure("require 'lanes'.configure{nb_user_keepers = 'gluh'}"); 307 L.requireFailure("require 'lanes'.configure{nb_user_keepers = 'gluh'}");
312 } 308 }
313 309
314 // ----------------------------------------------------------------------------------------- 310 // -----------------------------------------------------------------------------------------
315 311
316 SECTION("nb_user_keepers = -1") 312 SECTION("nb_user_keepers = -1")
317 { 313 {
318 L.requireFailure("require 'lanes'.configure{nb_user_keepers = -1}"); 314 L.requireFailure("require 'lanes'.configure{nb_user_keepers = -1}");
319 } 315 }
320 316
321 // ----------------------------------------------------------------------------------------- 317 // -----------------------------------------------------------------------------------------
322 318
323 SECTION("nb_user_keepers = 0") 319 SECTION("nb_user_keepers = 0")
324 { 320 {
325 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 0}"); 321 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 0}");
326 } 322 }
327 323
328 // ----------------------------------------------------------------------------------------- 324 // -----------------------------------------------------------------------------------------
329 325
330 SECTION("nb_user_keepers = 100") 326 SECTION("nb_user_keepers = 1")
331 { 327 {
332 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 100}"); 328 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 1}");
333 } 329 }
334 330
335 // ----------------------------------------------------------------------------------------- 331 // -----------------------------------------------------------------------------------------
336 332
337 SECTION("nb_user_keepers = 101") 333 SECTION("nb_user_keepers = 100")
338 { 334 {
339 L.requireFailure("require 'lanes'.configure{nb_user_keepers = 101}"); 335 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 100}");
340 }
341 } 336 }
342 337
343 // --------------------------------------------------------------------------------------------- 338 // -----------------------------------------------------------------------------------------
339
340 SECTION("nb_user_keepers = 101")
341 {
342 L.requireFailure("require 'lanes'.configure{nb_user_keepers = 101}");
343 }
344}
345
346// #################################################################################################
347
348TEST_CASE("lanes.configure.the rest")
349{
350 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
351
344 // on_state_create should be a function, either C or Lua, without upvalues 352 // on_state_create should be a function, either C or Lua, without upvalues
345 353
346 SECTION("on_state_create") 354 SECTION("on_state_create")