Blame SOURCES/0004-account-don-t-poll-more-frequently-than-notification.patch

fbd155
From ff98c03c88e53041dcc861de3b3a3351d55297fe Mon Sep 17 00:00:00 2001
fbd155
From: Ray Strode <rstrode@redhat.com>
fbd155
Date: Fri, 9 Nov 2018 10:39:11 -0500
fbd155
Subject: [PATCH 4/4] account: don't poll more frequently than notification
fbd155
 period
fbd155
fbd155
At the moment, if an account has no reason to receive a notification,
fbd155
the account plugin ends up polling continuously, desperately,
fbd155
and unsuccessfully trying to find a reason to notify. That leads
fbd155
to unnecessary CPU utilization.
fbd155
fbd155
The reason is an apparent think-o in the code.  The code tracks
fbd155
the last time a notification was shown, so it knows when to show
fbd155
the next notification later, even if the notification period, or
fbd155
account policy is updated by the admin in the interim.
fbd155
fbd155
The problem is that it's wrong to look at the last notification
fbd155
time if there's no reason to show a notification.  In that case
fbd155
the wakeup is merely to poll updates on the account policy.
fbd155
fbd155
This commit addresses the problem by only looking at the previous
fbd155
notification time, if it was within the current notification period.
fbd155
---
fbd155
 plugins/account/gsd-account-manager.c | 14 +++++++++++---
fbd155
 1 file changed, 11 insertions(+), 3 deletions(-)
fbd155
fbd155
diff --git a/plugins/account/gsd-account-manager.c b/plugins/account/gsd-account-manager.c
fbd155
index ff054edd..b48c0fe8 100644
fbd155
--- a/plugins/account/gsd-account-manager.c
fbd155
+++ b/plugins/account/gsd-account-manager.c
fbd155
@@ -207,65 +207,73 @@ out:
fbd155
 }
fbd155
 
fbd155
 static gboolean
fbd155
 set_policy_number (gint64 *destination,
fbd155
                    gint64  source)
fbd155
 {
fbd155
         if (*destination == source)
fbd155
                 return FALSE;
fbd155
 
fbd155
         *destination = source;
fbd155
         return TRUE;
fbd155
 }
fbd155
 
fbd155
 static gboolean
fbd155
 on_notify_period_elapsed (GsdAccountManager *manager)
fbd155
 {
fbd155
         manager->priv->notify_period_timeout_id = 0;
fbd155
         fetch_password_expiration_policy (manager);
fbd155
         return G_SOURCE_REMOVE;
fbd155
 }
fbd155
 
fbd155
 static void
fbd155
 queue_periodic_timeout (GsdAccountManager *manager)
fbd155
 {
fbd155
         if (manager->priv->notify_period_timeout_id != 0) {
fbd155
                 g_source_remove (manager->priv->notify_period_timeout_id);
fbd155
                 manager->priv->notify_period_timeout_id = 0;
fbd155
         }
fbd155
 
fbd155
         if (manager->priv->notify_period > 0) {
fbd155
-                gint64 already_elapsed_time;
fbd155
+                gint64 seconds_since_last_notification;
fbd155
+                guint seconds_between_notifications;
fbd155
+                guint seconds_until_next_notification;
fbd155
 
fbd155
-                already_elapsed_time = MAX (0, (g_get_monotonic_time () - manager->priv->last_notify_time) / G_USEC_PER_SEC);
fbd155
+                seconds_since_last_notification = MAX (0, (g_get_monotonic_time () - manager->priv->last_notify_time) / G_USEC_PER_SEC);
fbd155
+                seconds_between_notifications = manager->priv->notify_period * 60;
fbd155
 
fbd155
-                manager->priv->notify_period_timeout_id = g_timeout_add_seconds (MAX (0, manager->priv->notify_period * 60 - already_elapsed_time),
fbd155
+                if (seconds_since_last_notification > seconds_between_notifications)
fbd155
+                        seconds_until_next_notification = seconds_between_notifications;
fbd155
+                else
fbd155
+                        seconds_until_next_notification = seconds_between_notifications - seconds_since_last_notification;
fbd155
+
fbd155
+                manager->priv->notify_period_timeout_id = g_timeout_add_seconds (seconds_until_next_notification,
fbd155
                                                                                  (GSourceFunc) on_notify_period_elapsed,
fbd155
                                                                                  manager);
fbd155
         }
fbd155
 }
fbd155
 
fbd155
 static void
fbd155
 on_got_password_expiration_policy (GsdAccountsUser *accounts_user_proxy,
fbd155
                                    GAsyncResult    *res,
fbd155
                                    gpointer         user_data)
fbd155
 {
fbd155
         GsdAccountManager *manager = user_data;
fbd155
         g_autoptr(GError)  error = NULL;
fbd155
         gboolean           succeeded;
fbd155
         gint64             expiration_time;
fbd155
         gint64             last_change_time;
fbd155
         gint64             min_days_between_changes;
fbd155
         gint64             max_days_between_changes;
fbd155
         gint64             days_to_warn;
fbd155
         gint64             days_after_expiration_until_lock;
fbd155
 
fbd155
         gnome_settings_profile_start (NULL);
fbd155
         succeeded = gsd_accounts_user_call_get_password_expiration_policy_finish (accounts_user_proxy,
fbd155
                                                                                   &expiration_time,
fbd155
                                                                                   &last_change_time,
fbd155
                                                                                   &min_days_between_changes,
fbd155
                                                                                   &max_days_between_changes,
fbd155
                                                                                   &days_to_warn,
fbd155
                                                                                   &days_after_expiration_until_lock,
fbd155
                                                                                   res,
fbd155
                                                                                   &error);
fbd155
-- 
fbd155
2.21.0
fbd155