Chromium Code Reviews| Index: media/audio/audio_output_dispatcher.cc |
| =================================================================== |
| --- media/audio/audio_output_dispatcher.cc (revision 113173) |
| +++ media/audio/audio_output_dispatcher.cc (working copy) |
| @@ -19,12 +19,16 @@ |
| pause_delay_milliseconds_(2 * params.samples_per_packet * |
| base::Time::kMillisecondsPerSecond / params.sample_rate), |
| paused_proxies_(0), |
| - ALLOW_THIS_IN_INITIALIZER_LIST(close_timer_(FROM_HERE, |
| + ALLOW_THIS_IN_INITIALIZER_LIST(weak_this_(this)), |
|
henrika (OOO until Aug 14)
2011/12/07 10:08:34
Not sure why this is needed.
tommi (sloooow) - chröme
2011/12/07 12:26:44
It allows |this| to be used in an initializer list
henrika (OOO until Aug 14)
2011/12/07 12:48:01
I meant the weak pointer.
tommi (sloooow) - chröme
2011/12/07 14:46:23
Ah. Here's the comment from the header file:
/
|
| + close_timer_(FROM_HERE, |
| base::TimeDelta::FromMilliseconds(close_delay_ms), |
| - this, &AudioOutputDispatcher::ClosePendingStreams)) { |
| + weak_this_.GetWeakPtr(), |
| + &AudioOutputDispatcher::ClosePendingStreams) { |
| + DCHECK_EQ(MessageLoop::current(), message_loop_); |
| } |
| AudioOutputDispatcher::~AudioOutputDispatcher() { |
| + DCHECK_EQ(MessageLoop::current(), message_loop_); |
| } |
| bool AudioOutputDispatcher::StreamOpened() { |
| @@ -58,7 +62,7 @@ |
| // Schedule task to allocate streams for other proxies if we need to. |
| message_loop_->PostTask(FROM_HERE, base::Bind( |
| - &AudioOutputDispatcher::OpenTask, this)); |
| + &AudioOutputDispatcher::OpenTask, weak_this_.GetWeakPtr())); |
| return stream; |
| } |
| @@ -73,13 +77,17 @@ |
| // Don't recycle stream until two buffers worth of time has elapsed. |
| message_loop_->PostDelayedTask( |
| FROM_HERE, |
| - base::Bind(&AudioOutputDispatcher::StopStreamTask, this), |
| + base::Bind(&AudioOutputDispatcher::StopStreamTask, |
| + weak_this_.GetWeakPtr()), |
| pause_delay_milliseconds_); |
| } |
| void AudioOutputDispatcher::StopStreamTask() { |
| + DCHECK_EQ(MessageLoop::current(), message_loop_); |
| + |
| if (pausing_streams_.empty()) |
| return; |
| + |
| AudioOutputStream* stream = pausing_streams_.back(); |
| pausing_streams_.pop_back(); |
| idle_streams_.push_back(stream); |
| @@ -103,16 +111,36 @@ |
| } |
| } |
| +void AudioOutputDispatcher::Shutdown() { |
| + DCHECK_EQ(MessageLoop::current(), message_loop_); |
| + |
| + // Cancel any pending tasks to close paused streams or create new ones. |
| + weak_this_.InvalidateWeakPtrs(); |
| + |
| + // No AudioOutputProxy objects should hold a reference to us when we get |
| + // to this stage. |
| + DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference"; |
| + |
| + AudioOutputStreamList::iterator it = idle_streams_.begin(); |
| + for (; it != idle_streams_.end(); ++it) |
| + (*it)->Close(); |
| + idle_streams_.clear(); |
| + |
| + it = pausing_streams_.begin(); |
| + for (; it != pausing_streams_.end(); ++it) |
| + (*it)->Close(); |
| + pausing_streams_.clear(); |
| +} |
| + |
| MessageLoop* AudioOutputDispatcher::message_loop() { |
| return message_loop_; |
| } |
| bool AudioOutputDispatcher::CreateAndOpenStream() { |
| - AudioOutputStream* stream = |
| - audio_manager_->MakeAudioOutputStream(params_); |
| - if (!stream) { |
| + AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream(params_); |
| + if (!stream) |
| return false; |
| - } |
| + |
| if (!stream->Open()) { |
| stream->Close(); |
| return false; |
| @@ -134,6 +162,8 @@ |
| // This method is called by |close_timer_|. |
| void AudioOutputDispatcher::ClosePendingStreams() { |
| + DCHECK_EQ(MessageLoop::current(), message_loop_); |
| + |
| while (!idle_streams_.empty()) { |
| idle_streams_.back()->Close(); |
| idle_streams_.pop_back(); |