mirror of
https://github.com/lua/lua.git
synced 2026-01-28 18:35:01 +00:00
Before calling a finalizer, Lua not only checks stack limits, but actually ensures that a minimum number of slots are already allocated for the call. (If it cannot ensure that, it postpones the finalizer.) That avoids finalizers not running due to memory errors that the programmer cannot control.
46 lines
855 B
Lua
46 lines
855 B
Lua
-- track collections
|
|
|
|
|
|
local M = {}
|
|
|
|
-- import list
|
|
local stderr, collectgarbage = io.stderr, collectgarbage
|
|
|
|
-- the debug version of setmetatable does not create any object (such as
|
|
-- a '__metatable' string), and so it is more appropriate to be used in
|
|
-- a finalizer
|
|
local setmetatable = require"debug".setmetatable
|
|
|
|
global none
|
|
|
|
local active = false
|
|
|
|
|
|
-- each time a table is collected, remark it for finalization on next
|
|
-- cycle
|
|
local mt = {}
|
|
function mt.__gc (o)
|
|
stderr:write'.' -- mark progress
|
|
if active then
|
|
setmetatable(o, mt) -- remark object for finalization
|
|
end
|
|
end
|
|
|
|
|
|
function M.start ()
|
|
if not active then
|
|
active = true
|
|
setmetatable({}, mt) -- create initial object
|
|
end
|
|
end
|
|
|
|
|
|
function M.stop ()
|
|
if active then
|
|
active = false
|
|
collectgarbage() -- call finalizer for the last time
|
|
end
|
|
end
|
|
|
|
return M
|