gdm r5838 - in trunk: . daemon



Author: mccann
Date: Thu Feb 21 23:08:25 2008
New Revision: 5838
URL: http://svn.gnome.org/viewvc/gdm?rev=5838&view=rev

Log:
2008-02-21  William Jon McCann  <jmccann redhat com>

	* daemon/gdm-display-store.c: (remove_display),
	(gdm_display_store_remove):
	* daemon/gdm-display.c: (gdm_display_add_user_authorization),
	(gdm_display_set_slave_bus_name),
	(gdm_display_remove_user_authorization), (finish_idle),
	(slave_exited), (slave_died), (_gdm_display_set_status),
	(gdm_display_real_manage), (gdm_display_manage),
	(gdm_display_real_finish), (gdm_display_finish),
	(gdm_display_real_unmanage), (gdm_display_set_property),
	(gdm_display_get_property), (gdm_display_dispose),
	(gdm_display_class_init), (gdm_display_init),
	(gdm_display_finalize):
	* daemon/gdm-display.h:
	* daemon/gdm-local-display-factory.c: (take_next_display_number),
	(on_display_disposed), (on_static_display_status_changed),
	(create_display):
	* daemon/gdm-manager.c: (remove_display_for_connection):
	* daemon/gdm-static-display.c: (gdm_static_display_finish):
	Add quick death and looping detection for displays.



Modified:
   trunk/ChangeLog
   trunk/daemon/gdm-display-store.c
   trunk/daemon/gdm-display.c
   trunk/daemon/gdm-display.h
   trunk/daemon/gdm-local-display-factory.c
   trunk/daemon/gdm-manager.c
   trunk/daemon/gdm-static-display.c

Modified: trunk/daemon/gdm-display-store.c
==============================================================================
--- trunk/daemon/gdm-display-store.c	(original)
+++ trunk/daemon/gdm-display-store.c	Thu Feb 21 23:08:25 2008
@@ -73,13 +73,26 @@
         g_hash_table_remove_all (store->priv->displays);
 }
 
+static gboolean
+remove_display (char              *id,
+                GdmDisplay        *display,
+                GdmDisplay        *display_to_remove)
+{
+        if (display == display_to_remove) {
+                return TRUE;
+        }
+        return FALSE;
+}
+
 gboolean
 gdm_display_store_remove (GdmDisplayStore    *store,
                           GdmDisplay         *display)
 {
         g_return_val_if_fail (store != NULL, FALSE);
 
-        g_warning ("GdmDisplayStore: Implement me");
+        gdm_display_store_foreach_remove (store,
+                                          (GdmDisplayStoreFunc)remove_display,
+                                          display);
         return FALSE;
 }
 

Modified: trunk/daemon/gdm-display.c
==============================================================================
--- trunk/daemon/gdm-display.c	(original)
+++ trunk/daemon/gdm-display.c	Thu Feb 21 23:08:25 2008
@@ -43,7 +43,7 @@
 
 #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate))
 
-#define DEFAULT_SLAVE_COMMAND LIBEXECDIR"/gdm-simple-slave"
+#define DEFAULT_SLAVE_COMMAND LIBEXECDIR "/gdm-simple-slave"
 
 struct GdmDisplayPrivate
 {
@@ -55,6 +55,7 @@
         char                 *x11_display_name;
         int                   status;
         time_t                creation_time;
+        GTimer               *slave_timer;
         char                 *slave_command;
 
         char                 *x11_cookie;
@@ -72,6 +73,7 @@
 enum {
         PROP_0,
         PROP_ID,
+        PROP_STATUS,
         PROP_SEAT_ID,
         PROP_REMOTE_HOSTNAME,
         PROP_X11_DISPLAY_NUMBER,
@@ -253,7 +255,7 @@
 
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        g_debug ("Adding authorization for user:%s on display %s", username, display->priv->x11_display_name);
+        g_debug ("GdmDisplay: Adding authorization for user:%s on display %s", username, display->priv->x11_display_name);
 
         g_object_ref (display);
         ret = GDM_DISPLAY_GET_CLASS (display)->add_user_authorization (display, username, filename, error);
@@ -280,7 +282,7 @@
 
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        g_debug ("Setting slave bus name:%s on display %s", name, display->priv->x11_display_name);
+        g_debug ("GdmDisplay: Setting slave bus name:%s on display %s", name, display->priv->x11_display_name);
 
         g_object_ref (display);
         ret = GDM_DISPLAY_GET_CLASS (display)->set_slave_bus_name (display, name, error);
@@ -308,7 +310,7 @@
 
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        g_debug ("Removing authorization for user:%s on display %s", username, display->priv->x11_display_name);
+        g_debug ("GdmDisplay: Removing authorization for user:%s on display %s", username, display->priv->x11_display_name);
 
         g_object_ref (display);
         ret = GDM_DISPLAY_GET_CLASS (display)->remove_user_authorization (display, username, error);
@@ -399,8 +401,9 @@
 static gboolean
 finish_idle (GdmDisplay *display)
 {
-        gdm_display_finish (display);
         display->priv->finish_idle_id = 0;
+        /* finish may end up finalizing object */
+        gdm_display_finish (display);
         return FALSE;
 }
 
@@ -417,7 +420,7 @@
               int                  code,
               GdmDisplay          *display)
 {
-        g_debug ("Slave exited: %d", code);
+        g_debug ("GdmDisplay: Slave exited: %d", code);
 
         queue_finish (display);
 }
@@ -427,11 +430,22 @@
             int                  signum,
             GdmDisplay          *display)
 {
-        g_debug ("Slave died: %d", signum);
+        g_debug ("GdmDisplay: Slave died: %d", signum);
 
         queue_finish (display);
 }
 
+
+static void
+_gdm_display_set_status (GdmDisplay *display,
+                         int         status)
+{
+        if (status != display->priv->status) {
+                display->priv->status = status;
+                g_object_notify (G_OBJECT (display), "status");
+        }
+}
+
 static gboolean
 gdm_display_real_manage (GdmDisplay *display)
 {
@@ -439,7 +453,7 @@
 
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        g_debug ("GdmDisplay manage display");
+        g_debug ("GdmDisplay: manage display");
 
         g_assert (display->priv->slave_proxy == NULL);
 
@@ -449,7 +463,7 @@
                 return FALSE;
         }
 
-        display->priv->status = GDM_DISPLAY_MANAGED;
+        _gdm_display_set_status (display, GDM_DISPLAY_MANAGED);
 
         display->priv->slave_proxy = gdm_slave_proxy_new ();
         g_signal_connect (display->priv->slave_proxy,
@@ -468,6 +482,8 @@
         gdm_slave_proxy_set_command (display->priv->slave_proxy, command);
         g_free (command);
 
+        g_timer_start (display->priv->slave_timer);
+
         gdm_slave_proxy_start (display->priv->slave_proxy);
 
         return TRUE;
@@ -480,7 +496,7 @@
 
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        g_debug ("Managing display: %s", display->priv->id);
+        g_debug ("GdmDisplay: Managing display: %s", display->priv->id);
 
         g_object_ref (display);
         ret = GDM_DISPLAY_GET_CLASS (display)->manage (display);
@@ -494,9 +510,9 @@
 {
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        display->priv->status = GDM_DISPLAY_FINISHED;
+        _gdm_display_set_status (display, GDM_DISPLAY_FINISHED);
 
-        g_debug ("GdmDisplay finish display");
+        g_debug ("GdmDisplay: finish display");
 
         return TRUE;
 }
@@ -508,7 +524,7 @@
 
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        g_debug ("Finishing display: %s", display->priv->id);
+        g_debug ("GdmDisplay: Finishing display: %s", display->priv->id);
 
         g_object_ref (display);
         ret = GDM_DISPLAY_GET_CLASS (display)->finish (display);
@@ -520,12 +536,14 @@
 static gboolean
 gdm_display_real_unmanage (GdmDisplay *display)
 {
-        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+        gdouble elapsed;
 
-        display->priv->status = GDM_DISPLAY_UNMANAGED;
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
         g_debug ("GdmDisplay: unmanage display");
 
+        g_timer_stop (display->priv->slave_timer);
+
         if (display->priv->slave_proxy != NULL) {
                 gdm_slave_proxy_stop (display->priv->slave_proxy);
 
@@ -545,6 +563,14 @@
                 display->priv->access_file = NULL;
         }
 
+        elapsed = g_timer_elapsed (display->priv->slave_timer, NULL);
+        if (elapsed < 10) {
+                g_warning ("GdmDisplay: display lasted %lf seconds", elapsed);
+                _gdm_display_set_status (display, GDM_DISPLAY_FAILED);
+        } else {
+                _gdm_display_set_status (display, GDM_DISPLAY_UNMANAGED);
+        }
+
         return TRUE;
 }
 
@@ -682,6 +708,9 @@
         case PROP_ID:
                 _gdm_display_set_id (self, g_value_get_string (value));
                 break;
+        case PROP_STATUS:
+                _gdm_display_set_status (self, g_value_get_int (value));
+                break;
         case PROP_SEAT_ID:
                 _gdm_display_set_seat_id (self, g_value_get_string (value));
                 break;
@@ -723,6 +752,9 @@
         case PROP_ID:
                 g_value_set_string (value, self->priv->id);
                 break;
+        case PROP_STATUS:
+                g_value_set_int (value, self->priv->status);
+                break;
         case PROP_SEAT_ID:
                 g_value_set_string (value, self->priv->seat_id);
                 break;
@@ -807,13 +839,29 @@
 
         display = GDM_DISPLAY (object);
 
+        g_debug ("GdmDisplay: Disposing display");
+
         if (display->priv->finish_idle_id > 0) {
                 g_source_remove (display->priv->finish_idle_id);
                 display->priv->finish_idle_id = 0;
         }
 
-        g_debug ("GdmDisplay: Disposing display");
-        gdm_display_unmanage (display);
+        if (display->priv->slave_proxy != NULL) {
+                g_object_unref (display->priv->slave_proxy);
+                display->priv->slave_proxy = NULL;
+        }
+
+        if (display->priv->user_access_file != NULL) {
+                gdm_display_access_file_close (display->priv->user_access_file);
+                g_object_unref (display->priv->user_access_file);
+                display->priv->user_access_file = NULL;
+        }
+
+        if (display->priv->access_file != NULL) {
+                gdm_display_access_file_close (display->priv->access_file);
+                g_object_unref (display->priv->access_file);
+                display->priv->access_file = NULL;
+        }
 
         G_OBJECT_CLASS (gdm_display_parent_class)->dispose (object);
 }
@@ -904,6 +952,15 @@
                                                               "slave command",
                                                               DEFAULT_SLAVE_COMMAND,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_STATUS,
+                                         g_param_spec_int ("status",
+                                                           "status",
+                                                           "status",
+                                                           -1,
+                                                           G_MAXINT,
+                                                           GDM_DISPLAY_UNMANAGED,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
         g_type_class_add_private (klass, sizeof (GdmDisplayPrivate));
 
@@ -916,8 +973,8 @@
 
         display->priv = GDM_DISPLAY_GET_PRIVATE (display);
 
-        display->priv->status = GDM_DISPLAY_UNMANAGED;
         display->priv->creation_time = time (NULL);
+        display->priv->slave_timer = g_timer_new ();
 }
 
 static void
@@ -948,5 +1005,9 @@
                 g_object_unref (display->priv->user_access_file);
         }
 
+        if (display->priv->slave_timer != NULL) {
+                g_timer_destroy (display->priv->slave_timer);
+        }
+
         G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object);
 }

Modified: trunk/daemon/gdm-display.h
==============================================================================
--- trunk/daemon/gdm-display.h	(original)
+++ trunk/daemon/gdm-display.h	Thu Feb 21 23:08:25 2008
@@ -37,14 +37,15 @@
 typedef struct GdmDisplayPrivate GdmDisplayPrivate;
 
 typedef enum {
-        GDM_DISPLAY_UNMANAGED,
+        GDM_DISPLAY_UNMANAGED = 0,
         GDM_DISPLAY_MANAGED,
-        GDM_DISPLAY_FINISHED
+        GDM_DISPLAY_FINISHED,
+        GDM_DISPLAY_FAILED,
 } GdmDisplayStatus;
 
 typedef struct
 {
-        GObject           parent;
+        GObject            parent;
         GdmDisplayPrivate *priv;
 } GdmDisplay;
 

Modified: trunk/daemon/gdm-local-display-factory.c
==============================================================================
--- trunk/daemon/gdm-local-display-factory.c	(original)
+++ trunk/daemon/gdm-local-display-factory.c	Thu Feb 21 23:08:25 2008
@@ -51,11 +51,16 @@
 #define HAL_DBUS_DEVICE_INTERFACE               "org.freedesktop.Hal.Device"
 #define SEAT_PCI_DEVICE_CLASS                   3
 
+#define MAX_DISPLAY_FAILURES 5
+
 struct GdmLocalDisplayFactoryPrivate
 {
         DBusGConnection *connection;
         DBusGProxy      *proxy;
         GHashTable      *displays;
+
+        /* FIXME: this needs to be per seat? */
+        guint            num_failures;
 };
 
 enum {
@@ -66,6 +71,8 @@
 static void     gdm_local_display_factory_init          (GdmLocalDisplayFactory      *factory);
 static void     gdm_local_display_factory_finalize      (GObject                     *object);
 
+static GdmDisplay *create_display                       (GdmLocalDisplayFactory      *factory);
+
 static gpointer local_display_factory_object = NULL;
 
 G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY)
@@ -128,7 +135,7 @@
 
         g_debug ("GdmLocalDisplayFactory: Found the following X displays:");
         for (l = list; l != NULL; l = l->next) {
-                g_debug ("%u", GPOINTER_TO_UINT (l->data));
+                g_debug ("GdmLocalDisplayFactory: %u", GPOINTER_TO_UINT (l->data));
         }
 
         for (l = list; l != NULL; l = l->next) {
@@ -159,8 +166,7 @@
 on_display_disposed (GdmLocalDisplayFactory *factory,
                      GdmDisplay             *display)
 {
-        /* remove the display number from accounting */
-
+        g_debug ("GdmLocalDisplayFactory: Display %p disposed", display);
 }
 
 static void
@@ -275,6 +281,57 @@
         return ret;
 }
 
+static void
+on_static_display_status_changed (GdmDisplay             *display,
+                                  GParamSpec             *arg1,
+                                  GdmLocalDisplayFactory *factory)
+{
+        int              status;
+        GdmDisplayStore *store;
+        int              num;
+
+        num = -1;
+        gdm_display_get_x11_display_number (display, &num, NULL);
+        g_assert (num != -1);
+
+        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+
+        status = gdm_display_get_status (display);
+
+        g_debug ("GdmLocalDisplayFactory: static display status changed: %d", status);
+        switch (status) {
+        case GDM_DISPLAY_FINISHED:
+                /* remove the display number from factory->priv->displays
+                   so that it may be reused */
+                g_hash_table_remove (factory->priv->displays, GUINT_TO_POINTER (num));
+                gdm_display_store_remove (store, display);
+                /* reset num failures */
+                factory->priv->num_failures = 0;
+                create_display (factory);
+                break;
+        case GDM_DISPLAY_FAILED:
+                /* leave the display number in factory->priv->displays
+                   so that it doesn't get reused */
+                gdm_display_store_remove (store, display);
+                factory->priv->num_failures++;
+                if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) {
+                        /* oh shit */
+                        g_critical ("GdmLocalDisplayFactory: maximum number of displays failures reached: check Xorg.log for errors");
+                        exit (1);
+                }
+
+                create_display (factory);
+                break;
+        case GDM_DISPLAY_UNMANAGED:
+                break;
+        case GDM_DISPLAY_MANAGED:
+                break;
+        default:
+                g_assert_not_reached ();
+                break;
+        }
+}
+
 static GdmDisplay *
 create_display (GdmLocalDisplayFactory *factory)
 {
@@ -296,6 +353,11 @@
         /* FIXME: don't hardcode seat1? */
         g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
 
+        g_signal_connect (display,
+                          "notify::status",
+                          G_CALLBACK (on_static_display_status_changed),
+                          factory);
+
         store_display (factory, num, display);
 
         /* let store own the ref */

Modified: trunk/daemon/gdm-manager.c
==============================================================================
--- trunk/daemon/gdm-manager.c	(original)
+++ trunk/daemon/gdm-manager.c	Thu Feb 21 23:08:25 2008
@@ -180,7 +180,8 @@
 } RemoveDisplayData;
 
 static gboolean
-remove_display_for_connection (GdmDisplay        *display,
+remove_display_for_connection (char              *id,
+                               GdmDisplay        *display,
                                RemoveDisplayData *data)
 {
         g_assert (display != NULL);

Modified: trunk/daemon/gdm-static-display.c
==============================================================================
--- trunk/daemon/gdm-static-display.c	(original)
+++ trunk/daemon/gdm-static-display.c	Thu Feb 21 23:08:25 2008
@@ -98,13 +98,20 @@
 static gboolean
 gdm_static_display_finish (GdmDisplay *display)
 {
+        int status;
+
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        GDM_DISPLAY_CLASS (gdm_static_display_parent_class)->finish (display);
+        /* Don't call parent's finish since we don't ever
+           want to be put in the FINISHED state */
 
         /* restart static displays */
         gdm_display_unmanage (display);
-        gdm_display_manage (display);
+
+        status = gdm_display_get_status (display);
+        if (status != GDM_DISPLAY_FAILED) {
+                gdm_display_manage (display);
+        }
 
         return TRUE;
 }



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