gnome-session r5363 - in trunk: . gnome-session



Author: vuntz
Date: Tue Mar 24 23:51:10 2009
New Revision: 5363
URL: http://svn.gnome.org/viewvc/gnome-session?rev=5363&view=rev

Log:
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()


Modified:
   trunk/ChangeLog
   trunk/gnome-session/gsm-client.h
   trunk/gnome-session/gsm-manager.c
   trunk/gnome-session/gsm-manager.h
   trunk/gnome-session/gsm-xsmp-client.c

Modified: trunk/gnome-session/gsm-client.h
==============================================================================
--- trunk/gnome-session/gsm-client.h	(original)
+++ trunk/gnome-session/gsm-client.h	Tue Mar 24 23:51:10 2009
@@ -56,7 +56,8 @@
 
 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

Modified: trunk/gnome-session/gsm-manager.c
==============================================================================
--- trunk/gnome-session/gsm-manager.c	(original)
+++ trunk/gnome-session/gsm-manager.c	Tue Mar 24 23:51:10 2009
@@ -99,6 +99,10 @@
         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_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 @@
         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 @@
         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 @@
         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 @@
                 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 @@
 }
 
 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 @@
         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 @@
         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 @@
         /* 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 @@
                                           (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) {

Modified: trunk/gnome-session/gsm-manager.h
==============================================================================
--- trunk/gnome-session/gsm-manager.h	(original)
+++ trunk/gnome-session/gsm-manager.h	Tue Mar 24 23:51:10 2009
@@ -83,6 +83,7 @@
         /* 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;
 

Modified: trunk/gnome-session/gsm-xsmp-client.c
==============================================================================
--- trunk/gnome-session/gsm-xsmp-client.c	(original)
+++ trunk/gnome-session/gsm-xsmp-client.c	Tue Mar 24 23:51:10 2009
@@ -470,7 +470,6 @@
         }
 }
 
-#if 0
 static void
 xsmp_save_yourself_phase2 (GsmClient *client)
 {
@@ -480,7 +479,6 @@
 
         SmsSaveYourselfPhase2 (xsmp->priv->conn);
 }
-#endif
 
 static void
 xsmp_interact (GsmClient *client)
@@ -735,8 +733,7 @@
                   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 @@
                 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;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]