Closed lePereT closed 1 year ago
That's a very interesting functionality, but I suspect it is possible to implement with an auxiliary function without modifying the scheduler.
Something like
function defer( task, f )
sched.run( function()
sched.wait({task.EVENT_DIE, task.EVENT_FINISH})
f()
end)
end
If you want to free locals from inside a task, you could set up de defer from the task itself:
sched.run( function()
local file = io.open(...)
defer(sched.running_task, function() if file then file:close() end )
--rest of the task using file
end)
Does this make sense for you?
Hi Xopxe, it absolutely does,
I'd simplify the caller of defer
like this:
function defer( f )
local task = sched.running_task
sched.run( function()
sched.wait({task.EVENT_DIE, task.EVENT_FINISH})
f()
end)
end
sched.run( function()
local file = io.open(...)
defer( function() if file then file:close() end )
--rest of the task using file
end)
This is inspired by Go, whose defer
statement has the following shape: https://go.dev/blog/defer-panic-and-recover
Interestingly Go's defer creates a stack of functions whose arguments are evaluated at function call time, and which are executed in LIFO order, and deferred functions may read and assign to the returning function’s named return values. However, these probably apply more to that compiled environment
It would be useful to have a way of ensuring that clean up happens in tasks that open files or interact with resources that should be tidied up
I was thinking about implementing this simply, by creating a new function in the sched module called
defer
and a table field calleddeferred_tasks
for each task. All the code called in adefer
function would be added to a task, set to paused, that would be added to thedeferred_tasks
table of the parent task. When the parent task ends normally or the underlying coroutine crashes, the scheduler would unpause the tasks added to thedeferred_tasks
table.Would this work and would you consider a pull request that does this?