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:
Uli Schlachter 2015-11-19 18:06:58 +01:00 committed by Daniel Hahler
parent 970a92bb51
commit 0fdecfb2df
1 changed files with 29 additions and 0 deletions

View File

@ -131,6 +131,35 @@ describe("gears.object", function()
obj:weak_connect_signal("signal", cb)
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)
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80