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

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