summaryrefslogtreecommitdiff
path: root/apps/playlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playlist.c')
-rw-r--r--apps/playlist.c95
1 files changed, 63 insertions, 32 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index 77d8141af8..f6dda977f4 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -993,14 +993,14 @@ static int sort_playlist(struct playlist_info* playlist, bool start_current,
993 unsigned int current = playlist->indices[playlist->index]; 993 unsigned int current = playlist->indices[playlist->index];
994 994
995 if (playlist->amount > 0) 995 if (playlist->amount > 0)
996 qsort(playlist->indices, playlist->amount, 996 qsort((void*)playlist->indices, playlist->amount,
997 sizeof(playlist->indices[0]), compare); 997 sizeof(playlist->indices[0]), compare);
998 998
999#ifdef HAVE_DIRCACHE 999#ifdef HAVE_DIRCACHE
1000 /** We need to re-check the song names from disk because qsort can't 1000 /** We need to re-check the song names from disk because qsort can't
1001 * sort two arrays at once :/ 1001 * sort two arrays at once :/
1002 * FIXME: Please implement a better way to do this. */ 1002 * FIXME: Please implement a better way to do this. */
1003 memset(playlist->filenames, 0xff, playlist->max_playlist_size * sizeof(int)); 1003 memset((void*)playlist->filenames, 0xff, playlist->max_playlist_size * sizeof(int));
1004 queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0); 1004 queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0);
1005#endif 1005#endif
1006 1006
@@ -1378,7 +1378,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1378 1378
1379 if (playlist->in_ram && !control_file && max < 0) 1379 if (playlist->in_ram && !control_file && max < 0)
1380 { 1380 {
1381 max = strlcpy(tmp_buf, &playlist->buffer[seek], sizeof(tmp_buf)); 1381 max = strlcpy(tmp_buf, (char*)&playlist->buffer[seek], sizeof(tmp_buf));
1382 } 1382 }
1383 else if (max < 0) 1383 else if (max < 0)
1384 { 1384 {
@@ -1534,9 +1534,10 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1534 break; 1534 break;
1535 } 1535 }
1536 1536
1537 files = tc->cache.entries; 1537 files = tree_get_entries(tc);
1538 num_files = tc->filesindir; 1538 num_files = tc->filesindir;
1539 1539
1540 tree_lock_cache(tc);
1540 for (i=0; i<num_files; i++) 1541 for (i=0; i<num_files; i++)
1541 { 1542 {
1542 /* user abort */ 1543 /* user abort */
@@ -1562,6 +1563,7 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1562 start_dir = NULL; 1563 start_dir = NULL;
1563 } 1564 }
1564 } 1565 }
1566 tree_unlock_cache(tc);
1565 1567
1566 if (!exit) 1568 if (!exit)
1567 { 1569 {
@@ -1612,7 +1614,7 @@ static int check_subdir_for_music(char *dir, const char *subdir, bool recurse)
1612 return -2; 1614 return -2;
1613 } 1615 }
1614 1616
1615 files = tc->cache.entries; 1617 files = tree_get_entries(tc);
1616 num_files = tc->filesindir; 1618 num_files = tc->filesindir;
1617 1619
1618 for (i=0; i<num_files; i++) 1620 for (i=0; i<num_files; i++)
@@ -1629,6 +1631,7 @@ static int check_subdir_for_music(char *dir, const char *subdir, bool recurse)
1629 if (has_music) 1631 if (has_music)
1630 return 0; 1632 return 0;
1631 1633
1634 tree_lock_cache(tc);
1632 if (has_subdir && recurse) 1635 if (has_subdir && recurse)
1633 { 1636 {
1634 for (i=0; i<num_files; i++) 1637 for (i=0; i<num_files; i++)
@@ -1647,6 +1650,7 @@ static int check_subdir_for_music(char *dir, const char *subdir, bool recurse)
1647 } 1650 }
1648 } 1651 }
1649 } 1652 }
1653 tree_unlock_cache(tc);
1650 1654
1651 if (result < 0) 1655 if (result < 0)
1652 { 1656 {
@@ -1925,6 +1929,31 @@ static int rotate_index(const struct playlist_info* playlist, int index)
1925} 1929}
1926 1930
1927/* 1931/*
1932 * Need no movement protection since all 3 allocations are not passed to
1933 * other functions which can yield().
1934 */
1935static int move_callback(int handle, void* current, void* new)
1936{
1937 (void)handle;
1938 struct playlist_info* playlist = &current_playlist;
1939 if (current == playlist->indices)
1940 playlist->indices = new;
1941 else if (current == playlist->filenames)
1942 playlist->filenames = new;
1943 /* buffer can possibly point to a new buffer temporarily (playlist_save()).
1944 * just don't overwrite the pointer to that temp buffer */
1945 else if (current == playlist->buffer)
1946 playlist->buffer = new;
1947
1948 return BUFLIB_CB_OK;
1949}
1950
1951
1952static struct buflib_callbacks ops = {
1953 .move_callback = move_callback,
1954 .shrink_callback = NULL,
1955};
1956/*
1928 * Initialize playlist entries at startup 1957 * Initialize playlist entries at startup
1929 */ 1958 */
1930void playlist_init(void) 1959void playlist_init(void)
@@ -1941,20 +1970,23 @@ void playlist_init(void)
1941 playlist->fd = -1; 1970 playlist->fd = -1;
1942 playlist->control_fd = -1; 1971 playlist->control_fd = -1;
1943 playlist->max_playlist_size = global_settings.max_files_in_playlist; 1972 playlist->max_playlist_size = global_settings.max_files_in_playlist;
1944 handle = core_alloc("playlist idx", playlist->max_playlist_size * sizeof(int)); 1973 handle = core_alloc_ex("playlist idx",
1974 playlist->max_playlist_size * sizeof(int), &ops);
1945 playlist->indices = core_get_data(handle); 1975 playlist->indices = core_get_data(handle);
1946 playlist->buffer_size = 1976 playlist->buffer_size =
1947 AVERAGE_FILENAME_LENGTH * global_settings.max_files_in_dir; 1977 AVERAGE_FILENAME_LENGTH * global_settings.max_files_in_dir;
1948 handle = core_alloc("playlist buf", playlist->buffer_size); 1978 handle = core_alloc_ex("playlist buf",
1979 playlist->buffer_size, &ops);
1949 playlist->buffer = core_get_data(handle); 1980 playlist->buffer = core_get_data(handle);
1950 playlist->control_mutex = &current_playlist_mutex; 1981 playlist->control_mutex = &current_playlist_mutex;
1951 1982
1952 empty_playlist(playlist, true); 1983 empty_playlist(playlist, true);
1953 1984
1954#ifdef HAVE_DIRCACHE 1985#ifdef HAVE_DIRCACHE
1955 handle = core_alloc("playlist dc", playlist->max_playlist_size * sizeof(int)); 1986 handle = core_alloc_ex("playlist dc",
1987 playlist->max_playlist_size * sizeof(int), &ops);
1956 playlist->filenames = core_get_data(handle); 1988 playlist->filenames = core_get_data(handle);
1957 memset(playlist->filenames, 0xff, 1989 memset((void*)playlist->filenames, 0xff,
1958 playlist->max_playlist_size * sizeof(int)); 1990 playlist->max_playlist_size * sizeof(int));
1959 create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack), 1991 create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack),
1960 0, playlist_thread_name IF_PRIO(, PRIORITY_BACKGROUND) 1992 0, playlist_thread_name IF_PRIO(, PRIORITY_BACKGROUND)
@@ -2404,7 +2436,7 @@ int playlist_add(const char *filename)
2404#endif 2436#endif
2405 playlist->amount++; 2437 playlist->amount++;
2406 2438
2407 strcpy(&playlist->buffer[playlist->buffer_end_pos], filename); 2439 strcpy((char*)&playlist->buffer[playlist->buffer_end_pos], filename);
2408 playlist->buffer_end_pos += len; 2440 playlist->buffer_end_pos += len;
2409 playlist->buffer[playlist->buffer_end_pos++] = '\0'; 2441 playlist->buffer[playlist->buffer_end_pos++] = '\0';
2410 2442
@@ -2731,6 +2763,7 @@ int playlist_create_ex(struct playlist_info* playlist,
2731 } 2763 }
2732 2764
2733 playlist->buffer_size = 0; 2765 playlist->buffer_size = 0;
2766 playlist->buffer_handle = -1;
2734 playlist->buffer = NULL; 2767 playlist->buffer = NULL;
2735 playlist->control_mutex = &created_playlist_mutex; 2768 playlist->control_mutex = &created_playlist_mutex;
2736 } 2769 }
@@ -2779,10 +2812,10 @@ int playlist_set_current(struct playlist_info* playlist)
2779 2812
2780 if (playlist->indices && playlist->indices != current_playlist.indices) 2813 if (playlist->indices && playlist->indices != current_playlist.indices)
2781 { 2814 {
2782 memcpy(current_playlist.indices, playlist->indices, 2815 memcpy((void*)current_playlist.indices, (void*)playlist->indices,
2783 playlist->max_playlist_size*sizeof(int)); 2816 playlist->max_playlist_size*sizeof(int));
2784#ifdef HAVE_DIRCACHE 2817#ifdef HAVE_DIRCACHE
2785 memcpy(current_playlist.filenames, playlist->filenames, 2818 memcpy((void*)current_playlist.filenames, (void*)playlist->filenames,
2786 playlist->max_playlist_size*sizeof(int)); 2819 playlist->max_playlist_size*sizeof(int));
2787#endif 2820#endif
2788 } 2821 }
@@ -3358,6 +3391,7 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3358 char tmp_buf[MAX_PATH+1]; 3391 char tmp_buf[MAX_PATH+1];
3359 int result = 0; 3392 int result = 0;
3360 bool overwrite_current = false; 3393 bool overwrite_current = false;
3394 int old_handle = -1;
3361 char* old_buffer = NULL; 3395 char* old_buffer = NULL;
3362 size_t old_buffer_size = 0; 3396 size_t old_buffer_size = 0;
3363 3397
@@ -3380,15 +3414,16 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3380 { 3414 {
3381 /* not enough buffer space to store updated indices */ 3415 /* not enough buffer space to store updated indices */
3382 /* Try to get a buffer */ 3416 /* Try to get a buffer */
3383 old_buffer = playlist->buffer; 3417 old_handle = playlist->buffer_handle;
3418 /* can ignore volatile here, because core_get_data() is called later */
3419 old_buffer = (char*)playlist->buffer;
3384 old_buffer_size = playlist->buffer_size; 3420 old_buffer_size = playlist->buffer_size;
3385 playlist->buffer = plugin_get_buffer((size_t*)&playlist->buffer_size); 3421 playlist->buffer = plugin_get_buffer((size_t*)&playlist->buffer_size);
3386 if (playlist->buffer_size < (int)(playlist->amount * sizeof(int))) 3422 if (playlist->buffer_size < (int)(playlist->amount * sizeof(int)))
3387 { 3423 {
3388 playlist->buffer = old_buffer;
3389 playlist->buffer_size = old_buffer_size;
3390 splash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); 3424 splash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR));
3391 return -1; 3425 result = -1;
3426 goto reset_old_buffer;
3392 } 3427 }
3393 } 3428 }
3394 3429
@@ -3409,12 +3444,8 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3409 if (fd < 0) 3444 if (fd < 0)
3410 { 3445 {
3411 splash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); 3446 splash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR));
3412 if (old_buffer != NULL) 3447 result = -1;
3413 { 3448 goto reset_old_buffer;
3414 playlist->buffer = old_buffer;
3415 playlist->buffer_size = old_buffer_size;
3416 }
3417 return -1;
3418 } 3449 }
3419 3450
3420 display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT), false); 3451 display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT), false);
@@ -3514,11 +3545,12 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3514 } 3545 }
3515 3546
3516 cpu_boost(false); 3547 cpu_boost(false);
3517 if (old_buffer != NULL) 3548
3518 { 3549reset_old_buffer:
3519 playlist->buffer = old_buffer; 3550 if (old_handle > 0)
3520 playlist->buffer_size = old_buffer_size; 3551 old_buffer = core_get_data(old_handle);
3521 } 3552 playlist->buffer = old_buffer;
3553 playlist->buffer_size = old_buffer_size;
3522 3554
3523 return result; 3555 return result;
3524} 3556}
@@ -3534,9 +3566,9 @@ int playlist_directory_tracksearch(const char* dirname, bool recurse,
3534 char buf[MAX_PATH+1]; 3566 char buf[MAX_PATH+1];
3535 int result = 0; 3567 int result = 0;
3536 int num_files = 0; 3568 int num_files = 0;
3537 int i; 3569 int i;;
3538 struct entry *files;
3539 struct tree_context* tc = tree_get_context(); 3570 struct tree_context* tc = tree_get_context();
3571 struct tree_cache* cache = &tc->cache;
3540 int old_dirfilter = *(tc->dirfilter); 3572 int old_dirfilter = *(tc->dirfilter);
3541 3573
3542 if (!callback) 3574 if (!callback)
@@ -3552,7 +3584,6 @@ int playlist_directory_tracksearch(const char* dirname, bool recurse,
3552 return -1; 3584 return -1;
3553 } 3585 }
3554 3586
3555 files = tc->cache.entries;
3556 num_files = tc->filesindir; 3587 num_files = tc->filesindir;
3557 3588
3558 /* we've overwritten the dircache so tree browser will need to be 3589 /* we've overwritten the dircache so tree browser will need to be
@@ -3568,6 +3599,7 @@ int playlist_directory_tracksearch(const char* dirname, bool recurse,
3568 break; 3599 break;
3569 } 3600 }
3570 3601
3602 struct entry *files = core_get_data(cache->entries_handle);
3571 if (files[i].attr & ATTR_DIRECTORY) 3603 if (files[i].attr & ATTR_DIRECTORY)
3572 { 3604 {
3573 if (recurse) 3605 if (recurse)
@@ -3586,8 +3618,7 @@ int playlist_directory_tracksearch(const char* dirname, bool recurse,
3586 result = -1; 3618 result = -1;
3587 break; 3619 break;
3588 } 3620 }
3589 3621
3590 files = tc->cache.entries;
3591 num_files = tc->filesindir; 3622 num_files = tc->filesindir;
3592 if (!num_files) 3623 if (!num_files)
3593 { 3624 {