diff options
-rw-r--r-- | apps/playlist.c | 136 | ||||
-rw-r--r-- | apps/playlist.h | 2 |
2 files changed, 68 insertions, 70 deletions
diff --git a/apps/playlist.c b/apps/playlist.c index b56959fefc..7bdcafa69a 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -170,6 +170,25 @@ struct directory_search_context { | |||
170 | 170 | ||
171 | static struct playlist_info current_playlist; | 171 | static struct playlist_info current_playlist; |
172 | 172 | ||
173 | static void dc_init_filerefs(struct playlist_info *playlist, | ||
174 | int start, int count) | ||
175 | { | ||
176 | #ifdef HAVE_DIRCACHE | ||
177 | if (!playlist->dcfrefs_handle) | ||
178 | return; | ||
179 | |||
180 | struct dircache_fileref *dcfrefs = core_get_data(playlist->dcfrefs_handle); | ||
181 | int end = start + count; | ||
182 | |||
183 | for (int i = start; i < end; i++) | ||
184 | dircache_fileref_init(&dcfrefs[i]); | ||
185 | #else | ||
186 | (void)playlist; | ||
187 | (void)start; | ||
188 | (void)count; | ||
189 | #endif | ||
190 | } | ||
191 | |||
173 | #ifdef HAVE_DIRCACHE | 192 | #ifdef HAVE_DIRCACHE |
174 | #define PLAYLIST_LOAD_POINTERS 1 | 193 | #define PLAYLIST_LOAD_POINTERS 1 |
175 | #define PLAYLIST_CLEAN_POINTERS 2 | 194 | #define PLAYLIST_CLEAN_POINTERS 2 |
@@ -179,9 +198,6 @@ static struct event_queue playlist_queue SHAREDBSS_ATTR; | |||
179 | static struct queue_sender_list playlist_queue_sender_list SHAREDBSS_ATTR; | 198 | static struct queue_sender_list playlist_queue_sender_list SHAREDBSS_ATTR; |
180 | static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; | 199 | static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; |
181 | static const char dc_thread_playlist_name[] = "playlist cachectrl"; | 200 | static const char dc_thread_playlist_name[] = "playlist cachectrl"; |
182 | |||
183 | static void dc_copy_filerefs(struct dircache_fileref*, | ||
184 | const struct dircache_fileref*, int); | ||
185 | #endif | 201 | #endif |
186 | 202 | ||
187 | #if defined(PLAYLIST_DEBUG_MUTEX) | 203 | #if defined(PLAYLIST_DEBUG_MUTEX) |
@@ -882,9 +898,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist, | |||
882 | 898 | ||
883 | /* Store a new entry */ | 899 | /* Store a new entry */ |
884 | playlist->indices[ playlist->amount ] = i+count; | 900 | playlist->indices[ playlist->amount ] = i+count; |
885 | #ifdef HAVE_DIRCACHE | 901 | dc_init_filerefs(playlist, playlist->amount, 1); |
886 | dc_copy_filerefs(&playlist->dcfrefs[playlist->amount], NULL, 1); | ||
887 | #endif | ||
888 | playlist->amount++; | 902 | playlist->amount++; |
889 | } | 903 | } |
890 | } | 904 | } |
@@ -1191,13 +1205,14 @@ static int get_track_filename(struct playlist_info* playlist, int index, int see | |||
1191 | buf_length = MAX_PATH+1; | 1205 | buf_length = MAX_PATH+1; |
1192 | 1206 | ||
1193 | #ifdef HAVE_DIRCACHE | 1207 | #ifdef HAVE_DIRCACHE |
1194 | if (playlist->dcfrefs) | 1208 | if (playlist->dcfrefs_handle) |
1195 | { | 1209 | { |
1196 | max = dircache_get_fileref_path(&playlist->dcfrefs[index], | 1210 | struct dircache_fileref *dcfrefs = core_get_data_pinned(playlist->dcfrefs_handle); |
1211 | max = dircache_get_fileref_path(&dcfrefs[index], | ||
1197 | tmp_buf, sizeof(tmp_buf)); | 1212 | tmp_buf, sizeof(tmp_buf)); |
1198 | 1213 | ||
1199 | NOTEF("%s [in DCache]: 0x%x %s", __func__, | 1214 | NOTEF("%s [in DCache]: 0x%x %s", __func__, dcfrefs[index], tmp_buf); |
1200 | playlist->dcfrefs[index], tmp_buf); | 1215 | core_put_data_pinned(dcfrefs); |
1201 | } | 1216 | } |
1202 | #endif /* HAVE_DIRCACHE */ | 1217 | #endif /* HAVE_DIRCACHE */ |
1203 | 1218 | ||
@@ -1425,14 +1440,20 @@ static int add_track_to_playlist_unlocked(struct playlist_info* playlist, | |||
1425 | if (queue) | 1440 | if (queue) |
1426 | flags |= PLAYLIST_QUEUED; | 1441 | flags |= PLAYLIST_QUEUED; |
1427 | 1442 | ||
1443 | #ifdef HAVE_DIRCACHE | ||
1444 | struct dircache_fileref *dcfrefs = NULL; | ||
1445 | if (playlist->dcfrefs_handle) | ||
1446 | dcfrefs = core_get_data(playlist->dcfrefs_handle); | ||
1447 | #else | ||
1448 | int *dcfrefs = NULL; | ||
1449 | #endif | ||
1450 | |||
1428 | /* shift indices so that track can be added */ | 1451 | /* shift indices so that track can be added */ |
1429 | for (i=playlist->amount; i>insert_position; i--) | 1452 | for (i=playlist->amount; i>insert_position; i--) |
1430 | { | 1453 | { |
1431 | playlist->indices[i] = playlist->indices[i-1]; | 1454 | playlist->indices[i] = playlist->indices[i-1]; |
1432 | #ifdef HAVE_DIRCACHE | 1455 | if (dcfrefs) |
1433 | if (playlist->dcfrefs) | 1456 | dcfrefs[i] = dcfrefs[i-1]; |
1434 | playlist->dcfrefs[i] = playlist->dcfrefs[i-1]; | ||
1435 | #endif | ||
1436 | } | 1457 | } |
1437 | 1458 | ||
1438 | /* update stored indices if needed */ | 1459 | /* update stored indices if needed */ |
@@ -1463,10 +1484,7 @@ static int add_track_to_playlist_unlocked(struct playlist_info* playlist, | |||
1463 | } | 1484 | } |
1464 | 1485 | ||
1465 | playlist->indices[insert_position] = flags | seek_pos; | 1486 | playlist->indices[insert_position] = flags | seek_pos; |
1466 | 1487 | dc_init_filerefs(playlist, insert_position, 1); | |
1467 | #ifdef HAVE_DIRCACHE | ||
1468 | dc_copy_filerefs(&playlist->dcfrefs[insert_position], NULL, 1); | ||
1469 | #endif | ||
1470 | 1488 | ||
1471 | playlist->amount++; | 1489 | playlist->amount++; |
1472 | playlist->num_inserted_tracks++; | 1490 | playlist->num_inserted_tracks++; |
@@ -1534,14 +1552,20 @@ static int remove_track_from_playlist(struct playlist_info* playlist, | |||
1534 | 1552 | ||
1535 | inserted = playlist->indices[position] & PLAYLIST_INSERT_TYPE_MASK; | 1553 | inserted = playlist->indices[position] & PLAYLIST_INSERT_TYPE_MASK; |
1536 | 1554 | ||
1555 | #ifdef HAVE_DIRCACHE | ||
1556 | struct dircache_fileref *dcfrefs = NULL; | ||
1557 | if (playlist->dcfrefs_handle) | ||
1558 | dcfrefs = core_get_data(playlist->dcfrefs_handle); | ||
1559 | #else | ||
1560 | int *dcfrefs = NULL; | ||
1561 | #endif | ||
1562 | |||
1537 | /* shift indices now that track has been removed */ | 1563 | /* shift indices now that track has been removed */ |
1538 | for (i=position; i<playlist->amount; i++) | 1564 | for (i=position; i<playlist->amount; i++) |
1539 | { | 1565 | { |
1540 | playlist->indices[i] = playlist->indices[i+1]; | 1566 | playlist->indices[i] = playlist->indices[i+1]; |
1541 | #ifdef HAVE_DIRCACHE | 1567 | if (dcfrefs) |
1542 | if (playlist->dcfrefs) | 1568 | dcfrefs[i] = dcfrefs[i+1]; |
1543 | playlist->dcfrefs[i] = playlist->dcfrefs[i+1]; | ||
1544 | #endif | ||
1545 | } | 1569 | } |
1546 | 1570 | ||
1547 | playlist->amount--; | 1571 | playlist->amount--; |
@@ -1630,11 +1654,12 @@ static int randomise_playlist(struct playlist_info* playlist, | |||
1630 | playlist->indices[candidate] = playlist->indices[count]; | 1654 | playlist->indices[candidate] = playlist->indices[count]; |
1631 | playlist->indices[count] = indextmp; | 1655 | playlist->indices[count] = indextmp; |
1632 | #ifdef HAVE_DIRCACHE | 1656 | #ifdef HAVE_DIRCACHE |
1633 | if (playlist->dcfrefs) | 1657 | if (playlist->dcfrefs_handle) |
1634 | { | 1658 | { |
1635 | struct dircache_fileref dcftmp = playlist->dcfrefs[candidate]; | 1659 | struct dircache_fileref *dcfrefs = core_get_data(playlist->dcfrefs_handle); |
1636 | playlist->dcfrefs[candidate] = playlist->dcfrefs[count]; | 1660 | struct dircache_fileref dcftmp = dcfrefs[candidate]; |
1637 | playlist->dcfrefs[count] = dcftmp; | 1661 | dcfrefs[candidate] = dcfrefs[count]; |
1662 | dcfrefs[count] = dcftmp; | ||
1638 | } | 1663 | } |
1639 | #endif | 1664 | #endif |
1640 | } | 1665 | } |
@@ -1707,7 +1732,7 @@ static int sort_playlist_unlocked(struct playlist_info* playlist, | |||
1707 | /** We need to re-check the song names from disk because qsort can't | 1732 | /** We need to re-check the song names from disk because qsort can't |
1708 | * sort two arrays at once :/ | 1733 | * sort two arrays at once :/ |
1709 | * FIXME: Please implement a better way to do this. */ | 1734 | * FIXME: Please implement a better way to do this. */ |
1710 | dc_copy_filerefs(playlist->dcfrefs, NULL, playlist->max_playlist_size); | 1735 | dc_init_filerefs(playlist, 0, playlist->max_playlist_size); |
1711 | dc_load_playlist_pointers(); | 1736 | dc_load_playlist_pointers(); |
1712 | #endif | 1737 | #endif |
1713 | 1738 | ||
@@ -1859,24 +1884,6 @@ static int get_next_index(const struct playlist_info* playlist, int steps, | |||
1859 | } | 1884 | } |
1860 | 1885 | ||
1861 | #ifdef HAVE_DIRCACHE | 1886 | #ifdef HAVE_DIRCACHE |
1862 | |||
1863 | static void dc_copy_filerefs(struct dircache_fileref *dcfto, | ||
1864 | const struct dircache_fileref *dcffrom, | ||
1865 | int count) | ||
1866 | { | ||
1867 | if (!dcfto) | ||
1868 | return; | ||
1869 | |||
1870 | if (dcffrom) | ||
1871 | memmove(dcfto, dcffrom, count * sizeof (*dcfto)); | ||
1872 | else | ||
1873 | { | ||
1874 | /* just initialize the destination */ | ||
1875 | for (int i = 0; i < count; i++, dcfto++) | ||
1876 | dircache_fileref_init(dcfto); | ||
1877 | } | ||
1878 | } | ||
1879 | |||
1880 | static void dc_flush_playlist_callback(void) | 1887 | static void dc_flush_playlist_callback(void) |
1881 | { | 1888 | { |
1882 | struct playlist_info *playlist; | 1889 | struct playlist_info *playlist; |
@@ -1901,6 +1908,7 @@ static void dc_thread_playlist(void) | |||
1901 | static char tmp[MAX_PATH+1]; | 1908 | static char tmp[MAX_PATH+1]; |
1902 | 1909 | ||
1903 | struct playlist_info *playlist; | 1910 | struct playlist_info *playlist; |
1911 | struct dircache_fileref *dcfrefs; | ||
1904 | int index; | 1912 | int index; |
1905 | int seek; | 1913 | int seek; |
1906 | bool control_file; | 1914 | bool control_file; |
@@ -1939,7 +1947,7 @@ static void dc_thread_playlist(void) | |||
1939 | register_storage_idle_func(dc_flush_playlist_callback); | 1947 | register_storage_idle_func(dc_flush_playlist_callback); |
1940 | } | 1948 | } |
1941 | 1949 | ||
1942 | if (!playlist->dcfrefs || playlist->amount <= 0) | 1950 | if (!playlist->dcfrefs_handle || playlist->amount <= 0) |
1943 | break ; | 1951 | break ; |
1944 | 1952 | ||
1945 | /* Check if previously loaded pointers are intact. */ | 1953 | /* Check if previously loaded pointers are intact. */ |
@@ -1953,12 +1961,13 @@ static void dc_thread_playlist(void) | |||
1953 | break ; | 1961 | break ; |
1954 | 1962 | ||
1955 | trigger_cpu_boost(); | 1963 | trigger_cpu_boost(); |
1964 | dcfrefs = core_get_data_pinned(playlist->dcfrefs_handle); | ||
1956 | 1965 | ||
1957 | for (index = 0; index < playlist->amount | 1966 | for (index = 0; index < playlist->amount |
1958 | && queue_empty(&playlist_queue); index++) | 1967 | && queue_empty(&playlist_queue); index++) |
1959 | { | 1968 | { |
1960 | /* Process only pointers that are superficially stale. */ | 1969 | /* Process only pointers that are superficially stale. */ |
1961 | if (dircache_search(DCS_FILEREF, &playlist->dcfrefs[index], NULL) > 0) | 1970 | if (dircache_search(DCS_FILEREF, &dcfrefs[index], NULL) > 0) |
1962 | continue ; | 1971 | continue ; |
1963 | 1972 | ||
1964 | control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; | 1973 | control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; |
@@ -1973,12 +1982,13 @@ static void dc_thread_playlist(void) | |||
1973 | 1982 | ||
1974 | /* Obtain the dircache file entry cookie. */ | 1983 | /* Obtain the dircache file entry cookie. */ |
1975 | dircache_search(DCS_CACHED_PATH | DCS_UPDATE_FILEREF, | 1984 | dircache_search(DCS_CACHED_PATH | DCS_UPDATE_FILEREF, |
1976 | &playlist->dcfrefs[index], tmp); | 1985 | &dcfrefs[index], tmp); |
1977 | 1986 | ||
1978 | /* And be on background so user doesn't notice any delays. */ | 1987 | /* And be on background so user doesn't notice any delays. */ |
1979 | yield(); | 1988 | yield(); |
1980 | } | 1989 | } |
1981 | 1990 | ||
1991 | core_put_data_pinned(dcfrefs); | ||
1982 | cancel_cpu_boost(); | 1992 | cancel_cpu_boost(); |
1983 | 1993 | ||
1984 | if (index == playlist->amount) | 1994 | if (index == playlist->amount) |
@@ -2042,10 +2052,6 @@ static int move_callback(int handle, void* current, void* new) | |||
2042 | struct playlist_info* playlist = ¤t_playlist; | 2052 | struct playlist_info* playlist = ¤t_playlist; |
2043 | if (current == playlist->indices) | 2053 | if (current == playlist->indices) |
2044 | playlist->indices = new; | 2054 | playlist->indices = new; |
2045 | #ifdef HAVE_DIRCACHE | ||
2046 | else if (current == playlist->dcfrefs) | ||
2047 | playlist->dcfrefs = new; | ||
2048 | #endif /* HAVE_DIRCACHE */ | ||
2049 | return BUFLIB_CB_OK; | 2055 | return BUFLIB_CB_OK; |
2050 | } | 2056 | } |
2051 | 2057 | ||
@@ -2083,10 +2089,10 @@ void playlist_init(void) | |||
2083 | initalize_new_playlist(playlist, true); | 2089 | initalize_new_playlist(playlist, true); |
2084 | 2090 | ||
2085 | #ifdef HAVE_DIRCACHE | 2091 | #ifdef HAVE_DIRCACHE |
2086 | handle = core_alloc_ex( | 2092 | playlist->dcfrefs_handle = core_alloc( |
2087 | playlist->max_playlist_size * sizeof(*playlist->dcfrefs), &ops); | 2093 | playlist->max_playlist_size * sizeof(struct dircache_fileref)); |
2088 | playlist->dcfrefs = core_get_data(handle); | 2094 | dc_init_filerefs(playlist, 0, playlist->max_playlist_size); |
2089 | dc_copy_filerefs(playlist->dcfrefs, NULL, playlist->max_playlist_size); | 2095 | |
2090 | unsigned int playlist_thread_id = | 2096 | unsigned int playlist_thread_id = |
2091 | create_thread(dc_thread_playlist, playlist_stack, sizeof(playlist_stack), | 2097 | create_thread(dc_thread_playlist, playlist_stack, sizeof(playlist_stack), |
2092 | 0, dc_thread_playlist_name IF_PRIO(, PRIORITY_BACKGROUND) | 2098 | 0, dc_thread_playlist_name IF_PRIO(, PRIORITY_BACKGROUND) |
@@ -2149,10 +2155,7 @@ int playlist_add(const char *filename) | |||
2149 | chunk_put_data(&playlist->name_chunk_buffer, namebuf, indice); | 2155 | chunk_put_data(&playlist->name_chunk_buffer, namebuf, indice); |
2150 | 2156 | ||
2151 | playlist->indices[playlist->amount] = indice; | 2157 | playlist->indices[playlist->amount] = indice; |
2152 | 2158 | dc_init_filerefs(playlist, playlist->amount, 1); | |
2153 | #ifdef HAVE_DIRCACHE | ||
2154 | dc_copy_filerefs(&playlist->dcfrefs[playlist->amount], NULL, 1); | ||
2155 | #endif | ||
2156 | 2159 | ||
2157 | playlist->amount++; | 2160 | playlist->amount++; |
2158 | 2161 | ||
@@ -2217,15 +2220,16 @@ int playlist_create_ex(struct playlist_info* playlist, | |||
2217 | playlist->max_playlist_size = num_indices; | 2220 | playlist->max_playlist_size = num_indices; |
2218 | playlist->indices = index_buffer; | 2221 | playlist->indices = index_buffer; |
2219 | #ifdef HAVE_DIRCACHE | 2222 | #ifdef HAVE_DIRCACHE |
2220 | playlist->dcfrefs = (void *)&playlist->indices[num_indices]; | 2223 | playlist->dcfrefs_handle = 0; |
2221 | #endif | 2224 | #endif |
2222 | } | 2225 | } |
2223 | else | 2226 | else |
2224 | { | 2227 | { |
2228 | /* FIXME not sure if it's safe to share index buffers */ | ||
2225 | playlist->max_playlist_size = current_playlist.max_playlist_size; | 2229 | playlist->max_playlist_size = current_playlist.max_playlist_size; |
2226 | playlist->indices = current_playlist.indices; | 2230 | playlist->indices = current_playlist.indices; |
2227 | #ifdef HAVE_DIRCACHE | 2231 | #ifdef HAVE_DIRCACHE |
2228 | playlist->dcfrefs = current_playlist.dcfrefs; | 2232 | playlist->dcfrefs_handle = 0; |
2229 | #endif | 2233 | #endif |
2230 | } | 2234 | } |
2231 | 2235 | ||
@@ -2524,9 +2528,6 @@ size_t playlist_get_required_bufsz(struct playlist_info* playlist, | |||
2524 | playlist = ¤t_playlist; | 2528 | playlist = ¤t_playlist; |
2525 | 2529 | ||
2526 | size_t unit_size = sizeof (*playlist->indices); | 2530 | size_t unit_size = sizeof (*playlist->indices); |
2527 | #ifdef HAVE_DIRCACHE | ||
2528 | unit_size += sizeof (*playlist->dcfrefs); | ||
2529 | #endif | ||
2530 | if (include_namebuf) | 2531 | if (include_namebuf) |
2531 | namebuf = AVERAGE_FILENAME_LENGTH * global_settings.max_files_in_dir; | 2532 | namebuf = AVERAGE_FILENAME_LENGTH * global_settings.max_files_in_dir; |
2532 | 2533 | ||
@@ -3909,10 +3910,7 @@ int playlist_set_current(struct playlist_info* playlist) | |||
3909 | { | 3910 | { |
3910 | memcpy((void*)current_playlist.indices, (void*)playlist->indices, | 3911 | memcpy((void*)current_playlist.indices, (void*)playlist->indices, |
3911 | playlist->max_playlist_size*sizeof(*playlist->indices)); | 3912 | playlist->max_playlist_size*sizeof(*playlist->indices)); |
3912 | #ifdef HAVE_DIRCACHE | 3913 | dc_init_filerefs(¤t_playlist, 0, current_playlist.max_playlist_size); |
3913 | dc_copy_filerefs(current_playlist.dcfrefs, playlist->dcfrefs, | ||
3914 | playlist->max_playlist_size); | ||
3915 | #endif | ||
3916 | } | 3914 | } |
3917 | 3915 | ||
3918 | current_playlist.first_index = playlist->first_index; | 3916 | current_playlist.first_index = playlist->first_index; |
diff --git a/apps/playlist.h b/apps/playlist.h index ef943f1bd9..86c0c293ab 100644 --- a/apps/playlist.h +++ b/apps/playlist.h | |||
@@ -107,7 +107,7 @@ struct playlist_info | |||
107 | int num_cached; /* number of cached entries */ | 107 | int num_cached; /* number of cached entries */ |
108 | struct mutex mutex; /* mutex for control file access */ | 108 | struct mutex mutex; /* mutex for control file access */ |
109 | #ifdef HAVE_DIRCACHE | 109 | #ifdef HAVE_DIRCACHE |
110 | struct dircache_fileref *dcfrefs; /* Dircache entry shortcuts */ | 110 | int dcfrefs_handle; |
111 | #endif | 111 | #endif |
112 | int dirlen; /* Length of the path to the playlist file */ | 112 | int dirlen; /* Length of the path to the playlist file */ |
113 | char filename[MAX_PATH]; /* path name of m3u playlist on disk */ | 113 | char filename[MAX_PATH]; /* path name of m3u playlist on disk */ |