[gnome-menus] entry-directories: don't modify a list while iterating it
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-menus] entry-directories: don't modify a list while iterating it
- Date: Sat, 14 Dec 2013 16:24:09 +0000 (UTC)
commit 27b7c7100e007764acf56d91dc76474099f3f1b3
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Sat Dec 14 15:16:09 2013 +0100
entry-directories: don't modify a list while iterating it
cached_dir_unref() tries to remove the directory from the parent's
list of subdirectories, but it is also called when the parent is
being freed and iterating with foreach() on its directory list.
This is unsafe, so don't do it.
Also, fix the logic for remove_subdir() to unref() only when it's
right to do so (ie, always, when the function is called, because
everything keeps strong references).
https://bugzilla.gnome.org/show_bug.cgi?id=720460
libmenu/entry-directories.c | 22 ++++++++++++++++------
1 files changed, 16 insertions(+), 6 deletions(-)
---
diff --git a/libmenu/entry-directories.c b/libmenu/entry-directories.c
index 6af3850..52ddfd8 100644
--- a/libmenu/entry-directories.c
+++ b/libmenu/entry-directories.c
@@ -83,6 +83,7 @@ static void cached_dir_free (CachedDir *dir);
static gboolean cached_dir_load_entries_recursive (CachedDir *dir,
const char *dirname);
static void cached_dir_unref (CachedDir *dir);
+static void cached_dir_unref_noparent (CachedDir *dir);
static CachedDir * cached_dir_add_subdir (CachedDir *dir,
const char *basename,
const char *path);
@@ -156,7 +157,7 @@ cached_dir_free (CachedDir *dir)
dir->entries = NULL;
g_slist_foreach (dir->subdirs,
- (GFunc) cached_dir_unref,
+ (GFunc) cached_dir_unref_noparent,
NULL);
g_slist_free (dir->subdirs);
dir->subdirs = NULL;
@@ -191,6 +192,18 @@ cached_dir_unref (CachedDir *dir)
}
}
+static void
+cached_dir_unref_noparent (CachedDir *dir)
+{
+ if (--dir->references == 0)
+ {
+ if (dir->notify)
+ dir->notify (dir, dir->notify_data);
+
+ cached_dir_free (dir);
+ }
+}
+
static inline CachedDir *
find_subdir (CachedDir *dir,
const char *subdir)
@@ -406,11 +419,8 @@ cached_dir_remove_subdir (CachedDir *dir,
{
subdir->deleted = TRUE;
- if (subdir->references == 0)
- {
- cached_dir_unref (subdir);
- dir->subdirs = g_slist_remove (dir->subdirs, subdir);
- }
+ cached_dir_unref (subdir);
+ dir->subdirs = g_slist_remove (dir->subdirs, subdir);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]