diff options
author | xhwang <xhwang@chromium.org> | 2014-08-27 22:49:17 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-28 05:50:25 +0000 |
commit | 7def98aadf7cac26952eae1fb3294f56510d67d7 (patch) | |
tree | f801f90bf343976a70a653c8bd696e6b6b60db79 /media | |
parent | 6b4a887992b2c27041007630b233f402ddaed9a2 (diff) | |
download | chromium_src-7def98aadf7cac26952eae1fb3294f56510d67d7.zip chromium_src-7def98aadf7cac26952eae1fb3294f56510d67d7.tar.gz chromium_src-7def98aadf7cac26952eae1fb3294f56510d67d7.tar.bz2 |
Avoid deadlock between Pipeline and RendererImpl.
Both Pipeline and RendererImpl use it's own lock. We could end up with a dead
lock in the following scenario:
- On main thread, Pipeline holds it's lock (lock A) and calls into RendererImpl,
which also requires the RendererImpl's lock (lock B).
- On media thread, RendererImpl holds it's lock B and calls callback provided by
the Pipeline, which requires lock A.
This CL makes sure Pipeline never calls into RendererImpl while holding lock A
and RendererImpl nevers calls (back) into Pipeline while holding lock B. So
deadlock should not happen.
This CL also reverts 3 CLs that disabled various tests due to the bug:
- Revert "Exclude tests that deadlock under DrMemory (and Tsan)"
This reverts commit 0e014b9ad964236d67db60488168dbc0811655e9.
- Revert "Disable deadlock-y tests in TSan instead of just suppressing the error."
This reverts commit f712d106692d782f2a590a8e752f720ad76ee608.
- Revert "Suppress a deadlock report through media::Pipeline::GetMediaTime."
This reverts commit 5c72e0f67ce7e42804d809183bdae190024056ef.
BUG=407452
TEST=Ran PipelineIntegrationTest.ChunkDemuxerAbortRead_VideoOnly in a TSAN build for 10 mins and didn't see any issue.
Review URL: https://codereview.chromium.org/512973002
Cr-Commit-Position: refs/heads/master@{#292332}
Diffstat (limited to 'media')
-rw-r--r-- | media/base/pipeline.cc | 10 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test.cc | 3 | ||||
-rw-r--r-- | media/filters/renderer_impl.cc | 8 |
3 files changed, 12 insertions, 9 deletions
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc index 41eeb98..5b5826e 100644 --- a/media/base/pipeline.cc +++ b/media/base/pipeline.cc @@ -153,9 +153,13 @@ void Pipeline::SetVolume(float volume) { } TimeDelta Pipeline::GetMediaTime() const { + if (!renderer_) + return TimeDelta(); + + TimeDelta media_time = renderer_->GetMediaTime(); + base::AutoLock auto_lock(lock_); - return renderer_ ? std::min(renderer_->GetMediaTime(), duration_) - : TimeDelta(); + return std::min(media_time, duration_); } Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() const { @@ -439,7 +443,7 @@ void Pipeline::OnStopCompleted(PipelineStatus status) { DCHECK(!text_renderer_); { - base::AutoLock l(lock_); + base::AutoLock auto_lock(lock_); running_ = false; } diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc index f893fd9..3f24646 100644 --- a/media/filters/pipeline_integration_test.cc +++ b/media/filters/pipeline_integration_test.cc @@ -1425,8 +1425,6 @@ TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_AudioOnly) { 0x10CA, 19730)); } -// http://crbug.com/407452 -#if !defined(THREAD_SANITIZER) // Verify video decoder & renderer can handle aborted demuxer reads. TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) { ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", kVideoOnlyWebM, @@ -1435,7 +1433,6 @@ TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) { base::TimeDelta::FromMilliseconds(1668), 0x1C896, 65536)); } -#endif // !defined(THREAD_SANITIZER) // Verify that Opus audio in WebM containers can be played back. TEST_F(PipelineIntegrationTest, BasicPlayback_AudioOnly_Opus_WebM) { diff --git a/media/filters/renderer_impl.cc b/media/filters/renderer_impl.cc index 1dcbe1c..5361a2d 100644 --- a/media/filters/renderer_impl.cc +++ b/media/filters/renderer_impl.cc @@ -456,9 +456,10 @@ void RendererImpl::StartPlayback() { interpolation_state_ = INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE; time_source_->StartTicking(); } else { + base::TimeDelta duration = get_duration_cb_.Run(); base::AutoLock auto_lock(interpolator_lock_); interpolation_state_ = INTERPOLATION_STARTED; - interpolator_->SetUpperBound(get_duration_cb_.Run()); + interpolator_->SetUpperBound(duration); interpolator_->StartInterpolating(); } } @@ -505,8 +506,9 @@ void RendererImpl::OnAudioRendererEnded() { // Start clock since there is no more audio to trigger clock updates. { + base::TimeDelta duration = get_duration_cb_.Run(); base::AutoLock auto_lock(interpolator_lock_); - interpolator_->SetUpperBound(get_duration_cb_.Run()); + interpolator_->SetUpperBound(duration); StartClockIfWaitingForTimeUpdate_Locked(); } @@ -537,9 +539,9 @@ void RendererImpl::RunEndedCallbackIfNeeded() { return; { + base::TimeDelta duration = get_duration_cb_.Run(); base::AutoLock auto_lock(interpolator_lock_); PauseClockAndStopTicking_Locked(); - base::TimeDelta duration = get_duration_cb_.Run(); interpolator_->SetBounds(duration, duration); } |