diff options
Diffstat (limited to 'apps/playlist.c')
-rw-r--r-- | apps/playlist.c | 95 |
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 | */ | ||
1935 | static int move_callback(int handle, void* current, void* new) | ||
1936 | { | ||
1937 | (void)handle; | ||
1938 | struct playlist_info* playlist = ¤t_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 | |||
1952 | static 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 | */ |
1930 | void playlist_init(void) | 1959 | void 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 = ¤t_playlist_mutex; | 1981 | playlist->control_mutex = ¤t_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 | { | 3549 | reset_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 | { |