Commit 987bb630 authored by Vincent Untz's avatar Vincent Untz Committed by Vincent Untz

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
parent 9f0edb61
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> 2009-03-25 Vincent Untz <vuntz@gnome.org>
s/gdm_client_end_session_response/gsm_client_end_session_response/g s/gdm_client_end_session_response/gsm_client_end_session_response/g
......
...@@ -56,7 +56,8 @@ typedef enum { ...@@ -56,7 +56,8 @@ typedef enum {
typedef enum { typedef enum {
GSM_CLIENT_END_SESSION_FLAG_FORCEFUL = 1 << 0, 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; } GsmClientEndSessionFlag;
struct _GsmClient struct _GsmClient
......
...@@ -99,6 +99,10 @@ struct GsmManagerPrivate ...@@ -99,6 +99,10 @@ struct GsmManagerPrivate
gboolean forceful_logout; gboolean forceful_logout;
GSList *query_clients; GSList *query_clients;
guint query_timeout_id; 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; GtkWidget *inhibit_dialog;
...@@ -138,6 +142,7 @@ static void gsm_manager_init (GsmManager *manager); ...@@ -138,6 +142,7 @@ static void gsm_manager_init (GsmManager *manager);
static void gsm_manager_finalize (GObject *object); static void gsm_manager_finalize (GObject *object);
static gboolean auto_save_is_enabled (GsmManager *manager); static gboolean auto_save_is_enabled (GsmManager *manager);
static void maybe_save_session (GsmManager *manager);
static gpointer manager_object = NULL; static gpointer manager_object = NULL;
...@@ -345,6 +350,9 @@ phase_num_to_name (guint phase) ...@@ -345,6 +350,9 @@ phase_num_to_name (guint phase)
case GSM_MANAGER_PHASE_END_SESSION: case GSM_MANAGER_PHASE_END_SESSION:
name = "END_SESSION"; name = "END_SESSION";
break; break;
case GSM_MANAGER_PHASE_END_SESSION_LAST:
name = "END_SESSION_LAST";
break;
case GSM_MANAGER_PHASE_EXIT: case GSM_MANAGER_PHASE_EXIT:
name = "EXIT"; name = "EXIT";
break; break;
...@@ -370,6 +378,11 @@ end_phase (GsmManager *manager) ...@@ -370,6 +378,11 @@ end_phase (GsmManager *manager)
g_slist_free (manager->priv->query_clients); g_slist_free (manager->priv->query_clients);
manager->priv->query_clients = NULL; 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) { if (manager->priv->phase_timeout_id > 0) {
g_source_remove (manager->priv->phase_timeout_id); g_source_remove (manager->priv->phase_timeout_id);
manager->priv->phase_timeout_id = 0; manager->priv->phase_timeout_id = 0;
...@@ -385,6 +398,7 @@ end_phase (GsmManager *manager) ...@@ -385,6 +398,7 @@ end_phase (GsmManager *manager)
case GSM_MANAGER_PHASE_RUNNING: case GSM_MANAGER_PHASE_RUNNING:
case GSM_MANAGER_PHASE_QUERY_END_SESSION: case GSM_MANAGER_PHASE_QUERY_END_SESSION:
case GSM_MANAGER_PHASE_END_SESSION: case GSM_MANAGER_PHASE_END_SESSION:
case GSM_MANAGER_PHASE_END_SESSION_LAST:
manager->priv->phase++; manager->priv->phase++;
start_phase (manager); start_phase (manager);
break; break;
...@@ -439,6 +453,7 @@ on_phase_timeout (GsmManager *manager) ...@@ -439,6 +453,7 @@ on_phase_timeout (GsmManager *manager)
break; break;
case GSM_MANAGER_PHASE_QUERY_END_SESSION: case GSM_MANAGER_PHASE_QUERY_END_SESSION:
case GSM_MANAGER_PHASE_END_SESSION: case GSM_MANAGER_PHASE_END_SESSION:
case GSM_MANAGER_PHASE_END_SESSION_LAST:
break; break;
case GSM_MANAGER_PHASE_EXIT: case GSM_MANAGER_PHASE_EXIT:
break; break;
...@@ -585,6 +600,66 @@ do_phase_end_session (GsmManager *manager) ...@@ -585,6 +600,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 static gboolean
_client_stop (const char *id, _client_stop (const char *id,
GsmClient *client, GsmClient *client,
...@@ -1084,6 +1159,10 @@ start_phase (GsmManager *manager) ...@@ -1084,6 +1159,10 @@ start_phase (GsmManager *manager)
manager->priv->pending_apps = NULL; manager->priv->pending_apps = NULL;
g_slist_free (manager->priv->query_clients); g_slist_free (manager->priv->query_clients);
manager->priv->query_clients = NULL; 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) { if (manager->priv->query_timeout_id > 0) {
g_source_remove (manager->priv->query_timeout_id); g_source_remove (manager->priv->query_timeout_id);
...@@ -1113,6 +1192,9 @@ start_phase (GsmManager *manager) ...@@ -1113,6 +1192,9 @@ start_phase (GsmManager *manager)
case GSM_MANAGER_PHASE_END_SESSION: case GSM_MANAGER_PHASE_END_SESSION:
do_phase_end_session (manager); do_phase_end_session (manager);
break; break;
case GSM_MANAGER_PHASE_END_SESSION_LAST:
do_phase_end_session_last (manager);
break;
case GSM_MANAGER_PHASE_EXIT: case GSM_MANAGER_PHASE_EXIT:
do_phase_exit (manager); do_phase_exit (manager);
break; break;
...@@ -1645,7 +1727,7 @@ maybe_save_session (GsmManager *manager) ...@@ -1645,7 +1727,7 @@ maybe_save_session (GsmManager *manager)
/* We only allow session saving when session is running or when /* We only allow session saving when session is running or when
* logging out */ * logging out */
if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING && 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; goto out;
} }
...@@ -1724,6 +1806,11 @@ on_client_end_session_response (GsmClient *client, ...@@ -1724,6 +1806,11 @@ on_client_end_session_response (GsmClient *client,
(gpointer)gsm_client_peek_id (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 if (manager->priv->query_clients == NULL
&& gsm_store_size (manager->priv->inhibitors) == 0) { && gsm_store_size (manager->priv->inhibitors) == 0) {
if (manager->priv->query_timeout_id > 0) { if (manager->priv->query_timeout_id > 0) {
......
...@@ -83,6 +83,7 @@ typedef enum { ...@@ -83,6 +83,7 @@ typedef enum {
/* shutting down */ /* shutting down */
GSM_MANAGER_PHASE_QUERY_END_SESSION, GSM_MANAGER_PHASE_QUERY_END_SESSION,
GSM_MANAGER_PHASE_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 GSM_MANAGER_PHASE_EXIT
} GsmManagerPhase; } GsmManagerPhase;
......
...@@ -470,7 +470,6 @@ do_save_yourself (GsmXSMPClient *client, ...@@ -470,7 +470,6 @@ do_save_yourself (GsmXSMPClient *client,
} }
} }
#if 0
static void static void
xsmp_save_yourself_phase2 (GsmClient *client) xsmp_save_yourself_phase2 (GsmClient *client)
{ {
...@@ -480,7 +479,6 @@ xsmp_save_yourself_phase2 (GsmClient *client) ...@@ -480,7 +479,6 @@ xsmp_save_yourself_phase2 (GsmClient *client)
SmsSaveYourselfPhase2 (xsmp->priv->conn); SmsSaveYourselfPhase2 (xsmp->priv->conn);
} }
#endif
static void static void
xsmp_interact (GsmClient *client) xsmp_interact (GsmClient *client)
...@@ -735,8 +733,7 @@ xsmp_end_session (GsmClient *client, ...@@ -735,8 +733,7 @@ xsmp_end_session (GsmClient *client,
guint flags, guint flags,
GError **error) GError **error)
{ {
gboolean forceful; gboolean phase2;
int save_type;
if (GSM_XSMP_CLIENT (client)->priv->conn == NULL) { if (GSM_XSMP_CLIENT (client)->priv->conn == NULL) {
g_set_error (error, g_set_error (error,
...@@ -746,6 +743,14 @@ xsmp_end_session (GsmClient *client, ...@@ -746,6 +743,14 @@ xsmp_end_session (GsmClient *client,
return FALSE; return FALSE;
} }
phase2 = (flags & GSM_CLIENT_END_SESSION_FLAG_LAST);
if (phase2) {
xsmp_save_yourself_phase2 (client);
} else {
gboolean forceful;
int save_type;
forceful = (flags & GSM_CLIENT_END_SESSION_FLAG_FORCEFUL); forceful = (flags & GSM_CLIENT_END_SESSION_FLAG_FORCEFUL);
if (flags & GSM_CLIENT_END_SESSION_FLAG_SAVE) { if (flags & GSM_CLIENT_END_SESSION_FLAG_SAVE) {
...@@ -754,7 +759,10 @@ xsmp_end_session (GsmClient *client, ...@@ -754,7 +759,10 @@ xsmp_end_session (GsmClient *client,
save_type = SmSaveGlobal; 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; return TRUE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment