No more to-be-closed functions
To-be-closed variables must contain objects with '__toclose' metamethods (or nil). Functions were removed for several reasons: * Functions interact badly with sandboxes. If a sandbox raises an error to interrupt a script, a to-be-closed function still can hijack control and continue running arbitrary sandboxed code. * Functions interact badly with coroutines. If a coroutine yields and is never resumed again, its to-be-closed functions will never run. To-be-closed objects, on the other hand, will still be closed, provided they have appropriate finalizers. * If you really need a function, it is easy to create a dummy object to run that function in its '__toclose' metamethod. This comit also adds closing of variables in case of panic.
This commit is contained in:
@@ -142,8 +142,15 @@ do
|
||||
|
||||
-- to-be-closed variables in coroutines
|
||||
local X
|
||||
|
||||
local function func2close (f)
|
||||
return setmetatable({}, {__close = f})
|
||||
end
|
||||
|
||||
co = coroutine.create(function ()
|
||||
local *toclose x = function (err) assert(err == nil); X = false end
|
||||
local *toclose x = func2close(function (self, err)
|
||||
assert(err == nil); X = false
|
||||
end)
|
||||
X = true
|
||||
coroutine.yield()
|
||||
end)
|
||||
@@ -154,7 +161,9 @@ do
|
||||
|
||||
-- error killing a coroutine
|
||||
co = coroutine.create(function()
|
||||
local *toclose x = function (err) assert(err == nil); error(111) end
|
||||
local *toclose x = func2close(function (self, err)
|
||||
assert(err == nil); error(111)
|
||||
end)
|
||||
coroutine.yield()
|
||||
end)
|
||||
coroutine.resume(co)
|
||||
|
||||
Reference in New Issue
Block a user