diff --git a/chrome/renderer/media/chrome_speech_recognition_client.cc b/chrome/renderer/media/chrome_speech_recognition_client.cc index 7332f21f82072..d7988d87aa45b 100644 --- a/chrome/renderer/media/chrome_speech_recognition_client.cc +++ b/chrome/renderer/media/chrome_speech_recognition_client.cc @@ -102,11 +102,21 @@ bool ChromeSpeechRecognitionClient::IsSpeechRecognitionAvailable() { // existing callback. void ChromeSpeechRecognitionClient::SetOnReadyCallback( SpeechRecognitionClient::OnReadyCallback callback) { - on_ready_callback_ = std::move(callback); - - // Immediately run the callback if speech recognition is already available. - if (IsSpeechRecognitionAvailable() && on_ready_callback_) - std::move(on_ready_callback_).Run(); + // SetOnReadyCallback() is called from the media sequence + // (AudioRendererImpl::Initialize) while OnRecognizerBound() runs on the + // main thread; guard on_ready_callback_ with the existing lock and only + // Run() outside the lock to avoid re-entrancy. + SpeechRecognitionClient::OnReadyCallback to_run; + { + base::AutoLock auto_lock(is_recognizer_bound_lock_); + on_ready_callback_ = std::move(callback); + if (is_recognizer_bound_) { + to_run = std::move(on_ready_callback_); + } + } + if (to_run) { + std::move(to_run).Run(); + } } void ChromeSpeechRecognitionClient::Reconfigure( @@ -118,15 +128,20 @@ void ChromeSpeechRecognitionClient::Reconfigure( void ChromeSpeechRecognitionClient::OnRecognizerBound( bool is_multichannel_supported) { + SpeechRecognitionClient::OnReadyCallback to_run; { base::AutoLock auto_lock(is_recognizer_bound_lock_); is_recognizer_bound_ = true; + // Extract under lock; SetOnReadyCallback() may be running concurrently on + // the media sequence. + to_run = std::move(on_ready_callback_); } is_multichannel_supported_ = is_multichannel_supported; - if (on_ready_callback_) - std::move(on_ready_callback_).Run(); + if (to_run) { + std::move(to_run).Run(); + } } void ChromeSpeechRecognitionClient::SpeechRecognitionAvailabilityChanged( diff --git a/chrome/renderer/media/chrome_speech_recognition_client.h b/chrome/renderer/media/chrome_speech_recognition_client.h index 20d2497d6eba6..03cac02a9f19c 100644 --- a/chrome/renderer/media/chrome_speech_recognition_client.h +++ b/chrome/renderer/media/chrome_speech_recognition_client.h @@ -105,7 +105,8 @@ class ChromeSpeechRecognitionClient ChromeSpeechRecognitionClient::InitializeCallback initialize_callback_; - media::SpeechRecognitionClient::OnReadyCallback on_ready_callback_; + media::SpeechRecognitionClient::OnReadyCallback on_ready_callback_ + GUARDED_BY(is_recognizer_bound_lock_); base::RepeatingClosure reset_callback_;