2
* Copyright (C) 2003-2011 The Music Player Daemon Project
3
* http://www.musicpd.org
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License along
16
* with this program; if not, write to the Free Software Foundation, Inc.,
17
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
#include "update_queue.h"
23
#include "update_walk.h"
24
#include "update_remove.h"
29
#include "event_pipe.h"
34
#include "mpd_error.h"
41
#define G_LOG_DOMAIN "update"
43
static enum update_progress {
44
UPDATE_PROGRESS_IDLE = 0,
45
UPDATE_PROGRESS_RUNNING = 1,
46
UPDATE_PROGRESS_DONE = 2
51
static GThread *update_thr;
53
static const unsigned update_task_id_max = 1 << 15;
55
static unsigned update_task_id;
57
/* XXX this flag is passed to update_task() */
63
return (progress != UPDATE_PROGRESS_IDLE) ? update_task_id : 0;
66
static void * update_task(void *_path)
68
const char *path = _path;
70
if (path != NULL && *path != 0)
71
g_debug("starting: %s", path);
75
modified = update_walk(path, discard);
77
if (modified || !db_exists()) {
79
if (!db_save(&error)) {
80
g_warning("Failed to save database: %s",
86
if (path != NULL && *path != 0)
87
g_debug("finished: %s", path);
92
progress = UPDATE_PROGRESS_DONE;
93
event_pipe_emit(PIPE_EVENT_UPDATE);
98
spawn_update_task(const char *path)
102
assert(g_thread_self() == main_task);
104
progress = UPDATE_PROGRESS_RUNNING;
107
update_thr = g_thread_create(update_task, g_strdup(path), TRUE, &e);
108
if (update_thr == NULL)
109
MPD_ERROR("Failed to spawn update task: %s", e->message);
111
if (++update_task_id > update_task_id_max)
113
g_debug("spawned thread for update job id %i", update_task_id);
117
update_enqueue(const char *path, bool _discard)
119
assert(g_thread_self() == main_task);
121
if (!mapper_has_music_directory())
124
if (progress != UPDATE_PROGRESS_IDLE) {
125
unsigned next_task_id =
126
update_queue_push(path, discard, update_task_id);
127
if (next_task_id == 0)
130
return next_task_id > update_task_id_max ? 1 : next_task_id;
134
spawn_update_task(path);
136
idle_add(IDLE_UPDATE);
138
return update_task_id;
142
* Called in the main thread after the database update is finished.
144
static void update_finished_event(void)
148
assert(progress == UPDATE_PROGRESS_DONE);
150
g_thread_join(update_thr);
152
idle_add(IDLE_UPDATE);
155
/* send "idle" events */
156
playlist_increment_version_all(&g_playlist);
157
idle_add(IDLE_DATABASE);
160
path = update_queue_shift(&discard);
162
/* schedule the next path */
163
spawn_update_task(path);
166
progress = UPDATE_PROGRESS_IDLE;
172
void update_global_init(void)
174
event_pipe_register(PIPE_EVENT_UPDATE, update_finished_event);
176
update_remove_global_init();
177
update_walk_global_init();
180
void update_global_finish(void)
182
update_walk_global_finish();
183
update_remove_global_finish();