aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/directory.c30
-rw-r--r--src/song.c6
-rw-r--r--src/song.h2
3 files changed, 27 insertions, 11 deletions
diff --git a/src/directory.c b/src/directory.c
index a11d01d25..9613bbfbd 100644
--- a/src/directory.c
+++ b/src/directory.c
@@ -63,8 +63,13 @@ static time_t directory_dbModTime;
static pthread_t update_thr;
static const int update_task_id_max = 1 << 15;
+
static int update_task_id;
+static Song *delete;
+
+static struct condition delete_cond;
+
static int addToDirectory(Directory * directory, const char *name);
static void freeDirectory(Directory * directory);
@@ -144,6 +149,16 @@ void reap_update_task(void)
assert(pthread_equal(pthread_self(), main_task));
+ cond_enter(&delete_cond);
+ if (delete) {
+ char tmp[MPD_PATH_MAX];
+ LOG("removing: %s\n", get_song_url(tmp, delete));
+ deleteASongFromPlaylist(delete);
+ delete = NULL;
+ cond_signal(&delete_cond);
+ }
+ cond_leave(&delete_cond);
+
if (progress != UPDATE_PROGRESS_DONE)
return;
if (pthread_join(update_thr, (void **)&ret))
@@ -215,10 +230,19 @@ static void freeDirectory(Directory * directory)
static void delete_song(Directory *dir, Song *del)
{
- char path_max_tmp[MPD_PATH_MAX]; /* wasteful */
- LOG("removing: %s\n", get_song_url(path_max_tmp, del));
+ /* first, prevent traversers in main task from getting this */
songvec_delete(&dir->songs, del);
- freeSong(del); /* FIXME racy */
+
+ /* now take it out of the playlist (in the main_task) */
+ cond_enter(&delete_cond);
+ assert(!delete);
+ delete = del;
+ wakeup_main_task();
+ do { cond_wait(&delete_cond); } while (delete);
+ cond_leave(&delete_cond);
+
+ /* finally, all possible references gone, free it */
+ freeJustSong(del);
}
static void deleteEmptyDirectoriesInDirectory(Directory * directory)
diff --git a/src/song.c b/src/song.c
index f967e3e17..c9301386d 100644
--- a/src/song.c
+++ b/src/song.c
@@ -79,12 +79,6 @@ Song *newSong(const char *url, Directory * parentDir)
return song;
}
-void freeSong(Song * song)
-{
- deleteASongFromPlaylist(song);
- freeJustSong(song);
-}
-
void freeJustSong(Song * song)
{
if (song->tag)
diff --git a/src/song.h b/src/song.h
index d8189d42c..9aa9efa94 100644
--- a/src/song.h
+++ b/src/song.h
@@ -42,8 +42,6 @@ typedef struct _Song {
Song *newSong(const char *url, struct _Directory *parentDir);
-void freeSong(Song *);
-
void freeJustSong(Song *);
ssize_t song_print_info(Song * song, int fd);