From 09eba3e9c6d691fa008bac5252ca89f4bc2295db Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 12 Oct 2009 22:43:19 -0400 Subject: [PATCH 19/21] Add a timeout for QueryStop responses Allow a maximum of 2 seconds before we consider a session as unresponsive. --- src/ck-manager.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 52 insertions(+), 1 deletions(-) diff --git a/src/ck-manager.c b/src/ck-manager.c index ed6bfbb..2f2dce9 100644 --- a/src/ck-manager.c +++ b/src/ck-manager.c @@ -91,6 +91,7 @@ struct CkManagerPrivate GSList *query_sessions; DBusGMethodInvocation *query_context; + guint query_timeout; }; enum { @@ -986,7 +987,20 @@ get_system_num_users (CkManager *manager) static guint get_num_real_inhibitors (CkManager *manager) { - return g_hash_table_size (manager->priv->inhibitors); + guint num; + GHashTableIter iter; + CkInhibitor *inhibitor; + + num = 0; + + g_hash_table_iter_init (&iter, manager->priv->inhibitors); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&inhibitor)) { + if (g_strcmp0 (ck_inhibitor_peek_reason (inhibitor), "Not responding") != 0) { + num += 1; + } + } + + return num; } static gboolean @@ -1662,6 +1676,11 @@ query_stop_complete (CkManager *manager) { const char *action; + if (manager->priv->query_timeout > 0) { + g_source_remove (manager->priv->query_timeout); + manager->priv->query_timeout = 0; + } + #ifdef HAVE_POLKIT if (need_elevated_privileges (manager)) { action = "org.freedesktop.consolekit.system.restart-multiple-users"; @@ -2938,6 +2957,36 @@ ck_manager_get_inhibitors (CkManager *manager, return TRUE; } +static gboolean +on_query_stop_timeout (CkManager *manager) +{ + GSList *l; + + manager->priv->query_timeout = 0; + + for (l = manager->priv->query_sessions; l != NULL; l = l->next) { + CkSession *session = l->data; + CkInhibitor *inhibitor; + guint cookie; + + cookie = generate_unique_inhibitor_cookie (manager); + inhibitor = ck_inhibitor_new_for_session (NULL, + ck_session_peek_id (session), + CK_INHIBITOR_FLAG_SHUTDOWN, + "Not responding", + cookie); + g_hash_table_insert (manager->priv->inhibitors, GINT_TO_POINTER (cookie), inhibitor); + g_signal_emit (manager, signals[INHIBITOR_ADDED], 0, ck_inhibitor_peek_id (inhibitor)); + } + + g_slist_free (manager->priv->query_sessions); + manager->priv->query_sessions = NULL; + + query_stop_complete (manager); + + return FALSE; +} + static void remove_all_session_inhibitors (CkManager *manager) { @@ -2993,6 +3042,8 @@ ck_manager_query_stop (CkManager *manager, /* just in case, remove stale jit inhibitors; there shouldn't be any */ remove_all_session_inhibitors (manager); + manager->priv->query_timeout = g_timeout_add_seconds (2, (GSourceFunc)on_query_stop_timeout, manager); + g_hash_table_iter_init (&iter, manager->priv->sessions); while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&session)) { manager->priv->query_sessions = g_slist_prepend (manager->priv->query_sessions, session); -- 1.6.5.rc2