64 | 64 |
guint have_read_entries : 1;
|
65 | 65 |
guint deleted : 1;
|
66 | 66 |
|
67 | |
guint references : 28;
|
|
67 |
guint references;
|
|
68 |
|
|
69 |
GFunc notify;
|
|
70 |
gpointer notify_data;
|
68 | 71 |
};
|
69 | 72 |
|
70 | 73 |
struct CachedDirMonitor
|
|
79 | 82 |
static void cached_dir_free (CachedDir *dir);
|
80 | 83 |
static gboolean cached_dir_load_entries_recursive (CachedDir *dir,
|
81 | 84 |
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);
|
82 | 91 |
|
83 | 92 |
static void handle_cached_dir_changed (MenuMonitor *monitor,
|
84 | 93 |
MenuMonitorEvent event,
|
|
91 | 100 |
|
92 | 101 |
static CachedDir *dir_cache = NULL;
|
93 | 102 |
|
|
103 |
static void
|
|
104 |
clear_cache (CachedDir *dir,
|
|
105 |
gpointer *cache)
|
|
106 |
{
|
|
107 |
*cache = NULL;
|
|
108 |
}
|
|
109 |
|
94 | 110 |
static CachedDir *
|
95 | 111 |
cached_dir_new (const char *name)
|
96 | 112 |
{
|
97 | 113 |
CachedDir *dir;
|
98 | 114 |
|
99 | 115 |
dir = g_new0 (CachedDir, 1);
|
100 | |
|
101 | 116 |
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;
|
102 | 132 |
|
103 | 133 |
return dir;
|
104 | 134 |
}
|
|
126 | 156 |
dir->entries = NULL;
|
127 | 157 |
|
128 | 158 |
g_slist_foreach (dir->subdirs,
|
129 | |
(GFunc) cached_dir_free,
|
|
159 |
(GFunc) cached_dir_unref,
|
130 | 160 |
NULL);
|
131 | 161 |
g_slist_free (dir->subdirs);
|
132 | 162 |
dir->subdirs = NULL;
|
|
138 | 168 |
g_free (dir);
|
139 | 169 |
}
|
140 | 170 |
|
|
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 |
|
141 | 197 |
static inline CachedDir *
|
142 | 198 |
find_subdir (CachedDir *dir,
|
143 | 199 |
const char *subdir)
|
|
216 | 272 |
int i;
|
217 | 273 |
|
218 | 274 |
if (dir_cache == NULL)
|
219 | |
dir_cache = cached_dir_new ("/");
|
|
275 |
dir_cache = cached_dir_new_full ("/",
|
|
276 |
(GFunc) clear_cache,
|
|
277 |
&dir_cache);
|
220 | 278 |
dir = dir_cache;
|
221 | 279 |
|
222 | 280 |
g_assert (canonical != NULL && canonical[0] == G_DIR_SEPARATOR);
|
|
230 | 288 |
{
|
231 | 289 |
CachedDir *subdir;
|
232 | 290 |
|
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);
|
239 | 292 |
|
240 | 293 |
dir = subdir;
|
241 | 294 |
|
|
323 | 376 |
return FALSE;
|
324 | 377 |
}
|
325 | 378 |
|
326 | |
static gboolean
|
|
379 |
static CachedDir *
|
327 | 380 |
cached_dir_add_subdir (CachedDir *dir,
|
328 | 381 |
const char *basename,
|
329 | 382 |
const char *path)
|
|
335 | 388 |
if (subdir != NULL)
|
336 | 389 |
{
|
337 | 390 |
subdir->deleted = FALSE;
|
338 | |
return TRUE;
|
|
391 |
return subdir;
|
339 | 392 |
}
|
340 | 393 |
|
341 | 394 |
subdir = cached_dir_new (basename);
|
342 | 395 |
|
343 | |
if (!cached_dir_load_entries_recursive (subdir, path))
|
|
396 |
if (path != NULL && !cached_dir_load_entries_recursive (subdir, path))
|
344 | 397 |
{
|
345 | 398 |
cached_dir_free (subdir);
|
346 | |
return FALSE;
|
|
399 |
return NULL;
|
347 | 400 |
}
|
348 | 401 |
|
349 | 402 |
menu_verbose ("Caching dir \"%s\"\n", basename);
|
350 | 403 |
|
351 | 404 |
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;
|
355 | 408 |
}
|
356 | 409 |
|
357 | 410 |
static gboolean
|
|
368 | 421 |
|
369 | 422 |
if (subdir->references == 0)
|
370 | 423 |
{
|
371 | |
cached_dir_free (subdir);
|
|
424 |
cached_dir_unref (subdir);
|
372 | 425 |
dir->subdirs = g_slist_remove (dir->subdirs, subdir);
|
373 | 426 |
}
|
374 | 427 |
|
|
563 | 616 |
switch (event)
|
564 | 617 |
{
|
565 | 618 |
case MENU_MONITOR_EVENT_CREATED:
|
566 | |
handled = cached_dir_add_subdir (dir, basename, path);
|
|
619 |
handled = cached_dir_add_subdir (dir, basename, path) != NULL;
|
567 | 620 |
break;
|
568 | 621 |
|
569 | 622 |
case MENU_MONITOR_EVENT_CHANGED:
|
|
735 | 788 |
static void
|
736 | 789 |
cached_dir_add_reference (CachedDir *dir)
|
737 | 790 |
{
|
738 | |
dir->references++;
|
|
791 |
cached_dir_ref (dir);
|
739 | 792 |
|
740 | 793 |
if (dir->parent != NULL)
|
741 | 794 |
{
|
|
750 | 803 |
|
751 | 804 |
parent = dir->parent;
|
752 | 805 |
|
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);
|
776 | 807 |
|
777 | 808 |
if (parent != NULL)
|
778 | 809 |
{
|