diff options
author | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-05 22:15:26 +0000 |
---|---|---|
committer | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-05 22:15:26 +0000 |
commit | d07b760c638f1c7f4b9b10caceb663dc03f6ac4e (patch) | |
tree | be29ba4bd70fa2f8562c9ccfbc80e981740e27cd /media/audio | |
parent | 8d5bd540ada2783c6bf153bf0c57e82996ffd8fb (diff) | |
download | chromium_src-d07b760c638f1c7f4b9b10caceb663dc03f6ac4e.zip chromium_src-d07b760c638f1c7f4b9b10caceb663dc03f6ac4e.tar.gz chromium_src-d07b760c638f1c7f4b9b10caceb663dc03f6ac4e.tar.bz2 |
AudioManager::Shutdown() can potentially happen before all the ALSA streams are deleted. And in AudioManager::Shutdown(), we invalidate the message loop by audio_thread_.swap(audio_thread), and a crash will happen when the alive ALSA streams try to access to the message loop via manager_->GetMessageLoop().
BUG=130730
TEST=using http://www.corp.google.com/~xians/webrtc_test_audio_tag.html to setup a loopback audio.
Review URL: https://chromiumcodereview.appspot.com/10446118
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140633 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r-- | media/audio/linux/alsa_output.cc | 8 | ||||
-rw-r--r-- | media/audio/linux/alsa_output.h | 6 |
2 files changed, 10 insertions, 4 deletions
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc index 2f8461b..86c3999 100644 --- a/media/audio/linux/alsa_output.cc +++ b/media/audio/linux/alsa_output.cc @@ -169,13 +169,14 @@ AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, stop_stream_(false), wrapper_(wrapper), manager_(manager), + message_loop_(MessageLoop::current()), playback_handle_(NULL), frames_per_packet_(packet_size_ / bytes_per_frame_), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), state_(kCreated), volume_(1.0f), source_callback_(NULL) { - DCHECK(IsOnAudioThread()); + DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); // Sanity check input values. if (params.sample_rate() > kAlsaMaxSampleRate || @@ -548,7 +549,7 @@ void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) { // Only schedule more reads/writes if we are still in the playing state. if (state() == kIsPlaying) { - manager_->GetMessageLoop()->PostDelayedTask( + message_loop_->PostDelayedTask( FROM_HERE, base::Bind(&AlsaPcmOutputStream::WriteTask, weak_factory_.GetWeakPtr()), @@ -780,8 +781,7 @@ AlsaPcmOutputStream::InternalState AlsaPcmOutputStream::state() { } bool AlsaPcmOutputStream::IsOnAudioThread() const { - return !manager_->GetMessageLoop() || - manager_->GetMessageLoop()->BelongsToCurrentThread(); + return message_loop_ && message_loop_ == MessageLoop::current(); } uint32 AlsaPcmOutputStream::RunDataCallback(uint8* dest, diff --git a/media/audio/linux/alsa_output.h b/media/audio/linux/alsa_output.h index e11d6ec..7415821 100644 --- a/media/audio/linux/alsa_output.h +++ b/media/audio/linux/alsa_output.h @@ -190,6 +190,12 @@ class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { // Audio manager that created us. Used to report that we've been closed. AudioManagerLinux* manager_; + // Message loop to use for polling. The object is owned by the AudioManager. + // We hold a reference to the audio thread message loop since + // AudioManagerBase::ShutDown() can invalidate the message loop pointer + // before the stream gets deleted. + MessageLoop* message_loop_; + // Handle to the actual PCM playback device. snd_pcm_t* playback_handle_; |