Am 03.05.2014 18:37 schröbte Karel Tuma:
I know, I know, it is evil thing to do and I agree it is bad idea for
regular code. But hear me out:
local weak = setmetatable({}, {__mode="v"})
local resmt = {A}
function resmt.__gc(v)
print("resurrecting")
-- note that re-requesting finalizer is explicit like this
weak.x = setmetatable(v, resmt)
end
weak.x = setmetatable({}, resmt)
for i=1,10 do
collectgarbage()
end
assert(weak.x)
I would split your object into two parts: One frontend handle, and one
backend stored via `luaL_ref` in the registry. The frontend handle (Lua
table in 5.2, proxy userdata in 5.1) forwards all calls the the real
thing and has a __gc that checks for reachability on "the other side".
If you are still reachable over there, you create a _new_ frontend
handle and put it into your weak table for the next garbage collection
run to check again. In case you aren't reachable on the other side
either, you `luaL_unref` the backend userdata, which will be collected
eventually.
But maybe it's better to do your own periodic reachability checks (e.g.
every 100th time you receive an RPC) instead of using Lua's GC for that
-- depending on the circumstances Lua's GC might run more frequently (or
less frequently) than you'd like ...
HTH, Philipp