[gnome-session] add new phase: GSM_MANAGER_PHASE_EARLY_INITIALIZATION



commit 3e8f8d083686d49fd866a582a5895ba834227685
Author: Alban Crequy <alban crequy collabora co uk>
Date:   Mon Aug 19 21:13:45 2013 +0100

    add new phase: GSM_MANAGER_PHASE_EARLY_INITIALIZATION
    
    gnome-initial-setup-copy-worker and gnome-keyring (and others) used to be
    started automatically by the session manager during the
    GSM_MANAGER_PHASE_INITIALIZATION phase. This is racy because gnome-keyring
    could read its file ~/.local/share/keyrings/login.keyring before it is written
    by gnome-initial-setup-copy-worker. The correct solution is to wait
    gnome-initial-setup-copy-worker finishes before starting other components in
    the initialization phase.
    
    I want to enforce this order without adding knowledge of gnome-initial-setup in
    gnome-keyring and others. It must also work on systems which don't use
    gnome-initial-setup. So I don't use a flag file in gnome-keyring's
    AutostartCondition to delay its startup.
    
    Instead, I add a new phase GSM_MANAGER_PHASE_EARLY_INITIALIZATION before the
    initialization phase. If no autostart desktop files use that phase,
    gnome-session will just go on to the next phase. But if
    gnome-initial-setup-copy-worker uses this new phase, it will ensure
    gnome-initial-setup-copy-worker finishes before the newly installed files in
    $HOME are read by anyone.
    
    Relevent documentation:
    https://wiki.gnome.org/SessionManagement
    http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
    http://lists.freedesktop.org/archives/xdg/2007-January/007436.html
    
    https://bugzilla.gnome.org/show_bug.cgi?id=706692

 gnome-session/README              |   12 ++++++++----
 gnome-session/gsm-autostart-app.c |    4 +++-
 gnome-session/gsm-manager.c       |   10 ++++++++--
 gnome-session/gsm-manager.h       |    2 ++
 4 files changed, 21 insertions(+), 7 deletions(-)
---
diff --git a/gnome-session/README b/gnome-session/README
index 99ccc43..5da6e3d 100644
--- a/gnome-session/README
+++ b/gnome-session/README
@@ -9,16 +9,20 @@ and session files to create a list of GsmApps to be started.
 (GsmAppAutostart represents an autostarted app, and GsmAppResumed
 represents an app resumed from the previous saved session.)
 
-Startup is divided into 6 phases (GsmManagerPhase):
+Startup is divided into 7 phases (GsmManagerPhase):
 
     * GSM_MANAGER_PHASE_STARTUP covers gnome-session's internal
       startup, which also includes starting gconfd and dbus-daemon (if
       it's not already running). Gnome-session starts up those
       explicitly because it needs them for its own purposes.
 
-    * GSM_MANAGER_PHASE_INITIALIZATION is the first phase of "normal"
-      startup (ie, startup controlled by .desktop files rather than
-      hardcoding). It covers low-level stuff like
+    * GSM_MANAGER_PHASE_EARLY_INITIALIZATION is the first phase of
+      "normal" startup (ie, startup controlled by .desktop files
+      rather than hardcoding). It covers the possible installation of
+      files in $HOME by gnome-initial-setup and must be done before
+      other components such as gnome-keyring use those files.
+
+    * GSM_MANAGER_PHASE_INITIALIZATION covers low-level stuff like
       gnome-settings-daemon and at-spi-registryd, that need to be
       running very early (before any windows are displayed).
 
diff --git a/gnome-session/gsm-autostart-app.c b/gnome-session/gsm-autostart-app.c
index f90e528..c6c2c31 100644
--- a/gnome-session/gsm-autostart-app.c
+++ b/gnome-session/gsm-autostart-app.c
@@ -608,7 +608,9 @@ load_desktop_file (GsmAutostartApp  *app)
         phase_str = g_desktop_app_info_get_string (app->priv->app_info,
                                                    GSM_AUTOSTART_APP_PHASE_KEY);
         if (phase_str != NULL) {
-                if (strcmp (phase_str, "Initialization") == 0) {
+                if (strcmp (phase_str, "EarlyInitialization") == 0) {
+                        phase = GSM_MANAGER_PHASE_EARLY_INITIALIZATION;
+                } else if (strcmp (phase_str, "Initialization") == 0) {
                         phase = GSM_MANAGER_PHASE_INITIALIZATION;
                 } else if (strcmp (phase_str, "WindowManager") == 0) {
                         phase = GSM_MANAGER_PHASE_WINDOW_MANAGER;
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index 351d628..572dd37 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -448,6 +448,9 @@ phase_num_to_name (guint phase)
         case GSM_MANAGER_PHASE_STARTUP:
                 name = "STARTUP";
                 break;
+        case GSM_MANAGER_PHASE_EARLY_INITIALIZATION:
+                name = "EARLY_INITIALIZATION";
+                break;
         case GSM_MANAGER_PHASE_INITIALIZATION:
                 name = "INITIALIZATION";
                 break;
@@ -549,6 +552,7 @@ end_phase (GsmManager *manager)
 
         switch (manager->priv->phase) {
         case GSM_MANAGER_PHASE_STARTUP:
+        case GSM_MANAGER_PHASE_EARLY_INITIALIZATION:
         case GSM_MANAGER_PHASE_INITIALIZATION:
         case GSM_MANAGER_PHASE_WINDOW_MANAGER:
         case GSM_MANAGER_PHASE_PANEL:
@@ -696,6 +700,7 @@ on_phase_timeout (GsmManager *manager)
 
         switch (manager->priv->phase) {
         case GSM_MANAGER_PHASE_STARTUP:
+        case GSM_MANAGER_PHASE_EARLY_INITIALIZATION:
         case GSM_MANAGER_PHASE_INITIALIZATION:
         case GSM_MANAGER_PHASE_WINDOW_MANAGER:
         case GSM_MANAGER_PHASE_PANEL:
@@ -1535,6 +1540,7 @@ start_phase (GsmManager *manager)
 
         switch (manager->priv->phase) {
         case GSM_MANAGER_PHASE_STARTUP:
+        case GSM_MANAGER_PHASE_EARLY_INITIALIZATION:
         case GSM_MANAGER_PHASE_INITIALIZATION:
         case GSM_MANAGER_PHASE_WINDOW_MANAGER:
         case GSM_MANAGER_PHASE_PANEL:
@@ -1601,7 +1607,7 @@ debug_app_summary (GsmManager *manager)
         guint phase;
 
         g_debug ("GsmManager: App startup summary");
-        for (phase = GSM_MANAGER_PHASE_INITIALIZATION; phase < GSM_MANAGER_PHASE_RUNNING; phase++) {
+        for (phase = GSM_MANAGER_PHASE_EARLY_INITIALIZATION; phase < GSM_MANAGER_PHASE_RUNNING; phase++) {
                 g_debug ("GsmManager: Phase %s", phase_num_to_name (phase));
                 gsm_store_foreach (manager->priv->apps,
                                    (GsmStoreFunc)_debug_app_for_phase,
@@ -1617,7 +1623,7 @@ gsm_manager_start (GsmManager *manager)
         g_return_if_fail (GSM_IS_MANAGER (manager));
 
         gsm_xsmp_server_start (manager->priv->xsmp_server);
-        gsm_manager_set_phase (manager, GSM_MANAGER_PHASE_INITIALIZATION);
+        gsm_manager_set_phase (manager, GSM_MANAGER_PHASE_EARLY_INITIALIZATION);
         debug_app_summary (manager);
         start_phase (manager);
 }
diff --git a/gnome-session/gsm-manager.h b/gnome-session/gsm-manager.h
index 1957851..e60a3a2 100644
--- a/gnome-session/gsm-manager.h
+++ b/gnome-session/gsm-manager.h
@@ -69,6 +69,8 @@ typedef struct
 typedef enum {
         /* gsm's own startup/initialization phase */
         GSM_MANAGER_PHASE_STARTUP = 0,
+        /* gnome-initial-setup */
+        GSM_MANAGER_PHASE_EARLY_INITIALIZATION,
         /* xrandr setup, gnome-settings-daemon, etc */
         GSM_MANAGER_PHASE_INITIALIZATION,
         /* window/compositing managers */


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