Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(912)

Unified Diff: media/base/audio_renderer_mixer_input.cc

Issue 1748183006: Add lock to fix race in AudioRendererMixerInput. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moving lock down in ProvideInput Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/audio_renderer_mixer_input.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/audio_renderer_mixer_input.cc
diff --git a/media/base/audio_renderer_mixer_input.cc b/media/base/audio_renderer_mixer_input.cc
index 5743700f04b0a62c1c3c6eaf0f2d0bfa54aef0f5..f9905383c4cba1f9b9108a8d330e4be10040df9c 100644
--- a/media/base/audio_renderer_mixer_input.cc
+++ b/media/base/audio_renderer_mixer_input.cc
@@ -29,15 +29,22 @@ AudioRendererMixerInput::AudioRendererMixerInput(
mixer_(nullptr),
callback_(nullptr),
error_cb_(base::Bind(&AudioRendererMixerInput::OnRenderError,
- base::Unretained(this))) {}
+ base::Unretained(this))) {
+ // Can be constructed on any thread, but sink operations should all occur
+ // on same thread.
+ thread_checker_.DetachFromThread();
+}
AudioRendererMixerInput::~AudioRendererMixerInput() {
+ DCHECK(!started_);
DCHECK(!mixer_);
}
void AudioRendererMixerInput::Initialize(
const AudioParameters& params,
AudioRendererSink::RenderCallback* callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!started_);
DCHECK(!mixer_);
DCHECK(callback);
@@ -46,6 +53,7 @@ void AudioRendererMixerInput::Initialize(
}
void AudioRendererMixerInput::Start() {
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!started_);
DCHECK(!mixer_);
DCHECK(callback_); // Initialized.
@@ -68,6 +76,8 @@ void AudioRendererMixerInput::Start() {
}
void AudioRendererMixerInput::Stop() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
// Stop() may be called at any time, if Pause() hasn't been called we need to
// remove our mixer input before shutdown.
Pause();
@@ -90,6 +100,8 @@ void AudioRendererMixerInput::Stop() {
}
void AudioRendererMixerInput::Play() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
if (playing_ || !mixer_)
return;
@@ -98,6 +110,8 @@ void AudioRendererMixerInput::Play() {
}
void AudioRendererMixerInput::Pause() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
if (!playing_ || !mixer_)
return;
@@ -106,6 +120,8 @@ void AudioRendererMixerInput::Pause() {
}
bool AudioRendererMixerInput::SetVolume(double volume) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ base::AutoLock auto_lock(volume_lock_);
volume_ = volume;
return true;
}
@@ -118,6 +134,8 @@ void AudioRendererMixerInput::SwitchOutputDevice(
const std::string& device_id,
const url::Origin& security_origin,
const SwitchOutputDeviceCB& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
if (!mixer_) {
if (pending_switch_callback_.is_null()) {
pending_switch_callback_ = callback;
@@ -159,12 +177,16 @@ void AudioRendererMixerInput::SwitchOutputDevice(
}
AudioParameters AudioRendererMixerInput::GetOutputParameters() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
if (mixer_)
return mixer_->GetOutputDevice()->GetOutputParameters();
return get_hardware_params_cb_.Run(device_id_, security_origin_);
}
OutputDeviceStatus AudioRendererMixerInput::GetDeviceStatus() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
if (mixer_)
return mixer_->GetOutputDevice()->GetDeviceStatus();
@@ -176,6 +198,11 @@ OutputDeviceStatus AudioRendererMixerInput::GetDeviceStatus() {
double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus,
base::TimeDelta buffer_delay) {
+ // No thread checker here. This method is called on a different thread as part
+ // of audio rendering. AudioRendererMixer has locks that protect us from
+ // things like attempting to ProvideInput while simultaneously removing
+ // ourselves from mixer inputs (see Pause()).
+
// TODO(chcunningham): Delete this conversion and change ProvideInput to more
// precisely describe delay as a count of frames delayed instead of TimeDelta.
// See http://crbug.com/587522.
@@ -190,7 +217,11 @@ double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus,
frames_filled, audio_bus->frames() - frames_filled);
}
- return frames_filled > 0 ? volume_ : 0;
+ // Synchronize access to |volume_| with SetVolume().
+ {
DaleCurtis 2016/03/03 23:08:01 {} are unnecessary since you're right above a retu
chcunningham1 2016/03/03 23:18:53 thought maybe you'd ask for it as a best practice.
DaleCurtis 2016/03/03 23:26:41 I don't feel strongly. We typically only use {} ar
+ base::AutoLock auto_lock(volume_lock_);
+ return frames_filled > 0 ? volume_ : 0;
+ }
}
void AudioRendererMixerInput::OnRenderError() {
« no previous file with comments | « media/base/audio_renderer_mixer_input.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698