summaryrefslogtreecommitdiff
path: root/apps/playlist.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2017-01-17 14:45:07 -0500
committerMichael Sevakis <jethead71@rockbox.org>2017-01-17 15:27:47 -0500
commit16a9f84571276a13f4cfd5c66db8cd63ce4e2e7f (patch)
treec1a746cbf9ef8b7780b8ffd06783c75a97941373 /apps/playlist.c
parenta931c76b3a46d1884e985a3bfc82b947521dab97 (diff)
downloadrockbox-16a9f84571276a13f4cfd5c66db8cd63ce4e2e7f.tar.gz
rockbox-16a9f84571276a13f4cfd5c66db8cd63ce4e2e7f.zip
Reenable database ramcache and playlist dircache
Playlist dircache references should be back in working order. Reenabling dircache references in the database ramcache is not yet done as it requires quite a bit of rework. Otherwise, the database in RAM is functional again. Some buffer compatibility changes have been made for database commit because the dircache buffer can no longer be stolen, only freed by an API call. Change-Id: Ib57c3e98cb23e798d4439e9da7ebd73826e733a4
Diffstat (limited to 'apps/playlist.c')
-rw-r--r--apps/playlist.c160
1 files changed, 89 insertions, 71 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index 015e41ae0e..176cfc3af7 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -106,8 +106,9 @@
106#include "plugin.h" /* To borrow a temp buffer to rewrite a .m3u8 file */ 106#include "plugin.h" /* To borrow a temp buffer to rewrite a .m3u8 file */
107#include "panic.h" 107#include "panic.h"
108#include "logdiskf.h" 108#include "logdiskf.h"
109 109#ifdef HAVE_DIRCACHE
110#undef HAVE_DIRCACHE 110#include "dircache.h"
111#endif
111 112
112#define PLAYLIST_CONTROL_FILE_VERSION 2 113#define PLAYLIST_CONTROL_FILE_VERSION 2
113 114
@@ -205,6 +206,25 @@ static const char playlist_thread_name[] = "playlist cachectrl";
205static struct mutex current_playlist_mutex SHAREDBSS_ATTR; 206static struct mutex current_playlist_mutex SHAREDBSS_ATTR;
206static struct mutex created_playlist_mutex SHAREDBSS_ATTR; 207static struct mutex created_playlist_mutex SHAREDBSS_ATTR;
207 208
209#ifdef HAVE_DIRCACHE
210static void copy_filerefs(struct dircache_fileref *dcfto,
211 const struct dircache_fileref *dcffrom,
212 int count)
213{
214 if (!dcfto)
215 return;
216
217 if (dcffrom)
218 memmove(dcfto, dcffrom, count * sizeof (*dcfto));
219 else
220 {
221 /* just initialize the destination */
222 for (int i = 0; i < count; i++, dcfto++)
223 dircache_fileref_init(dcfto);
224 }
225}
226#endif /* HAVE_DIRCACHE */
227
208/* Check if the filename suggests M3U or M3U8 format. */ 228/* Check if the filename suggests M3U or M3U8 format. */
209static bool is_m3u8(const char* filename) 229static bool is_m3u8(const char* filename)
210{ 230{
@@ -401,6 +421,8 @@ static int recreate_control(struct playlist_info* playlist)
401 int i; 421 int i;
402 int result = 0; 422 int result = 0;
403 423
424 temp_file[0] = 0;
425
404 if(playlist->control_fd >= 0) 426 if(playlist->control_fd >= 0)
405 { 427 {
406 char* dir = playlist->filename; 428 char* dir = playlist->filename;
@@ -408,6 +430,7 @@ static int recreate_control(struct playlist_info* playlist)
408 char c = playlist->filename[playlist->dirlen-1]; 430 char c = playlist->filename[playlist->dirlen-1];
409 431
410 close(playlist->control_fd); 432 close(playlist->control_fd);
433 playlist->control_fd = 0;
411 434
412 snprintf(temp_file, sizeof(temp_file), "%s_temp", 435 snprintf(temp_file, sizeof(temp_file), "%s_temp",
413 playlist->control_filename); 436 playlist->control_filename);
@@ -571,10 +594,9 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
571 594
572 /* Store a new entry */ 595 /* Store a new entry */
573 playlist->indices[ playlist->amount ] = i+count; 596 playlist->indices[ playlist->amount ] = i+count;
574#ifdef HAVE_DIRCACHE 597 #ifdef HAVE_DIRCACHE
575 if (playlist->filenames) 598 copy_filerefs(&playlist->dcfrefs[playlist->amount], NULL, 1);
576 playlist->filenames[ playlist->amount ] = -1; 599 #endif
577#endif
578 playlist->amount++; 600 playlist->amount++;
579 } 601 }
580 } 602 }
@@ -779,8 +801,8 @@ static int add_track_to_playlist(struct playlist_info* playlist,
779 { 801 {
780 playlist->indices[i] = playlist->indices[i-1]; 802 playlist->indices[i] = playlist->indices[i-1];
781#ifdef HAVE_DIRCACHE 803#ifdef HAVE_DIRCACHE
782 if (playlist->filenames) 804 if (playlist->dcfrefs)
783 playlist->filenames[i] = playlist->filenames[i-1]; 805 playlist->dcfrefs[i] = playlist->dcfrefs[i-1];
784#endif 806#endif
785 } 807 }
786 808
@@ -814,8 +836,7 @@ static int add_track_to_playlist(struct playlist_info* playlist,
814 playlist->indices[insert_position] = flags | seek_pos; 836 playlist->indices[insert_position] = flags | seek_pos;
815 837
816#ifdef HAVE_DIRCACHE 838#ifdef HAVE_DIRCACHE
817 if (playlist->filenames) 839 copy_filerefs(&playlist->dcfrefs[insert_position], NULL, 1);
818 playlist->filenames[insert_position] = -1;
819#endif 840#endif
820 841
821 playlist->amount++; 842 playlist->amount++;
@@ -886,8 +907,8 @@ static int remove_track_from_playlist(struct playlist_info* playlist,
886 { 907 {
887 playlist->indices[i] = playlist->indices[i+1]; 908 playlist->indices[i] = playlist->indices[i+1];
888#ifdef HAVE_DIRCACHE 909#ifdef HAVE_DIRCACHE
889 if (playlist->filenames) 910 if (playlist->dcfrefs)
890 playlist->filenames[i] = playlist->filenames[i+1]; 911 playlist->dcfrefs[i] = playlist->dcfrefs[i+1];
891#endif 912#endif
892 } 913 }
893 914
@@ -934,7 +955,6 @@ static int randomise_playlist(struct playlist_info* playlist,
934{ 955{
935 int count; 956 int count;
936 int candidate; 957 int candidate;
937 long store;
938 unsigned int current = playlist->indices[playlist->index]; 958 unsigned int current = playlist->indices[playlist->index];
939 959
940 /* seed 0 is used to identify sorted playlist for resume purposes */ 960 /* seed 0 is used to identify sorted playlist for resume purposes */
@@ -951,15 +971,15 @@ static int randomise_playlist(struct playlist_info* playlist,
951 candidate = rand() % (count + 1); 971 candidate = rand() % (count + 1);
952 972
953 /* now swap the values at the 'count' and 'candidate' positions */ 973 /* now swap the values at the 'count' and 'candidate' positions */
954 store = playlist->indices[candidate]; 974 int indextmp = playlist->indices[candidate];
955 playlist->indices[candidate] = playlist->indices[count]; 975 playlist->indices[candidate] = playlist->indices[count];
956 playlist->indices[count] = store; 976 playlist->indices[count] = indextmp;
957#ifdef HAVE_DIRCACHE 977#ifdef HAVE_DIRCACHE
958 if (playlist->filenames) 978 if (playlist->dcfrefs)
959 { 979 {
960 store = playlist->filenames[candidate]; 980 struct dircache_fileref dcftmp = playlist->dcfrefs[candidate];
961 playlist->filenames[candidate] = playlist->filenames[count]; 981 playlist->dcfrefs[candidate] = playlist->dcfrefs[count];
962 playlist->filenames[count] = store; 982 playlist->dcfrefs[count] = dcftmp;
963 } 983 }
964#endif 984#endif
965 } 985 }
@@ -1001,7 +1021,7 @@ static int sort_playlist(struct playlist_info* playlist, bool start_current,
1001 /** We need to re-check the song names from disk because qsort can't 1021 /** We need to re-check the song names from disk because qsort can't
1002 * sort two arrays at once :/ 1022 * sort two arrays at once :/
1003 * FIXME: Please implement a better way to do this. */ 1023 * FIXME: Please implement a better way to do this. */
1004 memset((void*)playlist->filenames, 0xff, playlist->max_playlist_size * sizeof(int)); 1024 copy_filerefs(playlist->dcfrefs, NULL, playlist->max_playlist_size);
1005 queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0); 1025 queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0);
1006#endif 1026#endif
1007 1027
@@ -1245,11 +1265,6 @@ static void playlist_flush_callback(void)
1245 } 1265 }
1246} 1266}
1247 1267
1248static bool is_dircache_pointers_intact(void)
1249{
1250 return dircache_get_appflag(DIRCACHE_APPFLAG_PLAYLIST) ? true : false;
1251}
1252
1253static void playlist_thread(void) 1268static void playlist_thread(void)
1254{ 1269{
1255 struct queue_event ev; 1270 struct queue_event ev;
@@ -1290,24 +1305,26 @@ static void playlist_thread(void)
1290 register_storage_idle_func(playlist_flush_callback); 1305 register_storage_idle_func(playlist_flush_callback);
1291 } 1306 }
1292 1307
1293 if (!dircache_is_enabled() || !playlist->filenames 1308 if (!playlist->dcfrefs || playlist->amount <= 0)
1294 || playlist->amount <= 0)
1295 {
1296 break ; 1309 break ;
1297 }
1298 1310
1299 /* Check if previously loaded pointers are intact. */ 1311 /* Check if previously loaded pointers are intact. */
1300 if (is_dircache_pointers_intact() && !dirty_pointers) 1312 if (!dirty_pointers)
1301 break ; 1313 break ;
1302 1314
1303#ifdef HAVE_ADJUSTABLE_CPU_FREQ 1315 struct dircache_info info;
1304 cpu_boost(true); 1316 dircache_get_info(&info);
1305#endif 1317
1318 if (info.status != DIRCACHE_READY)
1319 break ;
1320
1321 trigger_cpu_boost();
1322
1306 for (index = 0; index < playlist->amount 1323 for (index = 0; index < playlist->amount
1307 && queue_empty(&playlist_queue); index++) 1324 && queue_empty(&playlist_queue); index++)
1308 { 1325 {
1309 /* Process only pointers that are not already loaded. */ 1326 /* Process only pointers that are superficially stale. */
1310 if (is_dircache_pointers_intact() && playlist->filenames[index] >= 0) 1327 if (dircache_search(DCS_FILEREF, &playlist->dcfrefs[index], NULL) == 0)
1311 continue ; 1328 continue ;
1312 1329
1313 control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; 1330 control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
@@ -1320,19 +1337,16 @@ static void playlist_thread(void)
1320 break ; 1337 break ;
1321 } 1338 }
1322 1339
1323 /* Set the dircache entry pointer. */ 1340 /* Obtain the dircache file entry cookie. */
1324 playlist->filenames[index] = dircache_get_entry_id(tmp); 1341 dircache_search(DCS_CACHED_PATH | DCS_UPDATE_FILEREF,
1342 &playlist->dcfrefs[index], tmp);
1325 1343
1326 /* And be on background so user doesn't notice any delays. */ 1344 /* And be on background so user doesn't notice any delays. */
1327 yield(); 1345 yield();
1328 } 1346 }
1329 1347
1330 if (dircache_is_enabled()) 1348 cancel_cpu_boost();
1331 dircache_set_appflag(DIRCACHE_APPFLAG_PLAYLIST); 1349
1332
1333#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1334 cpu_boost(false);
1335#endif
1336 if (index == playlist->amount) 1350 if (index == playlist->amount)
1337 dirty_pointers = false; 1351 dirty_pointers = false;
1338 1352
@@ -1364,17 +1378,12 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1364 buf_length = MAX_PATH+1; 1378 buf_length = MAX_PATH+1;
1365 1379
1366#ifdef HAVE_DIRCACHE 1380#ifdef HAVE_DIRCACHE
1367 if (is_dircache_pointers_intact() && playlist->filenames) 1381 if (playlist->dcfrefs)
1368 { 1382 {
1369 if (playlist->filenames[index] >= 0) 1383 max = dircache_get_fileref_path(&playlist->dcfrefs[index],
1370 { 1384 tmp_buf, sizeof(tmp_buf));
1371 max = dircache_copy_path(playlist->filenames[index],
1372 tmp_buf, sizeof(tmp_buf)-1);
1373 }
1374 } 1385 }
1375#else 1386#endif /* HAVE_DIRCACHE */
1376 (void)index;
1377#endif
1378 1387
1379 if (playlist->in_ram && !control_file && max < 0) 1388 if (playlist->in_ram && !control_file && max < 0)
1380 { 1389 {
@@ -1406,12 +1415,16 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1406 { 1415 {
1407 max = read(fd, tmp_buf, MIN((size_t) buf_length, sizeof(tmp_buf))); 1416 max = read(fd, tmp_buf, MIN((size_t) buf_length, sizeof(tmp_buf)));
1408 1417
1409 if ((max > 0) && !utf8) 1418 if (max > 0)
1410 { 1419 {
1420 /* playlist file may end without a new line - terminate buffer */
1421 tmp_buf[MIN(max, (int)sizeof(tmp_buf) - 1)] = '\0';
1422
1411 /* Use dir_buf as a temporary buffer. Note that dir_buf must 1423 /* Use dir_buf as a temporary buffer. Note that dir_buf must
1412 * be as large as tmp_buf. 1424 * be as large as tmp_buf.
1413 */ 1425 */
1414 max = convert_m3u(tmp_buf, max, sizeof(tmp_buf), dir_buf); 1426 if (!utf8)
1427 max = convert_m3u(tmp_buf, max, sizeof(tmp_buf), dir_buf);
1415 } 1428 }
1416 } 1429 }
1417 } 1430 }
@@ -1432,6 +1445,8 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1432 strlcpy(dir_buf, playlist->filename, playlist->dirlen); 1445 strlcpy(dir_buf, playlist->filename, playlist->dirlen);
1433 1446
1434 return format_track_path(buf, tmp_buf, buf_length, dir_buf); 1447 return format_track_path(buf, tmp_buf, buf_length, dir_buf);
1448
1449 (void)index;
1435} 1450}
1436 1451
1437static int get_next_directory(char *dir){ 1452static int get_next_directory(char *dir){
@@ -1974,11 +1989,12 @@ static int move_callback(int handle, void* current, void* new)
1974 struct playlist_info* playlist = &current_playlist; 1989 struct playlist_info* playlist = &current_playlist;
1975 if (current == playlist->indices) 1990 if (current == playlist->indices)
1976 playlist->indices = new; 1991 playlist->indices = new;
1977 else if (current == playlist->filenames)
1978 playlist->filenames = new;
1979 else if (current == playlist->buffer) 1992 else if (current == playlist->buffer)
1980 playlist->buffer = new; 1993 playlist->buffer = new;
1981 1994#ifdef HAVE_DIRCACHE
1995 else if (current == playlist->dcfrefs)
1996 playlist->dcfrefs = new;
1997#endif /* HAVE_DIRCACHE */
1982 return BUFLIB_CB_OK; 1998 return BUFLIB_CB_OK;
1983} 1999}
1984 2000
@@ -2019,15 +2035,15 @@ void playlist_init(void)
2019 2035
2020#ifdef HAVE_DIRCACHE 2036#ifdef HAVE_DIRCACHE
2021 handle = core_alloc_ex("playlist dc", 2037 handle = core_alloc_ex("playlist dc",
2022 playlist->max_playlist_size * sizeof(int), &ops); 2038 playlist->max_playlist_size * sizeof(*playlist->dcfrefs), &ops);
2023 playlist->filenames = core_get_data(handle); 2039 playlist->dcfrefs = core_get_data(handle);
2024 memset((void*)playlist->filenames, 0xff, 2040 copy_filerefs(playlist->dcfrefs, NULL, playlist->max_playlist_size);
2025 playlist->max_playlist_size * sizeof(int));
2026 create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack), 2041 create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack),
2027 0, playlist_thread_name IF_PRIO(, PRIORITY_BACKGROUND) 2042 0, playlist_thread_name IF_PRIO(, PRIORITY_BACKGROUND)
2028 IF_COP(, CPU)); 2043 IF_COP(, CPU));
2044
2029 queue_init(&playlist_queue, true); 2045 queue_init(&playlist_queue, true);
2030#endif 2046#endif /* HAVE_DIRCACHE */
2031} 2047}
2032 2048
2033/* 2049/*
@@ -2513,8 +2529,9 @@ int playlist_add(const char *filename)
2513 2529
2514 playlist->indices[playlist->amount] = playlist->buffer_end_pos; 2530 playlist->indices[playlist->amount] = playlist->buffer_end_pos;
2515#ifdef HAVE_DIRCACHE 2531#ifdef HAVE_DIRCACHE
2516 playlist->filenames[playlist->amount] = -1; 2532 copy_filerefs(&playlist->dcfrefs[playlist->amount], NULL, 1);
2517#endif 2533#endif
2534
2518 playlist->amount++; 2535 playlist->amount++;
2519 2536
2520 strcpy((char*)&playlist->buffer[playlist->buffer_end_pos], filename); 2537 strcpy((char*)&playlist->buffer[playlist->buffer_end_pos], filename);
@@ -2863,18 +2880,19 @@ int playlist_create_ex(struct playlist_info* playlist,
2863 2880
2864 if (index_buffer) 2881 if (index_buffer)
2865 { 2882 {
2866 int num_indices = index_buffer_size / sizeof(int); 2883 size_t unit_size = sizeof (*playlist->indices);
2867
2868#ifdef HAVE_DIRCACHE 2884#ifdef HAVE_DIRCACHE
2869 num_indices /= 2; 2885 unit_size += sizeof (*playlist->dcfrefs);
2870#endif 2886#endif
2887 int num_indices = index_buffer_size / unit_size;
2888
2871 if (num_indices > global_settings.max_files_in_playlist) 2889 if (num_indices > global_settings.max_files_in_playlist)
2872 num_indices = global_settings.max_files_in_playlist; 2890 num_indices = global_settings.max_files_in_playlist;
2873 2891
2874 playlist->max_playlist_size = num_indices; 2892 playlist->max_playlist_size = num_indices;
2875 playlist->indices = index_buffer; 2893 playlist->indices = index_buffer;
2876#ifdef HAVE_DIRCACHE 2894#ifdef HAVE_DIRCACHE
2877 playlist->filenames = (int*)&playlist->indices[num_indices]; 2895 playlist->dcfrefs = (void *)&playlist->indices[num_indices];
2878#endif 2896#endif
2879 } 2897 }
2880 else 2898 else
@@ -2882,7 +2900,7 @@ int playlist_create_ex(struct playlist_info* playlist,
2882 playlist->max_playlist_size = current_playlist.max_playlist_size; 2900 playlist->max_playlist_size = current_playlist.max_playlist_size;
2883 playlist->indices = current_playlist.indices; 2901 playlist->indices = current_playlist.indices;
2884#ifdef HAVE_DIRCACHE 2902#ifdef HAVE_DIRCACHE
2885 playlist->filenames = current_playlist.filenames; 2903 playlist->dcfrefs = current_playlist.dcfrefs;
2886#endif 2904#endif
2887 } 2905 }
2888 2906
@@ -2942,8 +2960,8 @@ int playlist_set_current(struct playlist_info* playlist)
2942 memcpy((void*)current_playlist.indices, (void*)playlist->indices, 2960 memcpy((void*)current_playlist.indices, (void*)playlist->indices,
2943 playlist->max_playlist_size*sizeof(int)); 2961 playlist->max_playlist_size*sizeof(int));
2944#ifdef HAVE_DIRCACHE 2962#ifdef HAVE_DIRCACHE
2945 memcpy((void*)current_playlist.filenames, (void*)playlist->filenames, 2963 copy_filerefs(current_playlist.dcfrefs, playlist->dcfrefs,
2946 playlist->max_playlist_size*sizeof(int)); 2964 playlist->max_playlist_size);
2947#endif 2965#endif
2948 } 2966 }
2949 2967