diff options
author | Vincent Untz <vuntz@gnome.org> | 2010-04-16 08:59:42 -0400 |
---|---|---|
committer | Vincent Untz <vuntz@gnome.org> | 2010-04-16 08:59:42 -0400 |
commit | 94db910c687b8360d4ffc47921099741dd05244f (patch) | |
tree | 54bcd59ae73c3f9bd0e11e22e01a1a5394810f99 | |
parent | e374f886e6f225375922de8c9f0cf1da8daf4613 (diff) | |
download | gconf-94db910c687b8360d4ffc47921099741dd05244f.tar.gz |
[gsettings] Fix crashes in notification code
-rw-r--r-- | gsettings/gconfsettingsbackend.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/gsettings/gconfsettingsbackend.c b/gsettings/gconfsettingsbackend.c index b8b64583..c8359249 100644 --- a/gsettings/gconfsettingsbackend.c +++ b/gsettings/gconfsettingsbackend.c @@ -36,7 +36,7 @@ typedef struct _GConfSettingsBackendNotifier GConfSettingsBackendNotifier; struct _GConfSettingsBackendPrivate { GConfClient *client; - GList *notifiers; + GSList *notifiers; /* By definition, with GSettings, we can't write to a key if we're not * subscribed to it or its parent. This means we'll be monitoring it, and * that we'll get a change notification for the write. That's something that @@ -54,10 +54,10 @@ struct _GConfSettingsBackendPrivate struct _GConfSettingsBackendNotifier { GConfSettingsBackendNotifier *parent; - gchar *path; - guint refcount; - guint notify_id; - GList *subpaths; + gchar *path; + guint refcount; + guint notify_id; + GSList *subpaths; }; static void @@ -75,7 +75,7 @@ gconf_settings_backend_find_notifier_or_parent (GConfSettingsBackend *gconf, const gchar *path) { GConfSettingsBackendNotifier *parent; - GList *l; + GSList *l; l = gconf->priv->notifiers; parent = NULL; @@ -113,8 +113,8 @@ gconf_settings_backend_free_notifier (GConfSettingsBackendNotifier *notifier, gconf_client_notify_remove (gconf->priv->client, notifier->notify_id); notifier->notify_id = 0; - g_list_foreach (notifier->subpaths, (GFunc) gconf_settings_backend_free_notifier, gconf); - g_list_free (notifier->subpaths); + g_slist_foreach (notifier->subpaths, (GFunc) gconf_settings_backend_free_notifier, gconf); + g_slist_free (notifier->subpaths); notifier->subpaths = NULL; g_slice_free (GConfSettingsBackendNotifier, notifier); @@ -127,8 +127,8 @@ gconf_settings_backend_add_notifier (GConfSettingsBackend *gconf, { GConfSettingsBackendNotifier *n_or_p; GConfSettingsBackendNotifier *notifier; - GList *siblings; - GList *l; + GSList *siblings; + GSList *l; n_or_p = gconf_settings_backend_find_notifier_or_parent (gconf, path); @@ -161,7 +161,7 @@ gconf_settings_backend_add_notifier (GConfSettingsBackend *gconf, while (l != NULL) { GConfSettingsBackendNotifier *sibling; - GList *next; + GSList *next; sibling = l->data; next = l->next; @@ -175,7 +175,7 @@ gconf_settings_backend_add_notifier (GConfSettingsBackend *gconf, sibling->notify_id = 0; } - siblings = g_list_remove_link (siblings, l); + siblings = g_slist_remove_link (siblings, l); l->next = notifier->subpaths; notifier->subpaths = l; } @@ -183,6 +183,8 @@ gconf_settings_backend_add_notifier (GConfSettingsBackend *gconf, l = next; } + siblings = g_slist_prepend (siblings, notifier); + if (notifier->parent) notifier->parent->subpaths = siblings; else @@ -200,7 +202,7 @@ gconf_settings_backend_remove_notifier (GConfSettingsBackend *gconf, notifier = gconf_settings_backend_find_notifier_or_parent (gconf, path); - g_assert (g_str_equal (path, notifier->path)); + g_assert (notifier && g_str_equal (path, notifier->path)); notifier->refcount -= 1; @@ -210,22 +212,37 @@ gconf_settings_backend_remove_notifier (GConfSettingsBackend *gconf, /* Move subpaths to the parent, and add a notify handler for each of them if * they have no parent anymore. */ if (notifier->parent) - notifier->parent->subpaths = g_list_concat (notifier->parent->subpaths, - notifier->subpaths); + { + GSList *l; + + for (l = notifier->subpaths; l != NULL; l = l->next) + { + GConfSettingsBackendNotifier *child = l->data; + child->parent = notifier->parent; + } + + notifier->parent->subpaths = g_slist_remove (notifier->parent->subpaths, + notifier); + notifier->parent->subpaths = g_slist_concat (notifier->parent->subpaths, + notifier->subpaths); + } else { - GList *l; + GSList *l; for (l = notifier->subpaths; l != NULL; l = l->next) { GConfSettingsBackendNotifier *child = l->data; + child->parent = NULL; child->notify_id = gconf_client_notify_add (gconf->priv->client, child->path, (GConfClientNotifyFunc) gconf_settings_backend_notified, gconf, NULL, NULL); } - gconf->priv->notifiers = g_list_concat (gconf->priv->notifiers, - notifier->subpaths); + gconf->priv->notifiers = g_slist_remove (gconf->priv->notifiers, + notifier); + gconf->priv->notifiers = g_slist_concat (gconf->priv->notifiers, + notifier->subpaths); } notifier->subpaths = NULL; @@ -853,8 +870,8 @@ gconf_settings_backend_finalize (GObject *object) { GConfSettingsBackend *gconf = GCONF_SETTINGS_BACKEND (object); - g_list_foreach (gconf->priv->notifiers, (GFunc) gconf_settings_backend_free_notifier, gconf); - g_list_free (gconf->priv->notifiers); + g_slist_foreach (gconf->priv->notifiers, (GFunc) gconf_settings_backend_free_notifier, gconf); + g_slist_free (gconf->priv->notifiers); gconf->priv->notifiers = NULL; g_object_unref (gconf->priv->client); |