|
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