diff options
author | Eric Wong <normalperson@yhbt.net> | 2008-10-12 05:28:25 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2008-10-12 05:29:27 -0700 |
commit | 7278e3b2ee49a853b01dc6532bd7067a264f235d (patch) | |
tree | 28e83de310f0c58df226e253a82b0d43ff784497 /src/songvec.c | |
parent | c87ce02575e0a9d5ac3e50938688187ea28ad400 (diff) | |
parent | c7579ca2d8422f0172537e1ca7d1bd46edfc4f9d (diff) | |
download | mpd-7278e3b2ee49a853b01dc6532bd7067a264f235d.tar.gz mpd-7278e3b2ee49a853b01dc6532bd7067a264f235d.tar.xz mpd-7278e3b2ee49a853b01dc6532bd7067a264f235d.zip |
Merge branch 'ew/directory'
* ew/directory: (21 commits)
update: fix multiple deletes from *vec iterators
directory: children leave parents before being free()ed
directory: always maintain sorted properties vectors
update: simplify the serialized_delete usage a bit
update: remove delete_each_song and clear_directory
directory: directory_free kills all that it contains
update: serialize directory deletions
update: serialize song_free in main thread
dirvec: introduce locking for all iterators
dirvec: use dirvec_for_each where it makes sense
dirvec: add dirvec_for_each iterator
songvec: avoid holding nr_lock during free(3)
update: allow music_root updates to be queued
update: validate in command.c and fix small memory leak
directory: rename isRootDirectory => path_is_music_root
Avoid calling isRootDirectory when we have a directory object
directory: make music_root global and avoid runtime initialization
directory: use mpd_sizeof_str_flex_array for path, too
tag_item: avoid wasting space when struct is unpackable
song: use mpd_sizeof_str_flex_array for song.url
...
[ew: fixed up merge errors with myself when isRootDirectory
went away]
Diffstat (limited to 'src/songvec.c')
-rw-r--r-- | src/songvec.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/src/songvec.c b/src/songvec.c index ce04a4373..19433a222 100644 --- a/src/songvec.c +++ b/src/songvec.c @@ -17,13 +17,6 @@ static size_t sv_size(struct songvec *sv) return sv->nr * sizeof(struct mpd_song *); } -void songvec_sort(struct songvec *sv) -{ - pthread_mutex_lock(&nr_lock); - qsort(sv->base, sv->nr, sizeof(struct mpd_song *), songvec_cmp); - pthread_mutex_unlock(&nr_lock); -} - struct mpd_song *songvec_find(const struct songvec *sv, const char *url) { int i; @@ -48,10 +41,12 @@ int songvec_delete(struct songvec *sv, const struct mpd_song *del) for (i = sv->nr; --i >= 0; ) { if (sv->base[i] != del) continue; - /* we _don't_ call freeSong() here */ + /* we _don't_ call song_free() here */ if (!--sv->nr) { + pthread_mutex_unlock(&nr_lock); free(sv->base); sv->base = NULL; + return i; } else { memmove(&sv->base[i], &sv->base[i + 1], (sv->nr - i + 1) * sizeof(struct mpd_song *)); @@ -66,40 +61,48 @@ int songvec_delete(struct songvec *sv, const struct mpd_song *del) void songvec_add(struct songvec *sv, struct mpd_song *add) { + size_t old_nr; + pthread_mutex_lock(&nr_lock); - ++sv->nr; + old_nr = sv->nr++; sv->base = xrealloc(sv->base, sv_size(sv)); - sv->base[sv->nr - 1] = add; + sv->base[old_nr] = add; + if (old_nr && songvec_cmp(&sv->base[old_nr - 1], &add) >= 0) + qsort(sv->base, sv->nr, sizeof(struct mpd_song *), songvec_cmp); pthread_mutex_unlock(&nr_lock); } void songvec_destroy(struct songvec *sv) { pthread_mutex_lock(&nr_lock); + sv->nr = 0; + pthread_mutex_unlock(&nr_lock); if (sv->base) { free(sv->base); sv->base = NULL; } - sv->nr = 0; - pthread_mutex_unlock(&nr_lock); } int songvec_for_each(const struct songvec *sv, int (*fn)(struct mpd_song *, void *), void *arg) { size_t i; + size_t prev_nr; pthread_mutex_lock(&nr_lock); - for (i = 0; i < sv->nr; ++i) { + for (i = 0; i < sv->nr; ) { struct mpd_song *song = sv->base[i]; assert(song); assert(*song->url); + prev_nr = sv->nr; pthread_mutex_unlock(&nr_lock); /* fn() may block */ if (fn(song, arg) < 0) return -1; pthread_mutex_lock(&nr_lock); /* sv->nr may change in fn() */ + if (prev_nr == sv->nr) + ++i; } pthread_mutex_unlock(&nr_lock); |