diff options
author | Vincent Untz <vuntz@gnome.org> | 2009-03-24 23:51:10 +0000 |
---|---|---|
committer | Vincent Untz <vuntz@src.gnome.org> | 2009-03-24 23:51:10 +0000 |
commit | 987bb6300c7d27fdf050c09aad26091b15ec87b4 (patch) | |
tree | 16914b4a98d7e25d82d3f4c63d2aaaeae7f3e261 | |
parent | 9f0edb6124b49d7b179e0201a665f2ebd2627d75 (diff) | |
download | gnome-session-987bb6300c7d27fdf050c09aad26091b15ec87b4.tar.gz |
Create a END_SESSION_LAST phase during which we handle the clients which
2009-03-25 Vincent Untz <vuntz@gnome.org>
Create a END_SESSION_LAST phase during which we handle the clients
which wanted to be ended last.
For this, we need to keep a list of clients in that case.
* gnome-session/gsm-client.h: add a new
GSM_CLIENT_END_SESSION_FLAG_LAST flag, to tell the client it's running
last.
* gnome-session/gsm-manager.[ch]: (phase_num_to_name): handle new phase
(end_phase): empty the list of clients that wants to be ended last if
it's not a relevant phase. Also handle new phase.
(on_phase_timeout): handle new phase
(_client_end_session_last): new, to tell a client that the session is
being ended. Works like _client_end_session()
(do_phase_end_session_last): prepare the right flags to be used for
each clients via _client_end_session_last(). Note that we don't use all
clients in the session here, but the list of clients that wanted to be
ended last.
We use a 10 seconds timeout for that phase to not block on clients that
don't reply. Also, if there's no client in the session, then save the
session if auto-save is enabled.
(start_phase): empty the list of clients that wants to be ended last if
it's not a relevant phase. Also handle new phase.
(maybe_save_session): make this call valid in END_SESSION_LAST instead
of END_SESSION
(on_client_end_session_response): save the client in a specific list if
it wants to be ended last.
* gnome-session/gsm-xsmp-client.c: (xsmp_save_yourself_phase2):
uncomment
(xsmp_end_session): if the client is running last, then it means it's
phase2 of SaveYourself, so use xsmp_save_yourself_phase2()
svn path=/trunk/; revision=5363
-rw-r--r-- | ChangeLog | 33 | ||||
-rw-r--r-- | gnome-session/gsm-client.h | 3 | ||||
-rw-r--r-- | gnome-session/gsm-manager.c | 89 | ||||
-rw-r--r-- | gnome-session/gsm-manager.h | 1 | ||||
-rw-r--r-- | gnome-session/gsm-xsmp-client.c | 26 |
5 files changed, 141 insertions, 11 deletions
@@ -1,5 +1,38 @@ 2009-03-25 Vincent Untz <vuntz@gnome.org> + Create a END_SESSION_LAST phase during which we handle the clients + which wanted to be ended last. + For this, we need to keep a list of clients in that case. + + * gnome-session/gsm-client.h: add a new + GSM_CLIENT_END_SESSION_FLAG_LAST flag, to tell the client it's running + last. + * gnome-session/gsm-manager.[ch]: (phase_num_to_name): handle new phase + (end_phase): empty the list of clients that wants to be ended last if + it's not a relevant phase. Also handle new phase. + (on_phase_timeout): handle new phase + (_client_end_session_last): new, to tell a client that the session is + being ended. Works like _client_end_session() + (do_phase_end_session_last): prepare the right flags to be used for + each clients via _client_end_session_last(). Note that we don't use all + clients in the session here, but the list of clients that wanted to be + ended last. + We use a 10 seconds timeout for that phase to not block on clients that + don't reply. Also, if there's no client in the session, then save the + session if auto-save is enabled. + (start_phase): empty the list of clients that wants to be ended last if + it's not a relevant phase. Also handle new phase. + (maybe_save_session): make this call valid in END_SESSION_LAST instead + of END_SESSION + (on_client_end_session_response): save the client in a specific list if + it wants to be ended last. + * gnome-session/gsm-xsmp-client.c: (xsmp_save_yourself_phase2): + uncomment + (xsmp_end_session): if the client is running last, then it means it's + phase2 of SaveYourself, so use xsmp_save_yourself_phase2() + +2009-03-25 Vincent Untz <vuntz@gnome.org> + s/gdm_client_end_session_response/gsm_client_end_session_response/g * gnome-session/gsm-client.c: (gsm_client_end_session_response): diff --git a/gnome-session/gsm-client.h b/gnome-session/gsm-client.h index afea62e4..8fa28ad4 100644 --- a/gnome-session/gsm-client.h +++ b/gnome-session/gsm-client.h @@ -56,7 +56,8 @@ typedef enum { typedef enum { GSM_CLIENT_END_SESSION_FLAG_FORCEFUL = 1 << 0, - GSM_CLIENT_END_SESSION_FLAG_SAVE = 1 << 1 + GSM_CLIENT_END_SESSION_FLAG_SAVE = 1 << 1, + GSM_CLIENT_END_SESSION_FLAG_LAST = 1 << 2 } GsmClientEndSessionFlag; struct _GsmClient diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c index 12c14e88..691c7b48 100644 --- a/gnome-session/gsm-manager.c +++ b/gnome-session/gsm-manager.c @@ -99,6 +99,10 @@ struct GsmManagerPrivate gboolean forceful_logout; GSList *query_clients; guint query_timeout_id; + /* This is used for GSM_MANAGER_PHASE_END_SESSION_LAST only at the + * moment, since it uses a sublist of all running client that replied + * in a specific way */ + GSList *next_query_clients; GtkWidget *inhibit_dialog; @@ -138,6 +142,7 @@ static void gsm_manager_init (GsmManager *manager); static void gsm_manager_finalize (GObject *object); static gboolean auto_save_is_enabled (GsmManager *manager); +static void maybe_save_session (GsmManager *manager); static gpointer manager_object = NULL; @@ -345,6 +350,9 @@ phase_num_to_name (guint phase) case GSM_MANAGER_PHASE_END_SESSION: name = "END_SESSION"; break; + case GSM_MANAGER_PHASE_END_SESSION_LAST: + name = "END_SESSION_LAST"; + break; case GSM_MANAGER_PHASE_EXIT: name = "EXIT"; break; @@ -370,6 +378,11 @@ end_phase (GsmManager *manager) g_slist_free (manager->priv->query_clients); manager->priv->query_clients = NULL; + if (manager->priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) { + g_slist_free (manager->priv->next_query_clients); + manager->priv->next_query_clients = NULL; + } + if (manager->priv->phase_timeout_id > 0) { g_source_remove (manager->priv->phase_timeout_id); manager->priv->phase_timeout_id = 0; @@ -385,6 +398,7 @@ end_phase (GsmManager *manager) case GSM_MANAGER_PHASE_RUNNING: case GSM_MANAGER_PHASE_QUERY_END_SESSION: case GSM_MANAGER_PHASE_END_SESSION: + case GSM_MANAGER_PHASE_END_SESSION_LAST: manager->priv->phase++; start_phase (manager); break; @@ -439,6 +453,7 @@ on_phase_timeout (GsmManager *manager) break; case GSM_MANAGER_PHASE_QUERY_END_SESSION: case GSM_MANAGER_PHASE_END_SESSION: + case GSM_MANAGER_PHASE_END_SESSION_LAST: break; case GSM_MANAGER_PHASE_EXIT: break; @@ -586,6 +601,66 @@ do_phase_end_session (GsmManager *manager) } static gboolean +_client_end_session_last (GsmClient *client, + ClientEndSessionData *data) +{ + gboolean ret; + GError *error; + + error = NULL; + ret = gsm_client_end_session (client, data->flags, &error); + if (! ret) { + g_warning ("Unable to query client: %s", error->message); + g_error_free (error); + /* FIXME: what should we do if we can't communicate with client? */ + } else { + g_debug ("GsmManager: adding client to end-session-last clients: %s", gsm_client_peek_id (client)); + data->manager->priv->query_clients = g_slist_prepend (data->manager->priv->query_clients, + client); + } + + return FALSE; +} + +static void +do_phase_end_session_last (GsmManager *manager) +{ + ClientEndSessionData data; + + data.manager = manager; + data.flags = 0; + + if (manager->priv->forceful_logout) { + data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL; + } + if (auto_save_is_enabled (manager)) { + data.flags |= GSM_CLIENT_END_SESSION_FLAG_SAVE; + } + data.flags |= GSM_CLIENT_END_SESSION_FLAG_LAST; + + if (manager->priv->phase_timeout_id > 0) { + g_source_remove (manager->priv->phase_timeout_id); + manager->priv->phase_timeout_id = 0; + } + + if (g_slist_length (manager->priv->next_query_clients) > 0) { + manager->priv->phase_timeout_id = g_timeout_add_seconds (10, + (GSourceFunc)on_phase_timeout, + manager); + + g_slist_foreach (manager->priv->next_query_clients, + (GFunc)_client_end_session_last, + &data); + } else { + if (data.flags & GSM_CLIENT_END_SESSION_FLAG_SAVE) { + maybe_save_session (manager); + } + + end_phase (manager); + } +} + +static gboolean _client_stop (const char *id, GsmClient *client, gpointer user_data) @@ -1084,6 +1159,10 @@ start_phase (GsmManager *manager) manager->priv->pending_apps = NULL; g_slist_free (manager->priv->query_clients); manager->priv->query_clients = NULL; + if (manager->priv->phase < GSM_MANAGER_PHASE_END_SESSION) { + g_slist_free (manager->priv->next_query_clients); + manager->priv->next_query_clients = NULL; + } if (manager->priv->query_timeout_id > 0) { g_source_remove (manager->priv->query_timeout_id); @@ -1113,6 +1192,9 @@ start_phase (GsmManager *manager) case GSM_MANAGER_PHASE_END_SESSION: do_phase_end_session (manager); break; + case GSM_MANAGER_PHASE_END_SESSION_LAST: + do_phase_end_session_last (manager); + break; case GSM_MANAGER_PHASE_EXIT: do_phase_exit (manager); break; @@ -1645,7 +1727,7 @@ maybe_save_session (GsmManager *manager) /* We only allow session saving when session is running or when * logging out */ if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING && - manager->priv->phase != GSM_MANAGER_PHASE_END_SESSION) { + manager->priv->phase != GSM_MANAGER_PHASE_END_SESSION_LAST) { goto out; } @@ -1724,6 +1806,11 @@ on_client_end_session_response (GsmClient *client, (gpointer)gsm_client_peek_id (client)); } + if (do_last) { + manager->priv->next_query_clients = g_slist_prepend (manager->priv->next_query_clients, + client); + } + if (manager->priv->query_clients == NULL && gsm_store_size (manager->priv->inhibitors) == 0) { if (manager->priv->query_timeout_id > 0) { diff --git a/gnome-session/gsm-manager.h b/gnome-session/gsm-manager.h index 17c70b38..1226ba03 100644 --- a/gnome-session/gsm-manager.h +++ b/gnome-session/gsm-manager.h @@ -83,6 +83,7 @@ typedef enum { /* shutting down */ GSM_MANAGER_PHASE_QUERY_END_SESSION, GSM_MANAGER_PHASE_END_SESSION, + GSM_MANAGER_PHASE_END_SESSION_LAST, /* for apps that want to be done after all other apps */ GSM_MANAGER_PHASE_EXIT } GsmManagerPhase; diff --git a/gnome-session/gsm-xsmp-client.c b/gnome-session/gsm-xsmp-client.c index 544f0f8a..bbd1f91f 100644 --- a/gnome-session/gsm-xsmp-client.c +++ b/gnome-session/gsm-xsmp-client.c @@ -470,7 +470,6 @@ do_save_yourself (GsmXSMPClient *client, } } -#if 0 static void xsmp_save_yourself_phase2 (GsmClient *client) { @@ -480,7 +479,6 @@ xsmp_save_yourself_phase2 (GsmClient *client) SmsSaveYourselfPhase2 (xsmp->priv->conn); } -#endif static void xsmp_interact (GsmClient *client) @@ -735,8 +733,7 @@ xsmp_end_session (GsmClient *client, guint flags, GError **error) { - gboolean forceful; - int save_type; + gboolean phase2; if (GSM_XSMP_CLIENT (client)->priv->conn == NULL) { g_set_error (error, @@ -746,15 +743,26 @@ xsmp_end_session (GsmClient *client, return FALSE; } - forceful = (flags & GSM_CLIENT_END_SESSION_FLAG_FORCEFUL); + phase2 = (flags & GSM_CLIENT_END_SESSION_FLAG_LAST); - if (flags & GSM_CLIENT_END_SESSION_FLAG_SAVE) { - save_type = SmSaveBoth; + if (phase2) { + xsmp_save_yourself_phase2 (client); } else { - save_type = SmSaveGlobal; + gboolean forceful; + int save_type; + + forceful = (flags & GSM_CLIENT_END_SESSION_FLAG_FORCEFUL); + + if (flags & GSM_CLIENT_END_SESSION_FLAG_SAVE) { + save_type = SmSaveBoth; + } else { + save_type = SmSaveGlobal; + } + + do_save_yourself (GSM_XSMP_CLIENT (client), + save_type, forceful); } - do_save_yourself (GSM_XSMP_CLIENT (client), save_type, forceful); return TRUE; } |