From c028ee2bf21b5625ebf8bb12bf3c96250c21ee50 Mon Sep 17 00:00:00 2001 From: "braveyao@webrtc.org" Date: Thu, 22 Aug 2013 03:14:34 +0000 Subject: [PATCH] Android audio opensles: random deadlock in stopRecording(). BUG=2201 Test=WebRTCDemo R=fischman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2039004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4589 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../android/audio_device_opensles_android.cc | 64 +++++++++---------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/webrtc/modules/audio_device/android/audio_device_opensles_android.cc b/webrtc/modules/audio_device/android/audio_device_opensles_android.cc index a306294647..d5d1276ec7 100644 --- a/webrtc/modules/audio_device/android/audio_device_opensles_android.cc +++ b/webrtc/modules/audio_device/android/audio_device_opensles_android.cc @@ -1000,40 +1000,8 @@ int32_t AudioDeviceAndroidOpenSLES::StartRecording() { } int32_t AudioDeviceAndroidOpenSLES::StopRecording() { - { - CriticalSectionScoped lock(&crit_sect_); - - if (!is_rec_initialized_) { - WEBRTC_OPENSL_TRACE(kTraceInfo, kTraceAudioDevice, id_, - " Recording is not initialized"); - return 0; - } - - if ((sles_recorder_itf_ != NULL) && (sles_recorder_ != NULL)) { - int32_t res = (*sles_recorder_itf_)->SetRecordState( - sles_recorder_itf_, - SL_RECORDSTATE_STOPPED); - if (res != SL_RESULT_SUCCESS) { - WEBRTC_OPENSL_TRACE(kTraceError, kTraceAudioDevice, id_, - " failed to stop recording"); - return -1; - } - res = (*sles_recorder_sbq_itf_)->Clear( - sles_recorder_sbq_itf_); - if (res != SL_RESULT_SUCCESS) { - WEBRTC_OPENSL_TRACE(kTraceError, kTraceAudioDevice, id_, - " failed to clear recorder buffer queue"); - return -1; - } - - // Destroy the recorder object - (*sles_recorder_)->Destroy(sles_recorder_); - sles_recorder_ = NULL; - sles_recorder_itf_ = NULL; - } - } - - // Stop the playout thread + // Stop the recording thread + // Cannot be under lock, risk of deadlock if (rec_thread_) { if (rec_thread_->Stop()) { delete rec_thread_; @@ -1041,15 +1009,41 @@ int32_t AudioDeviceAndroidOpenSLES::StopRecording() { } else { WEBRTC_TRACE(kTraceError, kTraceAudioDevice, id_, "Failed to stop recording thread "); - return -1; } } CriticalSectionScoped lock(&crit_sect_); + + if (!is_rec_initialized_) { + WEBRTC_OPENSL_TRACE(kTraceInfo, kTraceAudioDevice, id_, + " Recording is not initialized"); + return 0; + } + + int32_t res = (*sles_recorder_itf_)->SetRecordState( + sles_recorder_itf_, + SL_RECORDSTATE_STOPPED); + if (res != SL_RESULT_SUCCESS) { + WEBRTC_OPENSL_TRACE(kTraceError, kTraceAudioDevice, id_, + " failed to stop recording"); + } + + res = (*sles_recorder_sbq_itf_)->Clear(sles_recorder_sbq_itf_); + if (res != SL_RESULT_SUCCESS) { + WEBRTC_OPENSL_TRACE(kTraceError, kTraceAudioDevice, id_, + " failed to clear recorder buffer queue"); + } + + // Destroy the recorder object + (*sles_recorder_)->Destroy(sles_recorder_); + is_rec_initialized_ = false; is_recording_ = false; rec_warning_ = 0; rec_error_ = 0; + sles_recorder_ = NULL; + sles_recorder_itf_ = NULL; + sles_recorder_sbq_itf_ = NULL; return 0; }