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

Side by Side Diff: content/renderer/media/audio_device.cc

Issue 9112029: Safe and reliable fix for 2 race conditions. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 8 years, 11 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/renderer/media/audio_device.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/audio_device.h" 5 #include "content/renderer/media/audio_device.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 params.bits_per_sample = bits_per_sample_; 101 params.bits_per_sample = bits_per_sample_;
102 params.samples_per_packet = buffer_size_; 102 params.samples_per_packet = buffer_size_;
103 103
104 ChildProcess::current()->io_message_loop()->PostTask( 104 ChildProcess::current()->io_message_loop()->PostTask(
105 FROM_HERE, 105 FROM_HERE,
106 base::Bind(&AudioDevice::InitializeOnIOThread, this, params)); 106 base::Bind(&AudioDevice::InitializeOnIOThread, this, params));
107 } 107 }
108 108
109 void AudioDevice::Stop() { 109 void AudioDevice::Stop() {
110 DCHECK(MessageLoop::current() != ChildProcess::current()->io_message_loop()); 110 DCHECK(MessageLoop::current() != ChildProcess::current()->io_message_loop());
111 // Max waiting time for Stop() to complete. If this time limit is passed,
112 // we will stop waiting and return false. It ensures that Stop() can't block
113 // the calling thread forever.
114 const base::TimeDelta kMaxTimeOut = base::TimeDelta::FromMilliseconds(1000);
115
116 base::WaitableEvent completion(false, false); 111 base::WaitableEvent completion(false, false);
117 112
118 ChildProcess::current()->io_message_loop()->PostTask( 113 ChildProcess::current()->io_message_loop()->PostTask(
119 FROM_HERE, 114 FROM_HERE,
120 base::Bind(&AudioDevice::ShutDownOnIOThread, this, &completion)); 115 base::Bind(&AudioDevice::ShutDownOnIOThread, this, &completion));
121 116
122 // We wait here for the IO task to be completed to remove race conflicts 117 // We wait here for the IO task to be completed to remove race conflicts
123 // with OnLowLatencyCreated() and to ensure that Stop() acts as a synchronous 118 // with OnLowLatencyCreated() and to ensure that Stop() acts as a synchronous
124 // function call. 119 // function call.
125 if (!completion.TimedWait(kMaxTimeOut)) { 120 completion.Wait();
Chris Rogers 2012/01/06 18:26:28 Is there a case where the time-out is actually nee
tommi (sloooow) - chröme 2012/01/12 13:13:07 What about moving the call to ShutDownAudioThread
126 LOG(ERROR) << "Failed to shut down audio output on IO thread";
127 }
128 ShutDownAudioThread(); 121 ShutDownAudioThread();
129 } 122 }
130 123
131 void AudioDevice::Play() { 124 void AudioDevice::Play() {
132 ChildProcess::current()->io_message_loop()->PostTask( 125 ChildProcess::current()->io_message_loop()->PostTask(
133 FROM_HERE, 126 FROM_HERE,
134 base::Bind(&AudioDevice::PlayOnIOThread, this)); 127 base::Bind(&AudioDevice::PlayOnIOThread, this));
135 } 128 }
136 129
137 void AudioDevice::Pause(bool flush) { 130 void AudioDevice::Pause(bool flush) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 // the stream is first starting. 181 // the stream is first starting.
189 play_on_start_ = false; 182 play_on_start_ = false;
190 } 183 }
191 } 184 }
192 185
193 void AudioDevice::ShutDownOnIOThread(base::WaitableEvent* completion) { 186 void AudioDevice::ShutDownOnIOThread(base::WaitableEvent* completion) {
194 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop()); 187 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
195 is_started_ = false; 188 is_started_ = false;
196 189
197 // Make sure we don't call shutdown more than once. 190 // Make sure we don't call shutdown more than once.
198 if (!stream_id_) { 191 if (!stream_id_) {
tommi (sloooow) - chröme 2012/01/12 13:13:07 nit: this method can be simplified by removing thi
199 if (completion) 192 if (completion)
200 completion->Signal(); 193 completion->Signal();
201 return; 194 return;
202 } 195 }
203 196
204 filter_->RemoveDelegate(stream_id_); 197 filter_->RemoveDelegate(stream_id_);
205 Send(new AudioHostMsg_CloseStream(stream_id_)); 198 Send(new AudioHostMsg_CloseStream(stream_id_));
206 stream_id_ = 0; 199 stream_id_ = 0;
207 200
208 if (completion) 201 if (completion)
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 data, 331 data,
339 buffer_size_); 332 buffer_size_);
340 } 333 }
341 return num_frames; 334 return num_frames;
342 } 335 }
343 336
344 void AudioDevice::ShutDownAudioThread() { 337 void AudioDevice::ShutDownAudioThread() {
345 // Synchronize with OnLowLatencyCreated(). 338 // Synchronize with OnLowLatencyCreated().
346 base::AutoLock auto_lock(lock_); 339 base::AutoLock auto_lock(lock_);
347 if (audio_thread_.get()) { 340 if (audio_thread_.get()) {
348 // Close the socket to terminate the main thread function in the 341 // Close the socket to terminate the main thread function in the
tommi (sloooow) - chröme 2012/01/12 13:13:07 add a check that makes sure we're not currently on
349 // audio thread. 342 // audio thread.
350 audio_socket_->Close(); 343 audio_socket_->Close();
351 audio_thread_->Join(); 344 audio_thread_->Join();
352 audio_thread_.reset(NULL); 345 audio_thread_.reset(NULL);
353 } 346 }
354 } 347 }
OLDNEW
« no previous file with comments | « content/renderer/media/audio_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698