[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Prevent userdata from being marked for garbage collection?
- From: Roberto Ierusalimschy <roberto@...>
- Date: Wed, 4 Jul 2012 17:42:21 -0300
> So I was wondering if there was something like another callback
> metamethod for userdata, e.g. __mark(), that the garbage collector
> calls in order to decide if the userdata should be marked for
> collection.
I guess the following structure does what you want. Specifically,
once the object becomes garbage, it calls a user-defined function
('cancollect', in the example) to check whether the object can be
collected. Only when the answer is 'yes' will it call another specific
function ('collect', in the example) with the object and then actually
release the Lua object. (Note that you cannot use the __gc metamethod of
'myobject', as it will be called once the object becomes gargage; you
must use 'collect' to finalize the object.)
-- Roberto
-------------------------------------------------
local anchor = setmetatable({}, {__mode = "k"})
myobject = {name = "my object"} -- object to be preserved
local function cancollect (obj)
print("may I collect object " .. obj.name .. "?")
return (io.read() == "yes")
end
local function collect (obj)
print("collecting " .. obj.name)
end
local function mksentinel (obj)
local sentinel = {}
setmetatable(sentinel,
{__gc = function (s)
if not cancollect(obj) then
mksentinel(obj)
else
collect(obj)
end
end})
anchor[sentinel] = obj
obj.sentinel = sentinel
end
mksentinel(myobject)
print(1); collectgarbage()
print(2); collectgarbage()
myobject = nil
print(3); collectgarbage()
print(4); collectgarbage()
print(5); collectgarbage()
print(6); collectgarbage()