Skip to content

Avoid panicking if user code exhausts the auxillary thread stack by using a list #590

@cheesycod

Description

@cheesycod

Currently, if user code exhausts the stack, then mlua will fully panic (see

panic!("cannot create a Lua reference, out of auxiliary stack space (used {top} slots)");
).

In such a case, mlua should either fallback from auxiliary thread stack to registry or operate a pool of auxilliary threads.

As it stands right now, there is no way to safely sandbox mlua as any user code which makes and handles too many references can panic and cause issues, especially in a multi tenant environment. Would you be open to a PR which solves this btw by making mlua use a list of auxillary threads instead of just one (I already run mlua with a patch to do this in production and its super helpful)?

For example, consider the following code:

local task = task
if task == nil then
    if zune then
        task = zune.task
    else 
        task = require("@lune/task")
    end
end

local started = os.clock()

local amount = 4000000
local batches = 5
local per_batch = amount / batches

for current = 1, batches do
	local thread = coroutine.running()

	print(`Batch {current} / {batches}`)

	for i = 1, per_batch do
		--print("Spawning thread #" .. i)
		task.spawn(function()
			task.wait(0.1)
			--_TEST_ASYNC_WORK(0.1)
			if i == per_batch then
				print("Last thread in batch #" .. current)
				assert(coroutine.status(thread) == "suspended", `Thread {i} has status {coroutine.status(thread)}`)
				task.spawn(thread)
			end
		end)
	end

	coroutine.yield()
end
local took = os.clock() - started
print(`Spawned {amount} sleeping threads in {took}s`)

return -1

The following code panics in my machine with the auxiliary stack size error due to holding too many luathread references.

Note: I’ve also run into this same panic several times before when coding some algorithms in luau using mlua driver code.

BTW, if you're interested, I took a (WIP rn) stab at solving this/removing this limitation using a growing list of auxiliary threads instead of just one auxiliary thread: https://github.com/cheesycod/mlua/tree/mlua-listofaux (I already run this in production)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions