From 00c7817c9c326368c2cd89f1e786584283935c9c Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Thu, 12 Jan 2023 06:52:09 -0500 Subject: [PATCH] [BugFix] playlist.c DIRCACHE stop scanning when changing indices dc_playlist_thread may continue loading pointers even while underlying indices are changing instead stop the loop by marking pointers as clean and rebuild later Change-Id: If154f673b4af8d6e9c364499d58f1321834a76a4 --- apps/playlist.c | 55 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/apps/playlist.c b/apps/playlist.c index 4e4e3ed42a..f3f084b702 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -172,6 +172,8 @@ static struct playlist_info current_playlist; #ifdef HAVE_DIRCACHE #define PLAYLIST_LOAD_POINTERS 1 +#define PLAYLIST_CLEAN_POINTERS 2 +static bool dc_has_dirty_pointers = false; static struct event_queue playlist_queue SHAREDBSS_ATTR; static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; @@ -221,6 +223,16 @@ static void dc_load_playlist_pointers(void) /* No-Op for non dircache targets */ } +static void dc_discard_playlist_pointers(void) +{ +#ifdef HAVE_DIRCACHE + /* dump any pointers currently waiting */ + if (dc_has_dirty_pointers) + queue_send(&playlist_queue, PLAYLIST_CLEAN_POINTERS, 0); +#endif +/* No-Op for non dircache targets */ +} + static void close_playlist_control_file(struct playlist_info *playlist) { playlist_mutex_lock(&(playlist->mutex)); @@ -494,6 +506,7 @@ static void update_playlist_filename_unlocked(struct playlist_info* playlist, */ static void empty_playlist_unlocked(struct playlist_info* playlist, bool resume) { + dc_discard_playlist_pointers(); if(playlist->fd >= 0) /* If there is an already open playlist, close it. */ { @@ -884,7 +897,6 @@ static int add_indices_to_playlist(struct playlist_info* playlist, exit: playlist_mutex_unlock(&(playlist->mutex)); - dc_load_playlist_pointers(); return result; } @@ -1512,6 +1524,7 @@ static int remove_track_from_playlist(struct playlist_info* playlist, return -1; playlist_mutex_lock(&(playlist->mutex)); + inserted = playlist->indices[position] & PLAYLIST_INSERT_TYPE_MASK; /* shift indices now that track has been removed */ @@ -1590,6 +1603,8 @@ static int randomise_playlist(struct playlist_info* playlist, playlist_mutex_lock(&(playlist->mutex)); + dc_discard_playlist_pointers(); + /* seed 0 is used to identify sorted playlist for resume purposes */ if (seed == 0) seed = 1; @@ -1673,9 +1688,10 @@ static int sort_compare_fn(const void* p1, const void* p2) static int sort_playlist_unlocked(struct playlist_info* playlist, bool start_current, bool write) { - unsigned int current = playlist->indices[playlist->index]; + dc_discard_playlist_pointers(); + if (playlist->amount > 0) qsort((void*)playlist->indices, playlist->amount, sizeof(playlist->indices[0]), sort_compare_fn); @@ -1875,7 +1891,6 @@ static void dc_flush_playlist_callback(void) static void dc_thread_playlist(void) { struct queue_event ev; - bool dirty_pointers = false; static char tmp[MAX_PATH+1]; struct playlist_info *playlist; @@ -1897,8 +1912,13 @@ static void dc_thread_playlist(void) switch (ev.id) { + case PLAYLIST_CLEAN_POINTERS: + dc_has_dirty_pointers = false; + queue_reply(&playlist_queue, 0); + break; + case PLAYLIST_LOAD_POINTERS: - dirty_pointers = true; + dc_has_dirty_pointers = true; break ; /* Start the background scanning after either the disk spindown @@ -1916,7 +1936,7 @@ static void dc_thread_playlist(void) break ; /* Check if previously loaded pointers are intact. */ - if (!dirty_pointers) + if (!dc_has_dirty_pointers) break ; struct dircache_info info; @@ -1955,7 +1975,7 @@ static void dc_thread_playlist(void) cancel_cpu_boost(); if (index == playlist->amount) - dirty_pointers = false; + dc_has_dirty_pointers = false; break ; } @@ -2188,9 +2208,11 @@ int playlist_create_ex(struct playlist_info* playlist, new_playlist_unlocked(playlist, dir, file); if (file) + { /* load the playlist file */ add_indices_to_playlist(playlist, temp_buffer, temp_buffer_size); - + dc_load_playlist_pointers(); + } return 0; } @@ -2215,6 +2237,7 @@ int playlist_create(const char *dir, const char *file) buflen = ALIGN_DOWN(buflen, 512); /* to avoid partial sector I/O */ /* load the playlist file */ add_indices_to_playlist(playlist, buf, buflen); + dc_load_playlist_pointers(); core_free(handle); } else @@ -2285,6 +2308,8 @@ int playlist_delete(struct playlist_info* playlist, int index) return -1; } + dc_discard_playlist_pointers(); + if (index == PLAYLIST_DELETE_CURRENT) index = playlist->index; @@ -2570,6 +2595,8 @@ int playlist_insert_directory(struct playlist_info* playlist, return -1; } + dc_discard_playlist_pointers(); + if (queue) count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); else @@ -2622,6 +2649,8 @@ int playlist_insert_playlist(struct playlist_info* playlist, const char *filenam playlist_mutex_lock(&(playlist->mutex)); + dc_discard_playlist_pointers(); + cpu_boost(true); if (check_control(playlist) < 0) @@ -2750,6 +2779,8 @@ int playlist_insert_track(struct playlist_info* playlist, const char *filename, playlist_mutex_lock(&(playlist->mutex)); + dc_discard_playlist_pointers(); + if (check_control(playlist) < 0) { notify_control_access_error(); @@ -2763,7 +2794,9 @@ int playlist_insert_track(struct playlist_info* playlist, const char *filename, * bunch of files from tagcache, syncing after every file wouldn't be * a good thing to do. */ if (sync && result >= 0) + { playlist_sync(playlist); + } playlist_mutex_unlock(&(playlist->mutex)); @@ -2860,6 +2893,8 @@ int playlist_move(struct playlist_info* playlist, int index, int new_index) goto out; } + dc_discard_playlist_pointers(); + /* We want to insert the track at the position that was specified by new_index. This may be different then new_index because of the shifting that will occur after the delete. @@ -2975,6 +3010,8 @@ int playlist_next(int steps) { int i, j; + dc_discard_playlist_pointers(); + /* We need to delete all the queued songs */ for (i=0, j=steps; iindex > 0) if ((result = remove_track_from_playlist(playlist, 0, true)) < 0) return result; @@ -3762,6 +3801,7 @@ int playlist_save(struct playlist_info* playlist, char *filename, close(playlist->fd); playlist->fd = fd; fd = -1; + dc_discard_playlist_pointers(); if (!reparse) { @@ -3787,6 +3827,7 @@ int playlist_save(struct playlist_info* playlist, char *filename, /* we need to recreate control because inserted tracks are now part of the playlist and shuffle has been invalidated */ result = recreate_control_unlocked(playlist); + dc_load_playlist_pointers(); } }