configure.ac: Move OggVorbis Encoder to Encoder Plugins.
[mpd-mk.git] / src / update.c
blob83436612f64f9e8f8eae4016f813524ae13651dd
1 /*
2 * Copyright (C) 2003-2010 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.
20 #include "config.h"
21 #include "update_internal.h"
22 #include "update.h"
23 #include "database.h"
24 #include "mapper.h"
25 #include "playlist.h"
26 #include "event_pipe.h"
27 #include "update.h"
28 #include "idle.h"
29 #include "stats.h"
30 #include "main.h"
32 #include <glib.h>
34 #include <assert.h>
36 static enum update_progress {
37 UPDATE_PROGRESS_IDLE = 0,
38 UPDATE_PROGRESS_RUNNING = 1,
39 UPDATE_PROGRESS_DONE = 2
40 } progress;
42 static bool modified;
44 static GThread *update_thr;
46 static const unsigned update_task_id_max = 1 << 15;
48 static unsigned update_task_id;
50 /* XXX this flag is passed to update_task() */
51 static bool discard;
53 unsigned
54 isUpdatingDB(void)
56 return (progress != UPDATE_PROGRESS_IDLE) ? update_task_id : 0;
59 static void * update_task(void *_path)
61 const char *path = _path;
63 if (path != NULL && *path != 0)
64 g_debug("starting: %s", path);
65 else
66 g_debug("starting");
68 modified = update_walk(path, discard);
70 if (modified || !db_exists())
71 db_save();
73 if (path != NULL && *path != 0)
74 g_debug("finished: %s", path);
75 else
76 g_debug("finished");
77 g_free(_path);
79 progress = UPDATE_PROGRESS_DONE;
80 event_pipe_emit(PIPE_EVENT_UPDATE);
81 return NULL;
84 static void
85 spawn_update_task(const char *path)
87 GError *e = NULL;
89 assert(g_thread_self() == main_task);
91 progress = UPDATE_PROGRESS_RUNNING;
92 modified = false;
94 update_thr = g_thread_create(update_task, g_strdup(path), TRUE, &e);
95 if (update_thr == NULL)
96 g_error("Failed to spawn update task: %s", e->message);
98 if (++update_task_id > update_task_id_max)
99 update_task_id = 1;
100 g_debug("spawned thread for update job id %i", update_task_id);
103 unsigned
104 update_enqueue(const char *path, bool _discard)
106 assert(g_thread_self() == main_task);
108 if (!mapper_has_music_directory())
109 return 0;
111 if (progress != UPDATE_PROGRESS_IDLE) {
112 unsigned next_task_id =
113 update_queue_push(path, discard, update_task_id);
114 if (next_task_id == 0)
115 return 0;
117 return next_task_id > update_task_id_max ? 1 : next_task_id;
120 discard = _discard;
121 spawn_update_task(path);
123 idle_add(IDLE_UPDATE);
125 return update_task_id;
129 * Called in the main thread after the database update is finished.
131 static void update_finished_event(void)
133 char *path;
135 assert(progress == UPDATE_PROGRESS_DONE);
137 g_thread_join(update_thr);
139 idle_add(IDLE_UPDATE);
141 if (modified) {
142 /* send "idle" events */
143 playlist_increment_version_all(&g_playlist);
144 idle_add(IDLE_DATABASE);
147 path = update_queue_shift(&discard);
148 if (path != NULL) {
149 /* schedule the next path */
150 spawn_update_task(path);
151 g_free(path);
152 } else {
153 progress = UPDATE_PROGRESS_IDLE;
155 stats_update();
159 void update_global_init(void)
161 event_pipe_register(PIPE_EVENT_UPDATE, update_finished_event);
163 update_remove_global_init();
164 update_walk_global_init();
167 void update_global_finish(void)
169 update_walk_global_finish();
170 update_remove_global_finish();