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

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

Issue 1036993003: Fix the way locks are acquired in WebRtcAudioDeviceImpl::SetAudioRenderer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Name variables in comments according to convention, extra header comment. Created 5 years, 8 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
« no previous file with comments | « content/renderer/media/webrtc_audio_device_impl.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/webrtc_audio_device_impl.h" 5 #include "content/renderer/media/webrtc_audio_device_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/win/windows_version.h" 10 #include "base/win/windows_version.h"
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 uint32_t* sample_rate) const { 390 uint32_t* sample_rate) const {
391 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 391 DCHECK(signaling_thread_checker_.CalledOnValidThread());
392 *sample_rate = renderer_.get() ? renderer_->sample_rate() : 0; 392 *sample_rate = renderer_.get() ? renderer_->sample_rate() : 0;
393 return 0; 393 return 0;
394 } 394 }
395 395
396 bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) { 396 bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) {
397 DCHECK(main_thread_checker_.CalledOnValidThread()); 397 DCHECK(main_thread_checker_.CalledOnValidThread());
398 DCHECK(renderer); 398 DCHECK(renderer);
399 399
400 base::AutoLock auto_lock(lock_); 400 // Here we acquire |lock_| in order to protect the internal state.
401 if (renderer_.get()) 401 {
402 return false; 402 base::AutoLock auto_lock(lock_);
403 if (renderer_.get())
404 return false;
405 }
403 406
407 // We release |lock_| here because invoking |renderer|->Initialize while
408 // holding |lock_| would result in locks taken in the sequence
409 // (|this->lock_|, |renderer->lock_|) while another thread (i.e, the
410 // AudioOutputDevice thread) might concurrently invoke a renderer method,
411 // which can itself invoke a method from |this|, resulting in locks taken in
412 // the sequence (|renderer->lock_|, |this->lock_|) in that thread.
413 // This order discrepancy can cause a deadlock (see Issue 433993).
414 // However, we do not need to hold |this->lock_| in order to invoke
415 // |renderer|->Initialize, since it does not involve any unprotected access to
416 // the internal state of |this|.
404 if (!renderer->Initialize(this)) 417 if (!renderer->Initialize(this))
405 return false; 418 return false;
406 419
420 // We acquire |lock_| again and assert our precondition, since we are
421 // accessing the internal state again.
422 base::AutoLock auto_lock(lock_);
423 DCHECK(!renderer_.get());
tommi (sloooow) - chröme 2015/03/31 08:29:13 Would also be good to have a note here about how i
407 renderer_ = renderer; 424 renderer_ = renderer;
408 return true; 425 return true;
409 } 426 }
410 427
411 void WebRtcAudioDeviceImpl::AddAudioCapturer( 428 void WebRtcAudioDeviceImpl::AddAudioCapturer(
412 const scoped_refptr<WebRtcAudioCapturer>& capturer) { 429 const scoped_refptr<WebRtcAudioCapturer>& capturer) {
413 DCHECK(main_thread_checker_.CalledOnValidThread()); 430 DCHECK(main_thread_checker_.CalledOnValidThread());
414 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()"; 431 DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()";
415 DCHECK(capturer.get()); 432 DCHECK(capturer.get());
416 DCHECK(!capturer->device_id().empty()); 433 DCHECK(!capturer->device_id().empty());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 // If there is no capturer or there are more than one open capture devices, 488 // If there is no capturer or there are more than one open capture devices,
472 // return false. 489 // return false.
473 if (capturers_.size() != 1) 490 if (capturers_.size() != 1)
474 return false; 491 return false;
475 492
476 return capturers_.back()->GetPairedOutputParameters( 493 return capturers_.back()->GetPairedOutputParameters(
477 session_id, output_sample_rate, output_frames_per_buffer); 494 session_id, output_sample_rate, output_frames_per_buffer);
478 } 495 }
479 496
480 } // namespace content 497 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_device_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698