aboutsummaryrefslogtreecommitdiffstats
path: root/src/directory.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-09-29 02:48:09 -0700
committerEric Wong <normalperson@yhbt.net>2008-09-29 03:04:29 -0700
commit659a543da853bcb28c22df300a93bd22dc9ae877 (patch)
tree7b3651df4ec404fe7041b5a9b698e7ac17307b7e /src/directory.c
parent887f97b868886a66d7bb2fcd0e1fd6810297299d (diff)
downloadmpd-659a543da853bcb28c22df300a93bd22dc9ae877.tar.gz
mpd-659a543da853bcb28c22df300a93bd22dc9ae877.tar.xz
mpd-659a543da853bcb28c22df300a93bd22dc9ae877.zip
update: move path sanitation up the stack to avoid extra copies
Remove yet another use of our old malloc-happy linked list implementation and replace it with a simple array of strings. This also implements more eager error handling of invalid paths (still centralized in updateInit) so we can filter out bad paths before we spawn a thread. This also does its part to fix the "update" command inside list mode which lost its static variable in ada24f9a921ff95d874195acf253b5a9dd12213d (although it was broken and requires the fix in 769939b62f7557f8e7c483223d68a8b39af43e37, too).
Diffstat (limited to '')
-rw-r--r--src/directory.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/src/directory.c b/src/directory.c
index a332316ff..8d36985dc 100644
--- a/src/directory.c
+++ b/src/directory.c
@@ -114,16 +114,15 @@ void reap_update_task(void)
progress = UPDATE_PROGRESS_IDLE;
}
-static void * update_task(void *arg)
+/* @argv represents a null-terminated array of (null-terminated) strings */
+static void * update_task(void *argv)
{
- List *path_list = (List *)arg;
enum update_return ret = UPDATE_RETURN_NOUPDATE;
- if (path_list) {
- ListNode *node = path_list->firstNode;
-
- while (node) {
- switch (updatePath(node->key)) {
+ if (argv) {
+ char **pathv;
+ for (pathv = (char **)argv; *pathv; pathv++) {
+ switch (updatePath(*pathv)) {
case UPDATE_RETURN_ERROR:
ret = UPDATE_RETURN_ERROR;
goto out;
@@ -132,9 +131,9 @@ static void * update_task(void *arg)
case UPDATE_RETURN_UPDATED:
ret = UPDATE_RETURN_UPDATED;
}
- node = node->nextNode;
+ free(*pathv);
}
- freeList(path_list);
+ free(argv);
} else {
ret = updateDirectory(music_root);
}
@@ -147,17 +146,32 @@ out:
return (void *)ret;
}
-int updateInit(List * path_list)
+int updateInit(int argc, char *argv[])
{
pthread_attr_t attr;
+ char **pathv = NULL;
+ int i;
- if (progress != UPDATE_PROGRESS_IDLE)
+ if (progress != UPDATE_PROGRESS_IDLE) {
+ for (i = argc; --i >= 0; )
+ free(argv[i]);
return -1;
+ }
+
+ for (i = argc; --i >= 0; ) {
+ if (!argv[i])
+ return -2;
+ }
progress = UPDATE_PROGRESS_RUNNING;
+ if (argc > 0) {
+ pathv = xmalloc((argc + 1) * sizeof(char *));
+ memcpy(pathv, argv, argc * sizeof(char *));
+ pathv[argc] = NULL;
+ }
pthread_attr_init(&attr);
- if (pthread_create(&update_thr, &attr, update_task, path_list))
+ if (pthread_create(&update_thr, &attr, update_task, pathv))
FATAL("Failed to spawn update task: %s\n", strerror(errno));
directory_updateJobId++;
if (directory_updateJobId > 1 << 15)