Fix idle monitor watch leak
When an idle monitor watch is added and then removed by application, it is possible that watch->dead is marked when on_watch_added() is running. However, in this condition libgnome-desktop does not actually remove this watch in upstream (meta). This idle monitor watch leak may affect the performance of mutter when it has been running for a few days.
Background
I have noticed that the performance of gnome-shell degrades a lot (stuttering mouse cursor, etc.) after running for some days. Recently I found some time and did some debugging. By using gcore
as is mentioned by gnome-shell#62, I find that the glib main context "sources" GHashTable
is flooded by thousands of "[mutter] Idle monitor"
, and all of them are created by gsd-power
and gnome-session-binary
by dbus. To validate that too many sources slows down gnome-shell, I wrote a testing program creating 10000 idle watches (by dbus) and it confirmed my idea.
(I put some code snippets about analyzing coredump and flooding watches by dbus in GitHub Gist for anyone interested in).
I have checked the source code of gnome-settings-daemon and gnome-session, and it looks like that they are not leaking idle watches themselves. They all use gnome_idle_monitor_add_idle_watch()
and gnome_idle_monitor_remove_watch()
provided by (lib)gnome-desktop. After debugging by inserting g_warning()
to on_watch_added()
and gnome_idle_monitor_remove_watch()
, I found that the idle watch is actually not removed in mutter when watch->dead
condition is met (on my computer, this happens 309 times for 3 hours in gsd-power
).
And it looks easy to fix, thus I submitted this MR.