From a340bf0dee5bf134770f5d5f532efa90cdb08b3c Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Tue, 7 Oct 2008 02:25:27 -0700
Subject: directory: use songvec_for_each for iterators

Get rid of songvec_write so we can enforce proper locking
---
 src/directory.c | 86 +++++++++++++++++++++++++++++++++++++--------------------
 src/songvec.c   | 31 ---------------------
 src/songvec.h   |  2 --
 3 files changed, 56 insertions(+), 63 deletions(-)

diff --git a/src/directory.c b/src/directory.c
index 04523ceea..a11d01d25 100644
--- a/src/directory.c
+++ b/src/directory.c
@@ -276,15 +276,34 @@ static int skip_path(const char *path)
 	return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0;
 }
 
+struct delete_data {
+	char *tmp;
+	Directory *dir;
+	enum update_return ret;
+};
+
+/* passed to songvec_for_each */
+static int delete_song_if_removed(Song *song, void *_data)
+{
+	struct delete_data *data = _data;
+
+	data->tmp = get_song_url(data->tmp, song);
+	assert(data->tmp);
+
+	if (!isFile(data->tmp, NULL)) {
+		delete_song(data->dir, song);
+		data->ret = UPDATE_RETURN_UPDATED;
+	}
+	return 0;
+}
+
 static enum update_return
 removeDeletedFromDirectory(char *path_max_tmp, Directory * directory)
 {
-	const char *dirname = (directory && directory->path) ?
-	    directory->path : NULL;
 	enum update_return ret = UPDATE_RETURN_NOUPDATE;
 	int i;
-	struct songvec *sv = &directory->songs;
 	struct dirvec *dv = &directory->children;
+	struct delete_data data;
 
 	for (i = dv->nr; --i >= 0; ) {
 		if (isDir(dv->base[i]->path))
@@ -294,23 +313,12 @@ removeDeletedFromDirectory(char *path_max_tmp, Directory * directory)
 		ret = UPDATE_RETURN_UPDATED;
 	}
 
-	for (i = sv->nr; --i >= 0; ) { /* cleaner deletes if we go backwards */
-		Song *song = sv->base[i];
-		assert(song);
-		assert(*song->url);
-
-		if (dirname)
-			sprintf(path_max_tmp, "%s/%s", dirname, song->url);
-		else
-			strcpy(path_max_tmp, song->url);
-
-		if (!isFile(path_max_tmp, NULL)) {
-			delete_song(directory, song);
-			ret = UPDATE_RETURN_UPDATED;
-		}
-	}
+	data.dir = directory;
+	data.tmp = path_max_tmp;
+	data.ret = UPDATE_RETURN_UPDATED;
+	songvec_for_each(&directory->songs, delete_song_if_removed, &data);
 
-	return ret;
+	return data.ret;
 }
 
 static Directory *addDirectoryPathToDB(const char *utf8path)
@@ -684,7 +692,22 @@ int printDirectoryInfo(int fd, const char *name)
 		return -1;
 
 	printDirectoryList(fd, &directory->children);
-	songvec_write(&directory->songs, fd, 0);
+	songvec_for_each(&directory->songs,
+	                 song_print_info_x, (void *)(size_t)fd);
+
+	return 0;
+}
+
+static int directory_song_write(Song *song, void *data)
+{
+	int fd = (int)(size_t)data;
+
+	if (fdprintf(fd, SONG_KEY "%s\n", song->url) < 0)
+		return -1;
+	if (song_print_info(song, fd) < 0)
+		return -1;
+	if (fdprintf(fd, SONG_MTIME "%li\n", (long)song->mtime) < 0)
+		return -1;
 
 	return 0;
 }
@@ -709,7 +732,16 @@ static int writeDirectoryInfo(int fd, Directory * directory)
 		if (writeDirectoryInfo(fd, cur) < 0)
 			return -1;
 	}
-	songvec_write(&directory->songs, fd, 1);
+
+	if (fdprintf(fd, SONG_BEGIN "\n") < 0)
+		return -1;
+
+	if (songvec_for_each(&directory->songs,
+	                     directory_song_write, (void *)(size_t)fd) < 0)
+		return -1;
+
+	if (fdprintf(fd, SONG_END "\n") < 0)
+		return -1;
 
 	if (directory->path &&
 	    fdprintf(fd, DIRECTORY_END "%s\n",
@@ -967,15 +999,9 @@ static int traverseAllInSubDirectory(Directory * directory,
 		return err;
 
 	if (forEachSong) {
-		int i;
-		struct songvec *sv = &directory->songs;
-		Song **sp = sv->base;
-
-		for (i = sv->nr; --i >= 0; ) {
-			Song *song = *sp++;
-			if ((err = forEachSong(song, data)) < 0)
-				return err;
-		}
+		err = songvec_for_each(&directory->songs, forEachSong, data);
+		if (err < 0)
+			return err;
 	}
 
 	for (j = 0; err >= 0 && j < dv->nr; ++j)
diff --git a/src/songvec.c b/src/songvec.c
index 640eff0a8..cf0991029 100644
--- a/src/songvec.c
+++ b/src/songvec.c
@@ -104,34 +104,3 @@ int songvec_for_each(struct songvec *sv, int (*fn)(Song *, void *), void *arg)
 
 	return 0;
 }
-
-int songvec_write(struct songvec *sv, int fd, int extra)
-{
-	int i;
-	Song **sp = sv->base;
-
-	if (extra) {
-		if (fdprintf(fd, SONG_BEGIN "\n") < 0)
-			return -1;
-
-		for (i = sv->nr; --i >= 0; ) {
-			Song *song = *sp++;
-			if (fdprintf(fd, SONG_KEY "%s\n", song->url) < 0)
-				return -1;
-			if (song_print_info(song, fd) < 0)
-				return -1;
-			if (fdprintf(fd,
-			            SONG_MTIME "%li\n", (long)song->mtime) < 0)
-				return -1;
-		}
-
-		if (fdprintf(fd, SONG_END "\n") < 0)
-			return -1;
-	} else {
-		for (i = sv->nr; --i >= 0;)
-			if (song_print_info(*sp++, fd) < 0)
-				return -1;
-	}
-
-	return 0;
-}
diff --git a/src/songvec.h b/src/songvec.h
index adfdeccfb..dbe6be508 100644
--- a/src/songvec.h
+++ b/src/songvec.h
@@ -21,6 +21,4 @@ void songvec_destroy(struct songvec *sv);
 
 int songvec_for_each(struct songvec *sv, int (*fn)(Song *, void *), void *arg);
 
-int songvec_write(struct songvec *sv, int fd, int extra);
-
 #endif /* SONGVEC_H */
-- 
cgit v1.2.3