[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:
parent
16a32c576c
commit
00c7817c9c
1 changed files with 48 additions and 7 deletions
|
@ -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; i<j; i++)
|
||||
{
|
||||
|
@ -3153,6 +3190,8 @@ int playlist_remove_all_tracks(struct playlist_info *playlist)
|
|||
if (playlist == NULL)
|
||||
playlist = ¤t_playlist;
|
||||
|
||||
dc_discard_playlist_pointers();
|
||||
|
||||
while (playlist->index > 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue