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

Unified Diff: media/audio/audio_output_device.cc

Issue 10958004: Prevent AudioDeviceThread from starting if clients have called Stop() (round 2). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 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
Index: media/audio/audio_output_device.cc
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc
index 363cb4c67b2dac35b80ed5f46cbea4be52e86935..51111a2800b0f1b6c875fb5d950e4a0cc46382d5 100644
--- a/media/audio/audio_output_device.cc
+++ b/media/audio/audio_output_device.cc
@@ -49,7 +49,8 @@ AudioOutputDevice::AudioOutputDevice(
ipc_(ipc),
stream_id_(0),
play_on_start_(true),
- is_started_(false) {
+ is_started_(false),
+ stopping_(false) {
CHECK(ipc_);
}
@@ -90,6 +91,7 @@ void AudioOutputDevice::Stop() {
{
base::AutoLock auto_lock(audio_thread_lock_);
audio_thread_.Stop(MessageLoop::current());
+ stopping_ = true;
tommi (sloooow) - chröme 2012/09/20 15:00:22 instead of the variable, you can use audio_thread_
scherkus (not reviewing) 2012/09/20 17:48:28 Not quite... OnStreamCreated() DCHECKs for audio_t
}
message_loop()->PostTask(FROM_HERE,
@@ -166,16 +168,14 @@ void AudioOutputDevice::ShutDownOnIOThread() {
stream_id_ = 0;
}
- // We can run into an issue where ShutDownOnIOThread is called right after
- // OnStreamCreated is called in cases where Start/Stop are called before we
- // get the OnStreamCreated callback. To handle that corner case, we call
- // Stop(). In most cases, the thread will already be stopped.
// Another situation is when the IO thread goes away before Stop() is called
// in which case, we cannot use the message loop to close the thread handle
- // and can't not rely on the main thread existing either.
+ // and can't rely on the main thread existing either.
+ base::AutoLock auto_lock_(audio_thread_lock_);
base::ThreadRestrictions::ScopedAllowIO allow_io;
audio_thread_.Stop(NULL);
audio_callback_.reset();
+ stopping_ = false;
tommi (sloooow) - chröme 2012/09/20 15:00:22 this is one place that's functionally different fr
}
void AudioOutputDevice::SetVolumeOnIOThread(double volume) {
@@ -199,6 +199,7 @@ void AudioOutputDevice::OnStateChanged(AudioOutputIPCDelegate::State state) {
// TODO(tommi): Add an explicit contract for clearing the callback
// object. Possibly require calling Initialize again or provide
// a callback object via Start() and clear it in Stop().
+ base::AutoLock auto_lock_(audio_thread_lock_);
tommi (sloooow) - chröme 2012/09/20 15:00:22 this isn't needed. IsStopped() does locking intern
scherkus (not reviewing) 2012/09/20 17:48:28 Done.
if (!audio_thread_.IsStopped())
callback_->OnRenderError();
}
@@ -224,7 +225,19 @@ void AudioOutputDevice::OnStreamCreated(
// delegate and hence it should not receive callbacks.
DCHECK(stream_id_);
+ // Stop() can stop |audio_thread_| before we receive OnStreamCreated().
henrika (OOO until Aug 14) 2012/09/20 07:54:52 Sorry but this sentence is a bit tricky to underst
scherkus (not reviewing) 2012/09/20 17:48:28 Done.
+ // In that case we don't risk starting the thread using |callback_|, which
+ // may have point to freed memory.
tommi (sloooow) - chröme 2012/09/20 15:00:22 If AudioDeviceThread::Stop() has been called, then
scherkus (not reviewing) 2012/09/20 17:48:28 I like all of those ideas but considering this has
+ //
+ // TODO(scherkus): The real fix is to have sane ownership semantics. The fact
henrika (OOO until Aug 14) 2012/09/20 07:54:52 Seems like a very good idea to add a link to crbug
scherkus (not reviewing) 2012/09/20 17:48:28 Done.
+ // that |callback_| (which should own and outlive this object!) can point to
+ // freed memory is a mess. AudioRendererSink should be non-refcounted that
henrika (OOO until Aug 14) 2012/09/20 07:54:52 "that" -> "so that"
scherkus (not reviewing) 2012/09/20 17:48:28 Done.
+ // owners (WebRtcAudioDeviceImpl, AudioRendererImpl, etc...) can Stop() and
+ // delete as they see fit. AudioOutputDevice should internally use WeakPtr
+ // to handle teardown and thread hopping.
base::AutoLock auto_lock(audio_thread_lock_);
+ if (stopping_)
tommi (sloooow) - chröme 2012/09/20 15:00:22 If we change the Start() vs Initialize() contract,
scherkus (not reviewing) 2012/09/20 17:48:28 I prototyped a change and it appears webrtc can us
+ return;
DCHECK(audio_thread_.IsStopped());
audio_callback_.reset(new AudioOutputDevice::AudioThreadCallback(

Powered by Google App Engine
This is Rietveld 408576698