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

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