summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2023-01-12 06:52:09 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2023-01-12 19:36:38 -0500
commit00c7817c9c326368c2cd89f1e786584283935c9c (patch)
tree882c1abd6de5025cad8dc1f64ad06fd6dbddfffd /apps
parent16a32c576c3c8a6d1ab375a4f1f4c4c0595f49ee (diff)
downloadrockbox-00c7817c9c326368c2cd89f1e786584283935c9c.tar.gz
rockbox-00c7817c9c326368c2cd89f1e786584283935c9c.zip
[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
Diffstat (limited to 'apps')
-rw-r--r--apps/playlist.c55
1 files 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;
172 172
173#ifdef HAVE_DIRCACHE 173#ifdef HAVE_DIRCACHE
174#define PLAYLIST_LOAD_POINTERS 1 174#define PLAYLIST_LOAD_POINTERS 1
175#define PLAYLIST_CLEAN_POINTERS 2
176static bool dc_has_dirty_pointers = false;
175 177
176static struct event_queue playlist_queue SHAREDBSS_ATTR; 178static struct event_queue playlist_queue SHAREDBSS_ATTR;
177static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; 179static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
@@ -221,6 +223,16 @@ static void dc_load_playlist_pointers(void)
221/* No-Op for non dircache targets */ 223/* No-Op for non dircache targets */
222} 224}
223 225
226static void dc_discard_playlist_pointers(void)
227{
228#ifdef HAVE_DIRCACHE
229 /* dump any pointers currently waiting */
230 if (dc_has_dirty_pointers)
231 queue_send(&playlist_queue, PLAYLIST_CLEAN_POINTERS, 0);
232#endif
233/* No-Op for non dircache targets */
234}
235
224static void close_playlist_control_file(struct playlist_info *playlist) 236static void close_playlist_control_file(struct playlist_info *playlist)
225{ 237{
226 playlist_mutex_lock(&(playlist->mutex)); 238 playlist_mutex_lock(&(playlist->mutex));
@@ -494,6 +506,7 @@ static void update_playlist_filename_unlocked(struct playlist_info* playlist,
494 */ 506 */
495static void empty_playlist_unlocked(struct playlist_info* playlist, bool resume) 507static void empty_playlist_unlocked(struct playlist_info* playlist, bool resume)
496{ 508{
509 dc_discard_playlist_pointers();
497 510
498 if(playlist->fd >= 0) /* If there is an already open playlist, close it. */ 511 if(playlist->fd >= 0) /* If there is an already open playlist, close it. */
499 { 512 {
@@ -884,7 +897,6 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
884exit: 897exit:
885 898
886 playlist_mutex_unlock(&(playlist->mutex)); 899 playlist_mutex_unlock(&(playlist->mutex));
887 dc_load_playlist_pointers();
888 900
889 return result; 901 return result;
890} 902}
@@ -1512,6 +1524,7 @@ static int remove_track_from_playlist(struct playlist_info* playlist,
1512 return -1; 1524 return -1;
1513 1525
1514 playlist_mutex_lock(&(playlist->mutex)); 1526 playlist_mutex_lock(&(playlist->mutex));
1527
1515 inserted = playlist->indices[position] & PLAYLIST_INSERT_TYPE_MASK; 1528 inserted = playlist->indices[position] & PLAYLIST_INSERT_TYPE_MASK;
1516 1529
1517 /* shift indices now that track has been removed */ 1530 /* shift indices now that track has been removed */
@@ -1590,6 +1603,8 @@ static int randomise_playlist(struct playlist_info* playlist,
1590 1603
1591 playlist_mutex_lock(&(playlist->mutex)); 1604 playlist_mutex_lock(&(playlist->mutex));
1592 1605
1606 dc_discard_playlist_pointers();
1607
1593 /* seed 0 is used to identify sorted playlist for resume purposes */ 1608 /* seed 0 is used to identify sorted playlist for resume purposes */
1594 if (seed == 0) 1609 if (seed == 0)
1595 seed = 1; 1610 seed = 1;
@@ -1673,9 +1688,10 @@ static int sort_compare_fn(const void* p1, const void* p2)
1673static int sort_playlist_unlocked(struct playlist_info* playlist, 1688static int sort_playlist_unlocked(struct playlist_info* playlist,
1674 bool start_current, bool write) 1689 bool start_current, bool write)
1675{ 1690{
1676
1677 unsigned int current = playlist->indices[playlist->index]; 1691 unsigned int current = playlist->indices[playlist->index];
1678 1692
1693 dc_discard_playlist_pointers();
1694
1679 if (playlist->amount > 0) 1695 if (playlist->amount > 0)
1680 qsort((void*)playlist->indices, playlist->amount, 1696 qsort((void*)playlist->indices, playlist->amount,
1681 sizeof(playlist->indices[0]), sort_compare_fn); 1697 sizeof(playlist->indices[0]), sort_compare_fn);
@@ -1875,7 +1891,6 @@ static void dc_flush_playlist_callback(void)
1875static void dc_thread_playlist(void) 1891static void dc_thread_playlist(void)
1876{ 1892{
1877 struct queue_event ev; 1893 struct queue_event ev;
1878 bool dirty_pointers = false;
1879 static char tmp[MAX_PATH+1]; 1894 static char tmp[MAX_PATH+1];
1880 1895
1881 struct playlist_info *playlist; 1896 struct playlist_info *playlist;
@@ -1897,8 +1912,13 @@ static void dc_thread_playlist(void)
1897 1912
1898 switch (ev.id) 1913 switch (ev.id)
1899 { 1914 {
1915 case PLAYLIST_CLEAN_POINTERS:
1916 dc_has_dirty_pointers = false;
1917 queue_reply(&playlist_queue, 0);
1918 break;
1919
1900 case PLAYLIST_LOAD_POINTERS: 1920 case PLAYLIST_LOAD_POINTERS:
1901 dirty_pointers = true; 1921 dc_has_dirty_pointers = true;
1902 break ; 1922 break ;
1903 1923
1904 /* Start the background scanning after either the disk spindown 1924 /* Start the background scanning after either the disk spindown
@@ -1916,7 +1936,7 @@ static void dc_thread_playlist(void)
1916 break ; 1936 break ;
1917 1937
1918 /* Check if previously loaded pointers are intact. */ 1938 /* Check if previously loaded pointers are intact. */
1919 if (!dirty_pointers) 1939 if (!dc_has_dirty_pointers)
1920 break ; 1940 break ;
1921 1941
1922 struct dircache_info info; 1942 struct dircache_info info;
@@ -1955,7 +1975,7 @@ static void dc_thread_playlist(void)
1955 cancel_cpu_boost(); 1975 cancel_cpu_boost();
1956 1976
1957 if (index == playlist->amount) 1977 if (index == playlist->amount)
1958 dirty_pointers = false; 1978 dc_has_dirty_pointers = false;
1959 1979
1960 break ; 1980 break ;
1961 } 1981 }
@@ -2188,9 +2208,11 @@ int playlist_create_ex(struct playlist_info* playlist,
2188 new_playlist_unlocked(playlist, dir, file); 2208 new_playlist_unlocked(playlist, dir, file);
2189 2209
2190 if (file) 2210 if (file)
2211 {
2191 /* load the playlist file */ 2212 /* load the playlist file */
2192 add_indices_to_playlist(playlist, temp_buffer, temp_buffer_size); 2213 add_indices_to_playlist(playlist, temp_buffer, temp_buffer_size);
2193 2214 dc_load_playlist_pointers();
2215 }
2194 return 0; 2216 return 0;
2195} 2217}
2196 2218
@@ -2215,6 +2237,7 @@ int playlist_create(const char *dir, const char *file)
2215 buflen = ALIGN_DOWN(buflen, 512); /* to avoid partial sector I/O */ 2237 buflen = ALIGN_DOWN(buflen, 512); /* to avoid partial sector I/O */
2216 /* load the playlist file */ 2238 /* load the playlist file */
2217 add_indices_to_playlist(playlist, buf, buflen); 2239 add_indices_to_playlist(playlist, buf, buflen);
2240 dc_load_playlist_pointers();
2218 core_free(handle); 2241 core_free(handle);
2219 } 2242 }
2220 else 2243 else
@@ -2285,6 +2308,8 @@ int playlist_delete(struct playlist_info* playlist, int index)
2285 return -1; 2308 return -1;
2286 } 2309 }
2287 2310
2311 dc_discard_playlist_pointers();
2312
2288 if (index == PLAYLIST_DELETE_CURRENT) 2313 if (index == PLAYLIST_DELETE_CURRENT)
2289 index = playlist->index; 2314 index = playlist->index;
2290 2315
@@ -2570,6 +2595,8 @@ int playlist_insert_directory(struct playlist_info* playlist,
2570 return -1; 2595 return -1;
2571 } 2596 }
2572 2597
2598 dc_discard_playlist_pointers();
2599
2573 if (queue) 2600 if (queue)
2574 count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); 2601 count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT);
2575 else 2602 else
@@ -2622,6 +2649,8 @@ int playlist_insert_playlist(struct playlist_info* playlist, const char *filenam
2622 2649
2623 playlist_mutex_lock(&(playlist->mutex)); 2650 playlist_mutex_lock(&(playlist->mutex));
2624 2651
2652 dc_discard_playlist_pointers();
2653
2625 cpu_boost(true); 2654 cpu_boost(true);
2626 2655
2627 if (check_control(playlist) < 0) 2656 if (check_control(playlist) < 0)
@@ -2750,6 +2779,8 @@ int playlist_insert_track(struct playlist_info* playlist, const char *filename,
2750 2779
2751 playlist_mutex_lock(&(playlist->mutex)); 2780 playlist_mutex_lock(&(playlist->mutex));
2752 2781
2782 dc_discard_playlist_pointers();
2783
2753 if (check_control(playlist) < 0) 2784 if (check_control(playlist) < 0)
2754 { 2785 {
2755 notify_control_access_error(); 2786 notify_control_access_error();
@@ -2763,7 +2794,9 @@ int playlist_insert_track(struct playlist_info* playlist, const char *filename,
2763 * bunch of files from tagcache, syncing after every file wouldn't be 2794 * bunch of files from tagcache, syncing after every file wouldn't be
2764 * a good thing to do. */ 2795 * a good thing to do. */
2765 if (sync && result >= 0) 2796 if (sync && result >= 0)
2797 {
2766 playlist_sync(playlist); 2798 playlist_sync(playlist);
2799 }
2767 2800
2768 playlist_mutex_unlock(&(playlist->mutex)); 2801 playlist_mutex_unlock(&(playlist->mutex));
2769 2802
@@ -2860,6 +2893,8 @@ int playlist_move(struct playlist_info* playlist, int index, int new_index)
2860 goto out; 2893 goto out;
2861 } 2894 }
2862 2895
2896 dc_discard_playlist_pointers();
2897
2863 /* We want to insert the track at the position that was specified by 2898 /* We want to insert the track at the position that was specified by
2864 new_index. This may be different then new_index because of the 2899 new_index. This may be different then new_index because of the
2865 shifting that will occur after the delete. 2900 shifting that will occur after the delete.
@@ -2975,6 +3010,8 @@ int playlist_next(int steps)
2975 { 3010 {
2976 int i, j; 3011 int i, j;
2977 3012
3013 dc_discard_playlist_pointers();
3014
2978 /* We need to delete all the queued songs */ 3015 /* We need to delete all the queued songs */
2979 for (i=0, j=steps; i<j; i++) 3016 for (i=0, j=steps; i<j; i++)
2980 { 3017 {
@@ -3153,6 +3190,8 @@ int playlist_remove_all_tracks(struct playlist_info *playlist)
3153 if (playlist == NULL) 3190 if (playlist == NULL)
3154 playlist = &current_playlist; 3191 playlist = &current_playlist;
3155 3192
3193 dc_discard_playlist_pointers();
3194
3156 while (playlist->index > 0) 3195 while (playlist->index > 0)
3157 if ((result = remove_track_from_playlist(playlist, 0, true)) < 0) 3196 if ((result = remove_track_from_playlist(playlist, 0, true)) < 0)
3158 return result; 3197 return result;
@@ -3762,6 +3801,7 @@ int playlist_save(struct playlist_info* playlist, char *filename,
3762 close(playlist->fd); 3801 close(playlist->fd);
3763 playlist->fd = fd; 3802 playlist->fd = fd;
3764 fd = -1; 3803 fd = -1;
3804 dc_discard_playlist_pointers();
3765 3805
3766 if (!reparse) 3806 if (!reparse)
3767 { 3807 {
@@ -3787,6 +3827,7 @@ int playlist_save(struct playlist_info* playlist, char *filename,
3787 /* we need to recreate control because inserted tracks are 3827 /* we need to recreate control because inserted tracks are
3788 now part of the playlist and shuffle has been invalidated */ 3828 now part of the playlist and shuffle has been invalidated */
3789 result = recreate_control_unlocked(playlist); 3829 result = recreate_control_unlocked(playlist);
3830 dc_load_playlist_pointers();
3790 } 3831 }
3791 } 3832 }
3792 3833