summaryrefslogtreecommitdiff
path: root/apps/plugin.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/plugin.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/plugin.c')
-rw-r--r--apps/plugin.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 18c49f4c27..d80e6a1e0e 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -801,6 +801,8 @@ static const struct plugin_api rockbox_api = {
801 the API gets incompatible */ 801 the API gets incompatible */
802}; 802};
803 803
804static int plugin_buffer_handle;
805
804int plugin_load(const char* plugin, const void* parameter) 806int plugin_load(const char* plugin, const void* parameter)
805{ 807{
806 struct plugin_header *p_hdr; 808 struct plugin_header *p_hdr;
@@ -815,6 +817,8 @@ int plugin_load(const char* plugin, const void* parameter)
815 } 817 }
816 lc_close(current_plugin_handle); 818 lc_close(current_plugin_handle);
817 current_plugin_handle = pfn_tsr_exit = NULL; 819 current_plugin_handle = pfn_tsr_exit = NULL;
820 if (plugin_buffer_handle > 0)
821 plugin_buffer_handle = core_free(plugin_buffer_handle);
818 } 822 }
819 823
820 splash(0, ID2P(LANG_WAIT)); 824 splash(0, ID2P(LANG_WAIT));
@@ -878,6 +882,9 @@ int plugin_load(const char* plugin, const void* parameter)
878 touchscreen_set_mode(TOUCHSCREEN_BUTTON); 882 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
879#endif 883#endif
880 884
885 /* allow voice to back off if the plugin needs lots of memory */
886 talk_buffer_set_policy(TALK_BUFFER_LOOSE);
887
881#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE 888#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
882 open_files = 0; 889 open_files = 0;
883#endif 890#endif
@@ -891,8 +898,12 @@ int plugin_load(const char* plugin, const void* parameter)
891 { /* close handle if plugin is no tsr one */ 898 { /* close handle if plugin is no tsr one */
892 lc_close(current_plugin_handle); 899 lc_close(current_plugin_handle);
893 current_plugin_handle = NULL; 900 current_plugin_handle = NULL;
901 if (plugin_buffer_handle > 0)
902 plugin_buffer_handle = core_free(plugin_buffer_handle);
894 } 903 }
895 904
905 talk_buffer_set_policy(TALK_BUFFER_DEFAULT);
906
896 /* Go back to the global setting in case the plugin changed it */ 907 /* Go back to the global setting in case the plugin changed it */
897#ifdef HAVE_TOUCHSCREEN 908#ifdef HAVE_TOUCHSCREEN
898 touchscreen_set_mode(global_settings.touch_mode); 909 touchscreen_set_mode(global_settings.touch_mode);
@@ -984,8 +995,12 @@ void* plugin_get_buffer(size_t *buffer_size)
984 */ 995 */
985void* plugin_get_audio_buffer(size_t *buffer_size) 996void* plugin_get_audio_buffer(size_t *buffer_size)
986{ 997{
987 audio_stop(); 998 /* dummy ops with no callbacks, needed because by
988 return audio_get_buffer(true, buffer_size); 999 * default buflib buffers can be moved around which must be avoided */
1000 static struct buflib_callbacks dummy_ops;
1001 plugin_buffer_handle = core_alloc_maximum("plugin audio buf", buffer_size,
1002 &dummy_ops);
1003 return core_get_data(plugin_buffer_handle);
989} 1004}
990 1005
991/* The plugin wants to stay resident after leaving its main function, e.g. 1006/* The plugin wants to stay resident after leaving its main function, e.g.