Do not use ctx:iteration() as it causes a Lua Stack Dump

Whenever `ctx:iteration()` is called, when the PropertiesChanges signal is
emitted, awesome reports a problem with data left in the Lua stack:

```
2017-04-11 07:08:52 W: awesome: a_glib_poll:372: Something was left on the Lua stack, this is a bug!
-------- Lua stack dump ---------
3: nil
2: userdata     #16     0x2251a78
1: userdata     #320    0x27c5408
------- Lua stack dump end ------
```

This may eventually result in crashes or freezes. To fix the problem, don't use
the GLib context, instead:

- grab all properties from the proxy and copy them over into a table
- use that table as the data for the widget
- update the table when the PropertiesChanged signal is emitted
This commit is contained in:
Stefano Mazzucco 2017-04-11 08:54:14 +01:00
parent e7b5727d40
commit 4ddc1f5820
1 changed files with 21 additions and 4 deletions

View File

@ -21,7 +21,6 @@ local wibox = require("wibox")
local awful = require("awful") local awful = require("awful")
local naughty = require("naughty") local naughty = require("naughty")
local GLib = require("lgi").GLib
local power = require("upower_dbus") local power = require("upower_dbus")
-- Awesome DBus C API -- Awesome DBus C API
@ -35,7 +34,6 @@ local icon_theme_extensions = {"svg"}
icon_theme_dirs = beautiful.upower_icon_theme_dirs or icon_theme_dirs icon_theme_dirs = beautiful.upower_icon_theme_dirs or icon_theme_dirs
icon_theme_extensions = beautiful.upower_icon_theme_extension or icon_theme_extensions icon_theme_extensions = beautiful.upower_icon_theme_extension or icon_theme_extensions
local ctx = GLib.MainLoop():get_context()
local widget = wibox.widget.imagebox() local widget = wibox.widget.imagebox()
local function build_icon_path(device) local function build_icon_path(device)
@ -89,13 +87,32 @@ local function setup_signals(wdg)
and interface == wdg.device.interface and interface == wdg.device.interface
and info.path == wdg.device.object_path and info.path == wdg.device.object_path
then then
ctx:iteration() for k, v in pairs(changed) do
wdg.device[k] = v
end
wdg:update() wdg:update()
end end
end) end)
end end
end end
-- Although it would be nice to use ctx = lgi.GLib.MainLoop:get_context() and
-- then ctx:iteration() to update the proxy object, this causes a Lua Stack
-- Dump in awesome. You will see a line saying "Something was left on the Lua
-- stack, this is a bug!" in the stderr. Instead, copy over the values in a
-- simple table and to be used when PropertiesChanged is emitted.
local function get_data(device)
device = device or {}
local out = {}
for k, v in pairs(device) do
out[k] = v
end
for k, _ in pairs(device.accessors) do
out[k] = device[k]
end
return out
end
function widget:init() function widget:init()
local manager = power.Manager local manager = power.Manager
self.manager = manager self.manager = manager
@ -104,7 +121,7 @@ function widget:init()
for _, d in ipairs(self.manager.devices) do for _, d in ipairs(self.manager.devices) do
devices[d.type] = d devices[d.type] = d
end end
self.device = devices["Battery"] or devices["Line Power"] self.device = get_data(devices["Battery"] or devices["Line Power"])
self.tooltip = awful.tooltip({ objects = { widget },}) self.tooltip = awful.tooltip({ objects = { widget },})
self.gui_client = "" self.gui_client = ""