awesome/tests/test-leaks.lua
Uli Schlachter da6012da3e Fix memory leak in the default config on screen removal
The default config had tables like mywibox and mywibox[s] was the wibox
that is visible on screen s. When a screen is removed, nothing cleans up
these tables and so the screen and the wibox could not be garbage
collected. The same applies to the layoutbox, taglist etc.

This commit removes the global mywibox table and instead saves it as a
property on the screen. This way, the screen is not explicitly
referenced and when it is removed, the screen, its wibox and all of its
widgets become unreachable and can be garbage collected.

This commit also updates the docs and the tests that referenced things
(mostly the wibox) via mywibox[s] to now use s.mywibox.

Fixes: https://github.com/awesomeWM/awesome/issues/1125
Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-09-30 22:46:51 +02:00

86 lines
2.6 KiB
Lua

-- Some memory leak checks as integration tests.
local runner = require("_runner")
local awful = require("awful")
local cairo = require("lgi").cairo
local create_wibox = require("_wibox_helper").create_wibox
local wibox = require("wibox")
local prepare_for_collect = nil
local function emit_refresh()
awesome.emit_signal("refresh")
end
-- Make the layoutbox in the default config GC'able
for s in screen do
s.mywibox:set_widget(wibox.widget.textbox())
s.mywibox.visible = false
s.mywibox = nil
s.mylayoutbox = nil
end
emit_refresh()
-- Test if some objects can be garbage collected
local function collectable(a, b, c, d, e, f, g, h, last)
assert(last == nil, "got more arguments than supported")
local objs = setmetatable({ a, b, c, d, e, f, g, h }, { __mode = "v" })
a, b, c, d, e, f, g, h = nil, nil, nil, nil, nil, nil, nil, nil -- luacheck: ignore
if prepare_for_collect then
prepare_for_collect()
prepare_for_collect = nil
end
collectgarbage("collect")
collectgarbage("collect")
collectgarbage("collect")
-- Check if the table is now empty
for _, v in pairs(objs) do
print("Some object was not garbage collected!")
error(v)
end
end
-- Use the layoutbox for testing delayed tooltips
local function tooltip_delayed()
local l = awful.widget.layoutbox(1)
local t = l._layoutbox_tooltip
assert(t)
return l, t
end
local function tooltip_now()
local w = wibox.widget.textbox("some textbox")
local t = awful.tooltip({ objects = {w} })
return w, t
end
-- First test some basic widgets
collectable(wibox.widget.base.make_widget())
collectable(wibox.widget.textbox("foo"))
collectable(wibox.layout.fixed.horizontal())
collectable(wibox.layout.align.horizontal())
-- Then some random widgets from awful
collectable(awful.widget.launcher({ image = cairo.ImageSurface(cairo.Format.ARGB32, 20, 20), command = "bash" }))
collectable(awful.widget.prompt())
collectable(wibox.widget.textclock())
collectable(awful.widget.layoutbox(1))
-- Some widgets do things via timer.delayed_call
prepare_for_collect = emit_refresh
collectable(tooltip_delayed())
prepare_for_collect = emit_refresh
collectable(tooltip_now())
prepare_for_collect = emit_refresh
collectable(awful.widget.taglist(1, awful.widget.taglist.filter.all))
prepare_for_collect = emit_refresh
collectable(awful.widget.tasklist(1, awful.widget.tasklist.filter.currenttags))
prepare_for_collect = emit_refresh
collectable(create_wibox())
runner.run_steps({ function() return true end })
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80