From e018b35b0d99d24e1f3779fd51c07154b370eca9 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 11 Oct 2008 23:04:36 -0700 Subject: dirvec: use dirvec_for_each where it makes sense This way we can introduce locking to allow safe traversals from the main thread while we're updating. --- src/directory.c | 60 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 23 deletions(-) (limited to 'src/directory.c') diff --git a/src/directory.c b/src/directory.c index e66349e02..6a0bd18fd 100644 --- a/src/directory.c +++ b/src/directory.c @@ -50,18 +50,17 @@ void directory_free(struct directory *dir) free(dir); } -void directory_prune_empty(struct directory *dir) +static int dir_pruner(struct directory *dir, void *_dv) { - int i; - struct dirvec *dv = &dir->children; + directory_prune_empty(dir); + if (directory_is_empty(dir)) + dirvec_delete((struct dirvec *)_dv, dir); + return 0; +} - for (i = dv->nr; --i >= 0; ) { - directory_prune_empty(dv->base[i]); - if (directory_is_empty(dv->base[i])) - dirvec_delete(dv, dv->base[i]); - } - if (!dv->nr) - dirvec_destroy(dv); +void directory_prune_empty(struct directory *dir) +{ + dirvec_for_each(&dir->children, dir_pruner, &dir->children); } struct directory * @@ -97,27 +96,38 @@ directory_get_subdir(struct directory *dir, const char *name) return found; } -void directory_sort(struct directory *dir) +static int directory_sort_x(struct directory *dir, mpd_unused void *arg) { - int i; - struct dirvec *dv = &dir->children; + directory_sort(dir); + return 0; +} - dirvec_sort(dv); +void directory_sort(struct directory *dir) +{ + dirvec_sort(&dir->children); + dirvec_for_each(&dir->children, directory_sort_x, NULL); songvec_sort(&dir->songs); +} + +struct dirwalk_arg { + int (*each_song) (struct mpd_song *, void *); + int (*each_dir) (struct directory *, void *); + void *data; +}; - for (i = dv->nr; --i >= 0; ) - directory_sort(dv->base[i]); +static int dirwalk_x(struct directory *dir, void *_arg) +{ + struct dirwalk_arg *arg = _arg; + + return directory_walk(dir, arg->each_song, arg->each_dir, arg->data); } -int -directory_walk(struct directory *dir, +int directory_walk(struct directory *dir, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data) { - struct dirvec *dv = &dir->children; int err = 0; - size_t j; if (forEachDir && (err = forEachDir(dir, data)) < 0) return err; @@ -128,9 +138,13 @@ directory_walk(struct directory *dir, return err; } - for (j = 0; err >= 0 && j < dv->nr; ++j) - err = directory_walk(dv->base[j], forEachSong, - forEachDir, data); + if (forEachDir) { + struct dirwalk_arg dw_arg; + dw_arg.each_song = forEachSong; + dw_arg.each_dir = forEachDir; + dw_arg.data = data; + err = dirvec_for_each(&dir->children, dirwalk_x, &dw_arg); + } return err; } -- cgit v1.2.3