Package list cinnamon-menus / 81b3bc6
Memory leak fixes This time, with less crashes. Jasper St. Pierre authored 7 years ago Clement Lefebvre committed 3 years ago
2 changed file(s) with 76 addition(s) and 45 deletion(s). Raw diff Collapse all Expand all
6464 guint have_read_entries : 1;
6565 guint deleted : 1;
6666
67 guint references : 28;
67 guint references;
68
69 GFunc notify;
70 gpointer notify_data;
6871 };
6972
7073 struct CachedDirMonitor
7982 static void cached_dir_free (CachedDir *dir);
8083 static gboolean cached_dir_load_entries_recursive (CachedDir *dir,
8184 const char *dirname);
85 static void cached_dir_unref (CachedDir *dir);
86 static CachedDir * cached_dir_add_subdir (CachedDir *dir,
87 const char *basename,
88 const char *path);
89 static gboolean cached_dir_remove_subdir (CachedDir *dir,
90 const char *basename);
8291
8392 static void handle_cached_dir_changed (MenuMonitor *monitor,
8493 MenuMonitorEvent event,
91100
92101 static CachedDir *dir_cache = NULL;
93102
103 static void
104 clear_cache (CachedDir *dir,
105 gpointer *cache)
106 {
107 *cache = NULL;
108 }
109
94110 static CachedDir *
95111 cached_dir_new (const char *name)
96112 {
97113 CachedDir *dir;
98114
99115 dir = g_new0 (CachedDir, 1);
100
101116 dir->name = g_strdup (name);
117
118 return dir;
119 }
120
121 static CachedDir *
122 cached_dir_new_full (const char *name,
123 GFunc notify,
124 gpointer notify_data)
125 {
126 CachedDir *dir;
127
128 dir = cached_dir_new (name);
129
130 dir->notify = notify;
131 dir->notify_data = notify_data;
102132
103133 return dir;
104134 }
126156 dir->entries = NULL;
127157
128158 g_slist_foreach (dir->subdirs,
129 (GFunc) cached_dir_free,
159 (GFunc) cached_dir_unref,
130160 NULL);
131161 g_slist_free (dir->subdirs);
132162 dir->subdirs = NULL;
138168 g_free (dir);
139169 }
140170
171 static CachedDir *
172 cached_dir_ref (CachedDir *dir)
173 {
174 dir->references++;
175 return dir;
176 }
177
178 static void
179 cached_dir_unref (CachedDir *dir)
180 {
181 if (--dir->references)
182 {
183 CachedDir *parent;
184
185 parent = dir->parent;
186
187 if (parent != NULL)
188 cached_dir_remove_subdir (parent, dir->name);
189
190 if (dir->notify)
191 dir->notify (dir, dir->notify_data);
192
193 cached_dir_free (dir);
194 }
195 }
196
141197 static inline CachedDir *
142198 find_subdir (CachedDir *dir,
143199 const char *subdir)
216272 int i;
217273
218274 if (dir_cache == NULL)
219 dir_cache = cached_dir_new ("/");
275 dir_cache = cached_dir_new_full ("/",
276 (GFunc) clear_cache,
277 &dir_cache);
220278 dir = dir_cache;
221279
222280 g_assert (canonical != NULL && canonical[0] == G_DIR_SEPARATOR);
230288 {
231289 CachedDir *subdir;
232290
233 if ((subdir = find_subdir (dir, split[i])) == NULL)
234 {
235 subdir = cached_dir_new (split[i]);
236 dir->subdirs = g_slist_prepend (dir->subdirs, subdir);
237 subdir->parent = dir;
238 }
291 subdir = cached_dir_add_subdir (dir, split[i], NULL);
239292
240293 dir = subdir;
241294
323376 return FALSE;
324377 }
325378
326 static gboolean
379 static CachedDir *
327380 cached_dir_add_subdir (CachedDir *dir,
328381 const char *basename,
329382 const char *path)
335388 if (subdir != NULL)
336389 {
337390 subdir->deleted = FALSE;
338 return TRUE;
391 return subdir;
339392 }
340393
341394 subdir = cached_dir_new (basename);
342395
343 if (!cached_dir_load_entries_recursive (subdir, path))
396 if (path != NULL && !cached_dir_load_entries_recursive (subdir, path))
344397 {
345398 cached_dir_free (subdir);
346 return FALSE;
399 return NULL;
347400 }
348401
349402 menu_verbose ("Caching dir \"%s\"\n", basename);
350403
351404 subdir->parent = dir;
352 dir->subdirs = g_slist_prepend (dir->subdirs, subdir);
353
354 return TRUE;
405 dir->subdirs = g_slist_prepend (dir->subdirs, cached_dir_ref (subdir));
406
407 return subdir;
355408 }
356409
357410 static gboolean
368421
369422 if (subdir->references == 0)
370423 {
371 cached_dir_free (subdir);
424 cached_dir_unref (subdir);
372425 dir->subdirs = g_slist_remove (dir->subdirs, subdir);
373426 }
374427
563616 switch (event)
564617 {
565618 case MENU_MONITOR_EVENT_CREATED:
566 handled = cached_dir_add_subdir (dir, basename, path);
619 handled = cached_dir_add_subdir (dir, basename, path) != NULL;
567620 break;
568621
569622 case MENU_MONITOR_EVENT_CHANGED:
735788 static void
736789 cached_dir_add_reference (CachedDir *dir)
737790 {
738 dir->references++;
791 cached_dir_ref (dir);
739792
740793 if (dir->parent != NULL)
741794 {
750803
751804 parent = dir->parent;
752805
753 if (--dir->references == 0 && dir->deleted)
754 {
755 if (dir->parent != NULL)
756 {
757 GSList *tmp;
758
759 tmp = parent->subdirs;
760 while (tmp != NULL)
761 {
762 CachedDir *subdir = tmp->data;
763
764 if (!strcmp (subdir->name, dir->name))
765 {
766 parent->subdirs = g_slist_delete_link (parent->subdirs, tmp);
767 break;
768 }
769
770 tmp = tmp->next;
771 }
772 }
773
774 cached_dir_free (dir);
775 }
806 cached_dir_unref (dir);
776807
777808 if (parent != NULL)
778809 {
162162 MenuLayoutNode *layout);
163163 static void gmenu_tree_force_recanonicalize (GMenuTree *tree);
164164 static void gmenu_tree_invoke_monitors (GMenuTree *tree);
165
165
166166 static void gmenu_tree_item_unref_and_unset_parent (gpointer itemp);
167167
168168 typedef enum
14971497 NULL);
14981498 g_slist_free (directory->contents);
14991499 directory->contents = NULL;
1500
1500
15011501 g_slist_foreach (directory->default_layout_info,
15021502 (GFunc) menu_layout_node_unref,
15031503 NULL);