summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Untz <vuntz@gnome.org>2009-03-24 23:51:10 +0000
committerVincent Untz <vuntz@src.gnome.org>2009-03-24 23:51:10 +0000
commit987bb6300c7d27fdf050c09aad26091b15ec87b4 (patch)
tree16914b4a98d7e25d82d3f4c63d2aaaeae7f3e261
parent9f0edb6124b49d7b179e0201a665f2ebd2627d75 (diff)
downloadgnome-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--ChangeLog33
-rw-r--r--gnome-session/gsm-client.h3
-rw-r--r--gnome-session/gsm-manager.c89
-rw-r--r--gnome-session/gsm-manager.h1
-rw-r--r--gnome-session/gsm-xsmp-client.c26
5 files changed, 141 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 36b7e5b3..0e2d8d26 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;
}