Add a test case capturing problems with weak_connect_signal (#520)
This adds a cyclic dependency between the function used for the weak signal and an object with a __gc metamethod. The problem occurs since the GC will first finalize the object (call its __gc metamethod) and only in the next generation will it actually collect the garbage and remove the functions from weak-tables using it as a key. And yes this needs special code for Lua 5.1 because there __gc doesn't work on tables. :-( Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
970a92bb51
commit
0fdecfb2df
|
@ -131,6 +131,35 @@ describe("gears.object", function()
|
||||||
obj:weak_connect_signal("signal", cb)
|
obj:weak_connect_signal("signal", cb)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("weak signal is disconnected before __gc runs", function()
|
||||||
|
local finalized = false
|
||||||
|
do
|
||||||
|
local userdata
|
||||||
|
local function callback()
|
||||||
|
error("Signal should already be disconnected")
|
||||||
|
|
||||||
|
-- This should reference the object...
|
||||||
|
print("userdata:", userdata)
|
||||||
|
end
|
||||||
|
obj:weak_connect_signal("signal", callback)
|
||||||
|
|
||||||
|
-- Now create an object and tie its lifetime to the callback
|
||||||
|
local function gc()
|
||||||
|
finalized = true
|
||||||
|
end
|
||||||
|
if _VERSION <= "Lua 5.1" then
|
||||||
|
local userdata = newproxy(true)
|
||||||
|
getmetatable(userdata).__gc = gc
|
||||||
|
getmetatable(userdata).callback = callback
|
||||||
|
else
|
||||||
|
userdata = setmetatable({callback}, { __gc = gc })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
collectgarbage("collect")
|
||||||
|
assert.is_true(finalized)
|
||||||
|
obj:emit_signal("signal")
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||||
|
|
Loading…
Reference in New Issue