After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 707302 - MetaIdleMonitor: fire immediately watches that are already expired
MetaIdleMonitor: fire immediately watches that are already expired
Status: RESOLVED FIXED
Product: mutter
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: mutter-maint
mutter-maint
Depends on:
Blocks: 707274
 
 
Reported: 2013-09-02 18:46 UTC by Giovanni Campagna
Modified: 2013-09-16 20:39 UTC
See Also:
GNOME target: 3.10
GNOME version: ---


Attachments
MetaIdleMonitor: fire immediately watches that are already expired (1.54 KB, patch)
2013-09-02 18:46 UTC, Giovanni Campagna
none Details | Review
MetaIdleMonitor: fire immediately watches that are already expired (1.91 KB, patch)
2013-09-02 18:54 UTC, Giovanni Campagna
reviewed Details | Review
MetaIdleMonitor: fire immediately watches that are already expired (2.88 KB, patch)
2013-09-16 12:29 UTC, Giovanni Campagna
committed Details | Review

Description Giovanni Campagna 2013-09-02 18:46:34 UTC
The XSync semantics mandate that alarms already expired will not
fire until the counter is reset and the alarm triggered again, so
clients traditionally called get_idle_time() first to see if they
should install the alarm.
This is inherently racy, as by the time the call is handled by
mutter and the reply received the idle time could be different.
Instead, if we see that the watch would have fired in the past,
fire it immediately.

This is a behavior change, but it's a compatible one, as all legacy
clients are calling get_idle_time() first, and it was perfectly
possible for the idle time counter to trigger the alarm right
after the get_idle_time() call.
Comment 1 Giovanni Campagna 2013-09-02 18:46:35 UTC
Created attachment 253898 [details] [review]
MetaIdleMonitor: fire immediately watches that are already expired
Comment 2 Giovanni Campagna 2013-09-02 18:54:17 UTC
Created attachment 253899 [details] [review]
MetaIdleMonitor: fire immediately watches that are already expired

The XSync semantics mandate that alarms already expired will not
fire until the counter is reset and the alarm triggered again, so
clients traditionally called get_idle_time() first to see if they
should install the alarm.
This is inherently racy, as by the time the call is handled by
mutter and the reply received the idle time could be different.
Instead, if we see that the watch would have fired in the past,
fire it immediately.

This is a behavior change, but it's a compatible one, as all legacy
clients are calling get_idle_time() first, and it was perfectly
possible for the idle time counter to trigger the alarm right
after the get_idle_time() call.

Even better, let's send the dbus reply before the signal, otherwise
the client API will not recognize the ID and ignore it.
Comment 3 Ray Strode [halfline] 2013-09-03 12:47:25 UTC
Review of attachment 253899 [details] [review]:

makes sense.

::: src/core/meta-idle-monitor.c
@@ +481,3 @@
+
+      if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec)
+        g_idle_add (fire_watch_idle, watch);

I think it would better to store the idle id on the monitor. So in the wayland case above you create a GSource, maybe it would make sense to use the same source field for this? Then you can avoid dispatching more than once if there's already one queued, and can clean it up in dispose if one is pending.  That has the advantage of not having a struct field sitting around for the non-wayland case that will never get used too.
Comment 4 Giovanni Campagna 2013-09-16 12:22:46 UTC
(In reply to comment #3)
> Review of attachment 253899 [details] [review]:
> 
> makes sense.
> 
> ::: src/core/meta-idle-monitor.c
> @@ +481,3 @@
> +
> +      if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec)
> +        g_idle_add (fire_watch_idle, watch);
> 
> I think it would better to store the idle id on the monitor. So in the wayland
> case above you create a GSource, maybe it would make sense to use the same
> source field for this? Then you can avoid dispatching more than once if there's
> already one queued, and can clean it up in dispose if one is pending.  That has
> the advantage of not having a struct field sitting around for the non-wayland
> case that will never get used too.

I agree with storing the idle id, but not on the GSource, simply because this patch is for the x11 branch, and there is no GSource there.
Comment 5 Giovanni Campagna 2013-09-16 12:29:46 UTC
Created attachment 255020 [details] [review]
 MetaIdleMonitor: fire immediately watches that are already expired

The XSync semantics mandate that alarms already expired will not
fire until the counter is reset and the alarm triggered again, so
clients traditionally called get_idle_time() first to see if they
should install the alarm.
This is inherently racy, as by the time the call is handled by
mutter and the reply received the idle time could be different.
Instead, if we see that the watch would have fired in the past,
fire it immediately.

This is a behavior change, but it's a compatible one, as all legacy
clients are calling get_idle_time() first, and it was perfectly
possible for the idle time counter to trigger the alarm right
after the get_idle_time() call.
Comment 6 Ray Strode [halfline] 2013-09-16 17:24:27 UTC
Review of attachment 255020 [details] [review]:

++
Comment 7 Giovanni Campagna 2013-09-16 20:39:28 UTC
Attachment 255020 [details] pushed as 2fc9e1a - MetaIdleMonitor: fire immediately watches that are already expired