diff options
Diffstat (limited to 'src/universe.cpp')
-rw-r--r-- | src/universe.cpp | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/src/universe.cpp b/src/universe.cpp index 770fccf..097c642 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
@@ -176,7 +176,7 @@ Universe::Universe() | |||
176 | // Do I need to disable this when compiling for LuaJIT to prevent issues? | 176 | // Do I need to disable this when compiling for LuaJIT to prevent issues? |
177 | void Universe::initializeAllocatorFunction(lua_State* const L_) | 177 | void Universe::initializeAllocatorFunction(lua_State* const L_) |
178 | { | 178 | { |
179 | // start by just grabbing whatever allocator was provided to lua_newstate | 179 | // start by just grabbing whatever allocator was provided to the master state |
180 | protectedAllocator.initFrom(L_); | 180 | protectedAllocator.initFrom(L_); |
181 | STACK_CHECK_START_REL(L_, 1); // L_: settings | 181 | STACK_CHECK_START_REL(L_, 1); // L_: settings |
182 | switch (luaG_getfield(L_, -1, "allocator")) { // L_: settings allocator|nil|"protected" | 182 | switch (luaG_getfield(L_, -1, "allocator")) { // L_: settings allocator|nil|"protected" |
@@ -212,19 +212,17 @@ void Universe::initializeAllocatorFunction(lua_State* const L_) | |||
212 | default: // should be filtered out in lanes.lua | 212 | default: // should be filtered out in lanes.lua |
213 | raise_luaL_error(L_, "Bad config.allocator type %s", luaG_typename(L_, -1).data()); | 213 | raise_luaL_error(L_, "Bad config.allocator type %s", luaG_typename(L_, -1).data()); |
214 | } | 214 | } |
215 | lua_pop(L_, 1); // L_: settings | 215 | lua_pop(L_, 1); // L_: settings |
216 | STACK_CHECK(L_, 1); | 216 | STACK_CHECK(L_, 1); |
217 | 217 | ||
218 | std::ignore = luaG_getfield(L_, -1, "internal_allocator"); // L_: settings "libc"|"allocator" | 218 | std::ignore = luaG_getfield(L_, -1, "internal_allocator"); // L_: settings "libc"|"allocator" |
219 | LUA_ASSERT(L_, lua_isstring(L_, -1)); // should be the case due to lanes.lua parameter validation | ||
219 | std::string_view const _allocator{ luaG_tostring(L_, -1) }; | 220 | std::string_view const _allocator{ luaG_tostring(L_, -1) }; |
220 | if (_allocator == "libc") { | 221 | if (_allocator == "libc") { |
221 | internalAllocator = lanes::AllocatorDefinition{ lanes::AllocatorDefinition::kAllocatorVersion, libc_lua_Alloc, nullptr }; | 222 | internalAllocator = lanes::AllocatorDefinition{ lanes::AllocatorDefinition::kAllocatorVersion, libc_lua_Alloc, nullptr }; |
222 | } else if (provideAllocator == luaG_provide_protected_allocator) { | ||
223 | // user wants mutex protection on the state's allocator. Use protection for our own allocations too, just in case. | ||
224 | internalAllocator = protectedAllocator.makeDefinition(); | ||
225 | } else { | 223 | } else { |
226 | // no protection required, just use whatever we have as-is. | 224 | // use whatever the provider provides |
227 | internalAllocator = protectedAllocator; | 225 | internalAllocator = resolveAllocator(L_, "internal"); |
228 | } | 226 | } |
229 | lua_pop(L_, 1); // L_: settings | 227 | lua_pop(L_, 1); // L_: settings |
230 | STACK_CHECK(L_, 1); | 228 | STACK_CHECK(L_, 1); |
@@ -254,6 +252,29 @@ int Universe::InitializeFinalizer(lua_State* const L_) | |||
254 | 252 | ||
255 | // ################################################################################################# | 253 | // ################################################################################################# |
256 | 254 | ||
255 | lanes::AllocatorDefinition Universe::resolveAllocator(lua_State* const L_, std::string_view const& hint_) const | ||
256 | { | ||
257 | lanes::AllocatorDefinition _ret{ protectedAllocator }; | ||
258 | if (provideAllocator == nullptr) { | ||
259 | return _ret; | ||
260 | } | ||
261 | |||
262 | STACK_CHECK_START_REL(L_, 0); // here, we have a function we can call to obtain an allocator | ||
263 | lua_pushcclosure(L_, provideAllocator, 0); // L_: provideAllocator() | ||
264 | luaG_pushstring(L_, hint_); // L_: provideAllocator() "<hint>" | ||
265 | lua_call(L_, 1, 1); // L_: result | ||
266 | lanes::AllocatorDefinition* const _def{ luaG_tofulluserdata<lanes::AllocatorDefinition>(L_, -1) }; | ||
267 | if (!_def || _def->version != lanes::AllocatorDefinition::kAllocatorVersion) { | ||
268 | raise_luaL_error(L_, "Bad config.allocator function, must provide a valid AllocatorDefinition"); | ||
269 | } | ||
270 | _ret = *_def; | ||
271 | lua_pop(L_, 1); // L_: | ||
272 | STACK_CHECK(L_, 0); | ||
273 | return _ret; | ||
274 | } | ||
275 | |||
276 | // ################################################################################################# | ||
277 | |||
257 | void Universe::terminateFreeRunningLanes(lua_State* const L_, lua_Duration const shutdownTimeout_, CancelOp const op_) | 278 | void Universe::terminateFreeRunningLanes(lua_State* const L_, lua_Duration const shutdownTimeout_, CancelOp const op_) |
258 | { | 279 | { |
259 | if (selfdestructFirst != SELFDESTRUCT_END) { | 280 | if (selfdestructFirst != SELFDESTRUCT_END) { |