summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/playlist.c136
-rw-r--r--apps/playlist.h2
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
171static struct playlist_info current_playlist; 171static struct playlist_info current_playlist;
172 172
173static 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;
179static struct queue_sender_list playlist_queue_sender_list SHAREDBSS_ATTR; 198static struct queue_sender_list playlist_queue_sender_list SHAREDBSS_ATTR;
180static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; 199static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
181static const char dc_thread_playlist_name[] = "playlist cachectrl"; 200static const char dc_thread_playlist_name[] = "playlist cachectrl";
182
183static 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
1863static 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
1880static void dc_flush_playlist_callback(void) 1887static 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 = &current_playlist; 2052 struct playlist_info* playlist = &current_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 = &current_playlist; 2528 playlist = &current_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(&current_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 */