Codebase list cinnamon-menus / d13a994
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 Giovanni Campagna authored 10 years ago Clement Lefebvre committed 6 years ago
1 changed file(s) with 16 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
8383 static gboolean cached_dir_load_entries_recursive (CachedDir *dir,
8484 const char *dirname);
8585 static void cached_dir_unref (CachedDir *dir);
86 static void cached_dir_unref_noparent (CachedDir *dir);
8687 static CachedDir * cached_dir_add_subdir (CachedDir *dir,
8788 const char *basename,
8889 const char *path);
156157 dir->entries = NULL;
157158
158159 g_slist_foreach (dir->subdirs,
159 (GFunc) cached_dir_unref,
160 (GFunc) cached_dir_unref_noparent,
160161 NULL);
161162 g_slist_free (dir->subdirs);
162163 dir->subdirs = NULL;
187188 if (parent != NULL)
188189 cached_dir_remove_subdir (parent, dir->name);
189190
191 if (dir->notify)
192 dir->notify (dir, dir->notify_data);
193
194 cached_dir_free (dir);
195 }
196 }
197
198 static void
199 cached_dir_unref_noparent (CachedDir *dir)
200 {
201 if (--dir->references == 0)
202 {
190203 if (dir->notify)
191204 dir->notify (dir, dir->notify_data);
192205
419432 {
420433 subdir->deleted = TRUE;
421434
422 if (subdir->references == 0)
423 {
424 cached_dir_unref (subdir);
425 dir->subdirs = g_slist_remove (dir->subdirs, subdir);
426 }
435 cached_dir_unref (subdir);
436 dir->subdirs = g_slist_remove (dir->subdirs, subdir);
427437
428438 return TRUE;
429439 }