summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authorxians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-05 22:15:26 +0000
committerxians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-05 22:15:26 +0000
commitd07b760c638f1c7f4b9b10caceb663dc03f6ac4e (patch)
treebe29ba4bd70fa2f8562c9ccfbc80e981740e27cd /media/audio
parent8d5bd540ada2783c6bf153bf0c57e82996ffd8fb (diff)
downloadchromium_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.cc8
-rw-r--r--media/audio/linux/alsa_output.h6
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_;