diff options
author | William Wilgus <wilgus.william@gmail.com> | 2023-01-12 06:52:09 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2023-01-12 19:36:38 -0500 |
commit | 00c7817c9c326368c2cd89f1e786584283935c9c (patch) | |
tree | 882c1abd6de5025cad8dc1f64ad06fd6dbddfffd /apps | |
parent | 16a32c576c3c8a6d1ab375a4f1f4c4c0595f49ee (diff) | |
download | rockbox-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.c | 55 |
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 | ||
176 | static bool dc_has_dirty_pointers = false; | ||
175 | 177 | ||
176 | static struct event_queue playlist_queue SHAREDBSS_ATTR; | 178 | static struct event_queue playlist_queue SHAREDBSS_ATTR; |
177 | static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; | 179 | static 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 | ||
226 | static 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 | |||
224 | static void close_playlist_control_file(struct playlist_info *playlist) | 236 | static 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 | */ |
495 | static void empty_playlist_unlocked(struct playlist_info* playlist, bool resume) | 507 | static 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, | |||
884 | exit: | 897 | exit: |
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) | |||
1673 | static int sort_playlist_unlocked(struct playlist_info* playlist, | 1688 | static 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) | |||
1875 | static void dc_thread_playlist(void) | 1891 | static 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 = ¤t_playlist; | 3191 | playlist = ¤t_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 | ||