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