Commit c64c69fc authored by chfremer's avatar chfremer Committed by Commit bot

A deadlock could happen in the following situation:

1. As part of program shutdown, VideoCaptureManager::StopCaptureForClient() is
   called. This posts a task to destroy the capture device to the "device
   thread", which eventually leads to this destructor being called (on the
   "device thread").
2. While things on the "device thread" are running asynchronously,
   BrowserMainLoop is being destroyed. It's destructor waits for the "device
   thread" (audio thread) to complete.
3. |io_task_runner_| does not accept the posted task anymore.
4. |event.Wait()| will wait indefinitely causing the shutdown to hang.

This deadlock occurred on build bot linux_android_rel_ng in CL
https://codereview.chromium.org/2772963002/. It reproduces locally on a Nexus 5
device running KitKat.

In production, class GpuJpegDecodeAcceleratorHost is currenlty only used on
Chrome OS, but it might happen there as well, since the situation does not
appear to be platform-dependent.

BUG=706186
TEST=
  content_browsertests --gtest_filter="VideoCaptureBrowserTest.*"
  content_unittests --gtest_filter="*Video*"
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel

Review-Url: https://codereview.chromium.org/2786503002
Cr-Commit-Position: refs/heads/master@{#460531}
parent 9efba0cd
......@@ -118,11 +118,14 @@ GpuJpegDecodeAcceleratorHost::~GpuJpegDecodeAcceleratorHost() {
// routed to |receiver_| on IO thread.
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
io_task_runner_->PostTask(FROM_HERE,
base::Bind(&Receiver::InvalidateWeakPtr,
base::Unretained(receiver_.get()),
base::Unretained(&event)));
event.Wait();
bool task_expected_to_run = io_task_runner_->PostTask(
FROM_HERE, base::Bind(&Receiver::InvalidateWeakPtr,
base::Unretained(receiver_.get()),
base::Unretained(&event)));
// If the current call is happening during the browser shutdown, the
// |io_task_runner_| may no longer be accepting tasks.
if (task_expected_to_run)
event.Wait();
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment