From e8f1d4370fd7feb2fa0f3103a205f451d37eafa5 Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Fri, 28 Feb 2020 14:00:19 +0900 Subject: [PATCH] Fix double unlock of slot mutex in user stops scneario In addition, stream started callback and written data log are added for convienent debugging [Version] 0.12.64 [Issue Type] Bug Change-Id: I1f444f9ff2920156407c4baa11aa655116d241f6 --- packaging/libmm-sound.spec | 2 +- server/include/mm_sound_plugin_codec.h | 2 +- server/mm_sound_mgr_codec.c | 14 +++++--------- server/plugin/wav/mm_sound_plugin_codec_wave.c | 21 ++++++++++++++++----- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/packaging/libmm-sound.spec b/packaging/libmm-sound.spec index a6bf755..ab11251 100644 --- a/packaging/libmm-sound.spec +++ b/packaging/libmm-sound.spec @@ -1,6 +1,6 @@ Name: libmm-sound Summary: MMSound Package contains client lib and sound_server binary -Version: 0.12.63 +Version: 0.12.64 Release: 0 Group: System/Libraries License: Apache-2.0 diff --git a/server/include/mm_sound_plugin_codec.h b/server/include/mm_sound_plugin_codec.h index 2cea7a9..c5a8806 100644 --- a/server/include/mm_sound_plugin_codec.h +++ b/server/include/mm_sound_plugin_codec.h @@ -46,7 +46,7 @@ typedef struct { } mmsound_codec_info_t; typedef struct { - int (*stop_cb)(int); + int (*stop_cb)(int, bool); int pid; int param; int tone; diff --git a/server/mm_sound_mgr_codec.c b/server/mm_sound_mgr_codec.c index 6e4192f..c2c968b 100644 --- a/server/mm_sound_mgr_codec.c +++ b/server/mm_sound_mgr_codec.c @@ -56,8 +56,6 @@ typedef struct { int pluginid; int status; - bool stop_by_user; - } __mmsound_mgr_codec_handle_t; static MMSoundPluginType *g_codec_plugins = NULL; @@ -84,7 +82,7 @@ static guint g_timer_id = 0; #endif static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin); -static int _MMSoundMgrCodecStopCallback(int param); +static int _MMSoundMgrCodecStopCallback(int param, bool stop_by_user); static gboolean _mm_sound_mgr_codec_slot_is_empty(); static gboolean _idle_cb(gpointer user_data) @@ -433,8 +431,6 @@ int MMSoundMgrCodecStop(const int slotid) debug_msg("Found slot, Slotid [%d] State [%d]", slotid, g_slots[slotid].status); #endif - g_slots[slotid].stop_by_user = true; - err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle); if (err != MM_ERROR_NONE) debug_error("Fail to STOP Code : 0x%08X", err); @@ -446,7 +442,7 @@ cleanup: return err; } -static int _MMSoundMgrCodecStopCallback(int param) +static int _MMSoundMgrCodecStopCallback(int param, bool stop_by_user) { int err = MM_ERROR_NONE; @@ -455,9 +451,9 @@ static int _MMSoundMgrCodecStopCallback(int param) return MM_ERROR_INVALID_ARGUMENT; } - debug_enter("Slot(%d) : stop-by-user(%d)", param, g_slots[param].stop_by_user); + debug_enter("Slot(%d) : stop-by-user(%d)", param, stop_by_user); - if (!g_slots[param].stop_by_user) { + if (!stop_by_user) { SLOT_LOCK(); __mm_sound_mgr_ipc_notify_play_file_end(param); debug_msg("Client callback msg_type (instance) : [%d]", (int)g_slots[param].param); @@ -472,7 +468,7 @@ static int _MMSoundMgrCodecStopCallback(int param) if (_mm_sound_mgr_codec_slot_is_empty()) _mm_sound_mgr_codec_shutdown_timer_start(); - if (!g_slots[param].stop_by_user) + if (!stop_by_user) SLOT_UNLOCK(); debug_fleave(); diff --git a/server/plugin/wav/mm_sound_plugin_codec_wave.c b/server/plugin/wav/mm_sound_plugin_codec_wave.c index 7174ca3..65ea459 100644 --- a/server/plugin/wav/mm_sound_plugin_codec_wave.c +++ b/server/plugin/wav/mm_sound_plugin_codec_wave.c @@ -40,7 +40,7 @@ typedef struct { int handle; int repeat_count; - int (*stop_cb)(int); + int (*stop_cb)(int, bool); char filename[MM_SOUND_MAX_FILENAME]; int cb_param; char stream_type[MAX_STREAM_TYPE_LEN]; @@ -53,6 +53,8 @@ typedef struct { pa_sample_spec spec; SNDFILE *sf; SF_INFO si; + + size_t written; } wave_info_t; static int _sound_prepare(wave_info_t *h) @@ -225,7 +227,7 @@ static void _pa_stream_drain_complete_callback(pa_stream *s, int success, void * debug_msg("Invoke stop callback(%p, %d) of mgr_codec", h->stop_cb, h->cb_param); if (h->stop_cb) - h->stop_cb(h->cb_param); + h->stop_cb(h->cb_param, false); } static void _pa_stream_moved_callback(pa_stream *s, void *userdata) @@ -248,6 +250,12 @@ static void _pa_stream_buffer_attr_callback(pa_stream *s, void *userdata) debug_msg("stream(%p)", s); } +static void _pa_stream_started_callback(pa_stream *s, void *userdata) +{ + assert(s); + debug_msg("stream(%p)", s); +} + static void _pa_stream_write_callback(pa_stream *s, size_t length, void *userdata) { sf_count_t bytes = 0; @@ -278,13 +286,15 @@ static void _pa_stream_write_callback(pa_stream *s, size_t length, void *userdat if ((bytes = sf_readf_short(h->sf, data, (sf_count_t)(data_length / frame_size))) > 0) bytes *= (sf_count_t)frame_size; - debug_msg("stream(%p) : === %"PRId64" / %zu ===", s, bytes, data_length); + debug_msg("stream(%p) : === %"PRId64" / %zu / %zu ===", s, bytes, data_length, h->written); if (bytes > 0) pa_stream_write(s, data, (size_t)bytes, NULL, 0, PA_SEEK_RELATIVE); else pa_stream_cancel_write(s); + h->written += bytes; + /* If No more data, drain stream */ if (bytes < (sf_count_t)data_length) { debug_msg("stream(%p) : End Of Stream", s); @@ -403,6 +413,7 @@ static int _pa_stream_connect(wave_info_t *h) pa_stream_set_moved_callback(s, _pa_stream_moved_callback, h); pa_stream_set_underflow_callback(s, _pa_stream_underflow_callback, h); pa_stream_set_buffer_attr_callback(s, _pa_stream_buffer_attr_callback, h); + pa_stream_set_started_callback(s, _pa_stream_started_callback, h); ret = pa_stream_connect_playback(s, NULL, NULL, PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_START_CORKED, @@ -579,7 +590,7 @@ static int _mm_sound_plug_codec_wave_play(MMHandleType handle) { wave_info_t *h = (wave_info_t *)handle; - debug_msg("Start handle(%p), stream(%p)", h, h->s); + debug_msg("Start handle(%p), stream(%p), written(%zu)", h, h->s, h->written); _pa_stream_uncork(h); return MM_ERROR_NONE; @@ -598,7 +609,7 @@ static int _mm_sound_plug_codec_wave_stop(MMHandleType handle) _pa_stream_stop_disconnect(h); if (h->stop_cb) - h->stop_cb(h->cb_param); + h->stop_cb(h->cb_param, true); return MM_ERROR_NONE; } -- 2.7.4