From a9bd64b1dd2bbf6a6146d56d91da49ee5f3f06c3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 4 Jan 2009 20:30:23 +0100 Subject: update: splitted reap_update_task() Handle the DELETE and UPDATE events in separate callbacks: song_delete_event() safely deletes a song, and update_finished_event() is called when database update is complete. --- src/update.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'src/update.c') diff --git a/src/update.c b/src/update.c index ce342b88b..80fa3add3 100644 --- a/src/update.c +++ b/src/update.c @@ -690,35 +690,48 @@ directory_update_init(char *path) return update_task_id; } -static void reap_update_task(void) +/** + * Safely delete a song from the database. This must be done in the + * main task, to be sure that there is no pointer left to it. + */ +static void song_delete_event(void) { - assert(g_thread_self() == main_task); + char *uri; - if (progress == UPDATE_PROGRESS_IDLE) - return; + assert(progress == UPDATE_PROGRESS_RUNNING); + assert(delete != NULL); cond_enter(&delete_cond); - if (delete) { - char *tmp = song_get_uri(delete); - g_debug("removing: %s", tmp); - g_free(tmp); - - deleteASongFromPlaylist(delete); - delete = NULL; - cond_signal_sync(&delete_cond); - } + + uri = song_get_uri(delete); + g_debug("removing: %s", uri); + g_free(uri); + + deleteASongFromPlaylist(delete); + delete = NULL; + + cond_signal_sync(&delete_cond); + cond_leave(&delete_cond); +} + +/** + * Called in the main thread after the database update is finished. + */ +static void update_finished_event(void) +{ + assert(progress == UPDATE_PROGRESS_DONE); - if (progress != UPDATE_PROGRESS_DONE) - return; g_thread_join(update_thr); if (modified) { + /* send "idle" events */ playlistVersionChange(); idle_add(IDLE_DATABASE); } if (update_paths_nr) { + /* schedule the next path */ char *path = update_paths[0]; memmove(&update_paths[0], &update_paths[1], --update_paths_nr * sizeof(char *)); @@ -742,8 +755,8 @@ void update_global_init(void) cond_init(&delete_cond); - event_pipe_register(PIPE_EVENT_DELETE, reap_update_task); - event_pipe_register(PIPE_EVENT_UPDATE, reap_update_task); + event_pipe_register(PIPE_EVENT_DELETE, song_delete_event); + event_pipe_register(PIPE_EVENT_UPDATE, update_finished_event); } void update_global_finish(void) -- cgit v1.2.3