1
0
Fork 0
forked from len0rd/rockbox

[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
This commit is contained in:
William Wilgus 2023-01-12 06:52:09 -05:00 committed by William Wilgus
parent 16a32c576c
commit 00c7817c9c

View file

@ -172,6 +172,8 @@ static struct playlist_info current_playlist;
#ifdef HAVE_DIRCACHE #ifdef HAVE_DIRCACHE
#define PLAYLIST_LOAD_POINTERS 1 #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 struct event_queue playlist_queue SHAREDBSS_ATTR;
static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; 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 */ /* 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) static void close_playlist_control_file(struct playlist_info *playlist)
{ {
playlist_mutex_lock(&(playlist->mutex)); 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) 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. */ 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: exit:
playlist_mutex_unlock(&(playlist->mutex)); playlist_mutex_unlock(&(playlist->mutex));
dc_load_playlist_pointers();
return result; return result;
} }
@ -1512,6 +1524,7 @@ static int remove_track_from_playlist(struct playlist_info* playlist,
return -1; return -1;
playlist_mutex_lock(&(playlist->mutex)); playlist_mutex_lock(&(playlist->mutex));
inserted = playlist->indices[position] & PLAYLIST_INSERT_TYPE_MASK; inserted = playlist->indices[position] & PLAYLIST_INSERT_TYPE_MASK;
/* shift indices now that track has been removed */ /* 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)); playlist_mutex_lock(&(playlist->mutex));
dc_discard_playlist_pointers();
/* seed 0 is used to identify sorted playlist for resume purposes */ /* seed 0 is used to identify sorted playlist for resume purposes */
if (seed == 0) if (seed == 0)
seed = 1; 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, static int sort_playlist_unlocked(struct playlist_info* playlist,
bool start_current, bool write) bool start_current, bool write)
{ {
unsigned int current = playlist->indices[playlist->index]; unsigned int current = playlist->indices[playlist->index];
dc_discard_playlist_pointers();
if (playlist->amount > 0) if (playlist->amount > 0)
qsort((void*)playlist->indices, playlist->amount, qsort((void*)playlist->indices, playlist->amount,
sizeof(playlist->indices[0]), sort_compare_fn); sizeof(playlist->indices[0]), sort_compare_fn);
@ -1875,7 +1891,6 @@ static void dc_flush_playlist_callback(void)
static void dc_thread_playlist(void) static void dc_thread_playlist(void)
{ {
struct queue_event ev; struct queue_event ev;
bool dirty_pointers = false;
static char tmp[MAX_PATH+1]; static char tmp[MAX_PATH+1];
struct playlist_info *playlist; struct playlist_info *playlist;
@ -1897,8 +1912,13 @@ static void dc_thread_playlist(void)
switch (ev.id) switch (ev.id)
{ {
case PLAYLIST_CLEAN_POINTERS:
dc_has_dirty_pointers = false;
queue_reply(&playlist_queue, 0);
break;
case PLAYLIST_LOAD_POINTERS: case PLAYLIST_LOAD_POINTERS:
dirty_pointers = true; dc_has_dirty_pointers = true;
break ; break ;
/* Start the background scanning after either the disk spindown /* Start the background scanning after either the disk spindown
@ -1916,7 +1936,7 @@ static void dc_thread_playlist(void)
break ; break ;
/* Check if previously loaded pointers are intact. */ /* Check if previously loaded pointers are intact. */
if (!dirty_pointers) if (!dc_has_dirty_pointers)
break ; break ;
struct dircache_info info; struct dircache_info info;
@ -1955,7 +1975,7 @@ static void dc_thread_playlist(void)
cancel_cpu_boost(); cancel_cpu_boost();
if (index == playlist->amount) if (index == playlist->amount)
dirty_pointers = false; dc_has_dirty_pointers = false;
break ; break ;
} }
@ -2188,9 +2208,11 @@ int playlist_create_ex(struct playlist_info* playlist,
new_playlist_unlocked(playlist, dir, file); new_playlist_unlocked(playlist, dir, file);
if (file) if (file)
{
/* load the playlist file */ /* load the playlist file */
add_indices_to_playlist(playlist, temp_buffer, temp_buffer_size); add_indices_to_playlist(playlist, temp_buffer, temp_buffer_size);
dc_load_playlist_pointers();
}
return 0; 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 */ buflen = ALIGN_DOWN(buflen, 512); /* to avoid partial sector I/O */
/* load the playlist file */ /* load the playlist file */
add_indices_to_playlist(playlist, buf, buflen); add_indices_to_playlist(playlist, buf, buflen);
dc_load_playlist_pointers();
core_free(handle); core_free(handle);
} }
else else
@ -2285,6 +2308,8 @@ int playlist_delete(struct playlist_info* playlist, int index)
return -1; return -1;
} }
dc_discard_playlist_pointers();
if (index == PLAYLIST_DELETE_CURRENT) if (index == PLAYLIST_DELETE_CURRENT)
index = playlist->index; index = playlist->index;
@ -2570,6 +2595,8 @@ int playlist_insert_directory(struct playlist_info* playlist,
return -1; return -1;
} }
dc_discard_playlist_pointers();
if (queue) if (queue)
count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT);
else else
@ -2622,6 +2649,8 @@ int playlist_insert_playlist(struct playlist_info* playlist, const char *filenam
playlist_mutex_lock(&(playlist->mutex)); playlist_mutex_lock(&(playlist->mutex));
dc_discard_playlist_pointers();
cpu_boost(true); cpu_boost(true);
if (check_control(playlist) < 0) 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)); playlist_mutex_lock(&(playlist->mutex));
dc_discard_playlist_pointers();
if (check_control(playlist) < 0) if (check_control(playlist) < 0)
{ {
notify_control_access_error(); 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 * bunch of files from tagcache, syncing after every file wouldn't be
* a good thing to do. */ * a good thing to do. */
if (sync && result >= 0) if (sync && result >= 0)
{
playlist_sync(playlist); playlist_sync(playlist);
}
playlist_mutex_unlock(&(playlist->mutex)); playlist_mutex_unlock(&(playlist->mutex));
@ -2860,6 +2893,8 @@ int playlist_move(struct playlist_info* playlist, int index, int new_index)
goto out; goto out;
} }
dc_discard_playlist_pointers();
/* We want to insert the track at the position that was specified by /* 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 new_index. This may be different then new_index because of the
shifting that will occur after the delete. shifting that will occur after the delete.
@ -2975,6 +3010,8 @@ int playlist_next(int steps)
{ {
int i, j; int i, j;
dc_discard_playlist_pointers();
/* We need to delete all the queued songs */ /* We need to delete all the queued songs */
for (i=0, j=steps; i<j; i++) for (i=0, j=steps; i<j; i++)
{ {
@ -3153,6 +3190,8 @@ int playlist_remove_all_tracks(struct playlist_info *playlist)
if (playlist == NULL) if (playlist == NULL)
playlist = &current_playlist; playlist = &current_playlist;
dc_discard_playlist_pointers();
while (playlist->index > 0) while (playlist->index > 0)
if ((result = remove_track_from_playlist(playlist, 0, true)) < 0) if ((result = remove_track_from_playlist(playlist, 0, true)) < 0)
return result; return result;
@ -3762,6 +3801,7 @@ int playlist_save(struct playlist_info* playlist, char *filename,
close(playlist->fd); close(playlist->fd);
playlist->fd = fd; playlist->fd = fd;
fd = -1; fd = -1;
dc_discard_playlist_pointers();
if (!reparse) if (!reparse)
{ {
@ -3787,6 +3827,7 @@ int playlist_save(struct playlist_info* playlist, char *filename,
/* we need to recreate control because inserted tracks are /* we need to recreate control because inserted tracks are
now part of the playlist and shuffle has been invalidated */ now part of the playlist and shuffle has been invalidated */
result = recreate_control_unlocked(playlist); result = recreate_control_unlocked(playlist);
dc_load_playlist_pointers();
} }
} }