[gconf] [gsettings] Fix crashes in notification code
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gconf] [gsettings] Fix crashes in notification code
- Date: Fri, 16 Apr 2010 13:10:48 +0000 (UTC)
commit 94db910c687b8360d4ffc47921099741dd05244f
Author: Vincent Untz <vuntz gnome org>
Date: Fri Apr 16 08:59:42 2010 -0400
[gsettings] Fix crashes in notification code
gsettings/gconfsettingsbackend.c | 57 ++++++++++++++++++++++++-------------
1 files changed, 37 insertions(+), 20 deletions(-)
---
diff --git a/gsettings/gconfsettingsbackend.c b/gsettings/gconfsettingsbackend.c
index b8b6458..c835924 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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]