Commit feb1cf50 authored by Lubomir Rintel's avatar Lubomir Rintel Committed by Ray Strode

display-factory: avoid removing a display from store while iterating it

parent 79a7360b
......@@ -35,6 +35,7 @@
struct GdmDisplayFactoryPrivate
{
GdmDisplayStore *display_store;
guint purge_displays_id;
};
enum {
......@@ -59,6 +60,41 @@ gdm_display_factory_error_quark (void)
return ret;
}
static gboolean
purge_display (char *id,
GdmDisplay *display,
gpointer user_data)
{
int status;
status = gdm_display_get_status (display);
switch (status) {
case GDM_DISPLAY_FINISHED:
case GDM_DISPLAY_FAILED:
return TRUE;
default:
return FALSE;
}
}
static void
purge_displays (GdmDisplayFactory *factory)
{
factory->priv->purge_displays_id = 0;
gdm_display_store_foreach_remove (factory->priv->display_store,
(GdmDisplayStoreFunc)purge_display,
NULL);
}
void
gdm_display_factory_queue_purge_displays (GdmDisplayFactory *factory)
{
if (factory->priv->purge_displays_id == 0) {
factory->priv->purge_displays_id = g_idle_add ((GSourceFunc) purge_displays, factory);
}
}
GdmDisplayStore *
gdm_display_factory_get_display_store (GdmDisplayFactory *factory)
{
......@@ -187,5 +223,10 @@ gdm_display_factory_finalize (GObject *object)
g_return_if_fail (factory->priv != NULL);
if (factory->priv->purge_displays_id != 0) {
g_source_remove (factory->priv->purge_displays_id);
factory->priv->purge_displays_id = 0;
}
G_OBJECT_CLASS (gdm_display_factory_parent_class)->finalize (object);
}
......@@ -64,6 +64,7 @@ GType gdm_display_factory_get_type (void);
gboolean gdm_display_factory_start (GdmDisplayFactory *manager);
gboolean gdm_display_factory_stop (GdmDisplayFactory *manager);
GdmDisplayStore * gdm_display_factory_get_display_store (GdmDisplayFactory *manager);
void gdm_display_factory_queue_purge_displays (GdmDisplayFactory *manager);
G_END_DECLS
......
......@@ -249,7 +249,6 @@ on_display_status_changed (GdmDisplay *display,
GdmLocalDisplayFactory *factory)
{
int status;
GdmDisplayStore *store;
int num;
char *seat_id = NULL;
char *session_type = NULL;
......@@ -259,8 +258,6 @@ on_display_status_changed (GdmDisplay *display,
num = -1;
gdm_display_get_x11_display_number (display, &num, NULL);
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
g_object_get (display,
"seat-id", &seat_id,
"is-initial", &is_initial,
......@@ -278,7 +275,7 @@ on_display_status_changed (GdmDisplay *display,
if (num != -1) {
g_hash_table_remove (factory->priv->used_display_numbers, GUINT_TO_POINTER (num));
}
gdm_display_store_remove (store, display);
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory));
/* if this is a local display, do a full resync. Only
* seats without displays will get created anyway. This
......@@ -295,7 +292,7 @@ on_display_status_changed (GdmDisplay *display,
case GDM_DISPLAY_FAILED:
/* leave the display number in factory->priv->used_display_numbers
so that it doesn't get reused */
gdm_display_store_remove (store, display);
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory));
/* Create a new equivalent display if it was static */
if (is_local) {
......
......@@ -2066,15 +2066,12 @@ on_display_status_changed (GdmDisplay *display,
GdmXdmcpDisplayFactory *factory)
{
int status;
GdmDisplayStore *store;
GdmLaunchEnvironment *launch_environment;
GdmSession *session;
GdmAddress *address;
gint32 session_number;
int display_number;
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
launch_environment = NULL;
g_object_get (display, "launch-environment", &launch_environment, NULL);
......@@ -2095,10 +2092,10 @@ on_display_status_changed (GdmDisplay *display,
NULL);
gdm_xdmcp_send_alive (factory, address, display_number, session_number);
gdm_display_store_remove (store, display);
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory));
break;
case GDM_DISPLAY_FAILED:
gdm_display_store_remove (store, display);
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory));
break;
case GDM_DISPLAY_UNMANAGED:
if (session != NULL) {
......
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