summaryrefslogtreecommitdiff
path: root/apps/playlist.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2013-05-30 11:24:16 +0200
committerThomas Martitz <kugel@rockbox.org>2013-12-23 12:17:38 +0100
commit22e802e80048defd401462e062afcb10093ac793 (patch)
tree09d24f7eb2a3b18e6563e838398b2715394f7c4c /apps/playlist.c
parent64b9e1fa7b645daa36ca0018dc168d4f871fd538 (diff)
downloadrockbox-22e802e80048defd401462e062afcb10093ac793.tar.gz
rockbox-22e802e80048defd401462e062afcb10093ac793.zip
playback,talk: Share audiobuffer via core_alloc_maximum().
This fixes the radioart crash that was the result of buffering.c working on a freed buffer at the same time as buflib (radioart uses buffering.c for the images). With this change the buffer is owned by buflib exclusively so this cannot happen. As a result, audio_get_buffer() doesn't exist anymore. Callers should call core_alloc_maximum() directly. This buffer needs to be protected as usual against movement if necessary (previously it was not protected at all which cased the radioart crash), To get most of it they can adjust the willingness of the talk engine to give its buffer away (at the expense of disabling voice interface) with the new talk_buffer_set_policy() function. Change-Id: I52123012208d04967876a304451d634e2bef3a33
Diffstat (limited to 'apps/playlist.c')
-rwxr-xr-xapps/playlist.c87
1 files changed, 63 insertions, 24 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index 35b7e35baa..3d930cf3f9 100755
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -104,6 +104,7 @@
104#include "rbunicode.h" 104#include "rbunicode.h"
105#include "root_menu.h" 105#include "root_menu.h"
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 108
108#define PLAYLIST_CONTROL_FILE_VERSION 2 109#define PLAYLIST_CONTROL_FILE_VERSION 2
109 110
@@ -532,13 +533,6 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
532 533
533 splash(0, ID2P(LANG_WAIT)); 534 splash(0, ID2P(LANG_WAIT));
534 535
535 if (!buffer)
536 {
537 /* use mp3 buffer for maximum load speed */
538 audio_stop();
539 buffer = audio_get_buffer(false, &buflen);
540 }
541
542 store_index = true; 536 store_index = true;
543 537
544 while(1) 538 while(1)
@@ -2077,8 +2071,26 @@ int playlist_create(const char *dir, const char *file)
2077 new_playlist(playlist, dir, file); 2071 new_playlist(playlist, dir, file);
2078 2072
2079 if (file) 2073 if (file)
2080 /* load the playlist file */ 2074 {
2081 add_indices_to_playlist(playlist, NULL, 0); 2075 /* dummy ops with no callbacks, needed because by
2076 * default buflib buffers can be moved around which must be avoided */
2077 static struct buflib_callbacks dummy_ops;
2078 int handle;
2079 size_t buflen;
2080 /* use mp3 buffer for maximum load speed */
2081 handle = core_alloc_maximum("temp", &buflen, &dummy_ops);
2082 if (handle > 0)
2083 {
2084 /* load the playlist file */
2085 add_indices_to_playlist(playlist, core_get_data(handle), buflen);
2086 core_free(handle);
2087 }
2088 else
2089 {
2090 /* should not happen */
2091 panicf("%s(): OOM", __func__);
2092 }
2093 }
2082 2094
2083 return 0; 2095 return 0;
2084} 2096}
@@ -2094,14 +2106,22 @@ int playlist_resume(void)
2094 struct playlist_info* playlist = &current_playlist; 2106 struct playlist_info* playlist = &current_playlist;
2095 char *buffer; 2107 char *buffer;
2096 size_t buflen; 2108 size_t buflen;
2109 int handle;
2097 int nread; 2110 int nread;
2098 int total_read = 0; 2111 int total_read = 0;
2099 int control_file_size = 0; 2112 int control_file_size = 0;
2100 bool first = true; 2113 bool first = true;
2101 bool sorted = true; 2114 bool sorted = true;
2115 int result = -1;
2102 2116
2117 /* dummy ops with no callbacks, needed because by
2118 * default buflib buffers can be moved around which must be avoided */
2119 static struct buflib_callbacks dummy_ops;
2103 /* use mp3 buffer for maximum load speed */ 2120 /* use mp3 buffer for maximum load speed */
2104 buffer = (char *)audio_get_buffer(false, &buflen); 2121 handle = core_alloc_maximum("temp", &buflen, &dummy_ops);
2122 if (handle < 0)
2123 panicf("%s(): OOM", __func__);
2124 buffer = core_get_data(handle);
2105 2125
2106 empty_playlist(playlist, true); 2126 empty_playlist(playlist, true);
2107 2127
@@ -2110,7 +2130,7 @@ int playlist_resume(void)
2110 if (playlist->control_fd < 0) 2130 if (playlist->control_fd < 0)
2111 { 2131 {
2112 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); 2132 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));
2113 return -1; 2133 goto out;
2114 } 2134 }
2115 playlist->control_created = true; 2135 playlist->control_created = true;
2116 2136
@@ -2118,7 +2138,7 @@ int playlist_resume(void)
2118 if (control_file_size <= 0) 2138 if (control_file_size <= 0)
2119 { 2139 {
2120 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); 2140 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));
2121 return -1; 2141 goto out;
2122 } 2142 }
2123 2143
2124 /* read a small amount first to get the header */ 2144 /* read a small amount first to get the header */
@@ -2127,14 +2147,14 @@ int playlist_resume(void)
2127 if(nread <= 0) 2147 if(nread <= 0)
2128 { 2148 {
2129 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); 2149 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));
2130 return -1; 2150 goto out;
2131 } 2151 }
2132 2152
2133 playlist->started = true; 2153 playlist->started = true;
2134 2154
2135 while (1) 2155 while (1)
2136 { 2156 {
2137 int result = 0; 2157 result = 0;
2138 int count; 2158 int count;
2139 enum playlist_command current_command = PLAYLIST_COMMAND_COMMENT; 2159 enum playlist_command current_command = PLAYLIST_COMMAND_COMMENT;
2140 int last_newline = 0; 2160 int last_newline = 0;
@@ -2195,7 +2215,10 @@ int playlist_resume(void)
2195 version = atoi(str1); 2215 version = atoi(str1);
2196 2216
2197 if (version != PLAYLIST_CONTROL_FILE_VERSION) 2217 if (version != PLAYLIST_CONTROL_FILE_VERSION)
2198 return -1; 2218 {
2219 result = -1;
2220 goto out;
2221 }
2199 2222
2200 update_playlist_filename(playlist, str2, str3); 2223 update_playlist_filename(playlist, str2, str3);
2201 2224
@@ -2204,7 +2227,7 @@ int playlist_resume(void)
2204 /* NOTE: add_indices_to_playlist() overwrites the 2227 /* NOTE: add_indices_to_playlist() overwrites the
2205 audiobuf so we need to reload control file 2228 audiobuf so we need to reload control file
2206 data */ 2229 data */
2207 add_indices_to_playlist(playlist, NULL, 0); 2230 add_indices_to_playlist(playlist, buffer, buflen);
2208 } 2231 }
2209 else if (str2[0] != '\0') 2232 else if (str2[0] != '\0')
2210 { 2233 {
@@ -2242,7 +2265,10 @@ int playlist_resume(void)
2242 buffer */ 2265 buffer */
2243 if (add_track_to_playlist(playlist, str3, position, 2266 if (add_track_to_playlist(playlist, str3, position,
2244 queue, total_read+(str3-buffer)) < 0) 2267 queue, total_read+(str3-buffer)) < 0)
2245 return -1; 2268 {
2269 result = -1;
2270 goto out;
2271 }
2246 2272
2247 playlist->last_insert_pos = last_position; 2273 playlist->last_insert_pos = last_position;
2248 2274
@@ -2264,7 +2290,10 @@ int playlist_resume(void)
2264 2290
2265 if (remove_track_from_playlist(playlist, position, 2291 if (remove_track_from_playlist(playlist, position,
2266 false) < 0) 2292 false) < 0)
2267 return -1; 2293 {
2294 result = -1;
2295 goto out;
2296 }
2268 2297
2269 break; 2298 break;
2270 } 2299 }
@@ -2291,7 +2320,10 @@ int playlist_resume(void)
2291 2320
2292 if (randomise_playlist(playlist, seed, false, 2321 if (randomise_playlist(playlist, seed, false,
2293 false) < 0) 2322 false) < 0)
2294 return -1; 2323 {
2324 result = -1;
2325 goto out;
2326 }
2295 sorted = false; 2327 sorted = false;
2296 break; 2328 break;
2297 } 2329 }
@@ -2308,7 +2340,10 @@ int playlist_resume(void)
2308 playlist->first_index = atoi(str1); 2340 playlist->first_index = atoi(str1);
2309 2341
2310 if (sort_playlist(playlist, false, false) < 0) 2342 if (sort_playlist(playlist, false, false) < 0)
2311 return -1; 2343 {
2344 result = -1;
2345 goto out;
2346 }
2312 2347
2313 sorted = true; 2348 sorted = true;
2314 break; 2349 break;
@@ -2421,13 +2456,14 @@ int playlist_resume(void)
2421 if (result < 0) 2456 if (result < 0)
2422 { 2457 {
2423 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_INVALID)); 2458 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_INVALID));
2424 return result; 2459 goto out;
2425 } 2460 }
2426 2461
2427 if (useraborted) 2462 if (useraborted)
2428 { 2463 {
2429 splash(HZ*2, ID2P(LANG_CANCEL)); 2464 splash(HZ*2, ID2P(LANG_CANCEL));
2430 return -1; 2465 result = -1;
2466 goto out;
2431 } 2467 }
2432 if (!newline || (exit_loop && count<nread)) 2468 if (!newline || (exit_loop && count<nread))
2433 { 2469 {
@@ -2435,7 +2471,8 @@ int playlist_resume(void)
2435 { 2471 {
2436 /* no newline at end of control file */ 2472 /* no newline at end of control file */
2437 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_INVALID)); 2473 splash(HZ*2, ID2P(LANG_PLAYLIST_CONTROL_INVALID));
2438 return -1; 2474 result = -1;
2475 goto out;
2439 } 2476 }
2440 2477
2441 /* We didn't end on a newline or we exited loop prematurely. 2478 /* We didn't end on a newline or we exited loop prematurely.
@@ -2464,7 +2501,9 @@ int playlist_resume(void)
2464 queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0); 2501 queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0);
2465#endif 2502#endif
2466 2503
2467 return 0; 2504out:
2505 core_free(handle);
2506 return result;
2468} 2507}
2469 2508
2470/* 2509/*