summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2022-08-15 17:10:40 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-11-09 11:48:35 +0100
commit0e6f6c964256358e4970442d130c09a1320b1666 (patch)
tree56b712cd40ce5fb09b544b0709b4da863813a579
parentce837f21f22d3a0851781dbf6627beb18bfae3f3 (diff)
downloadqtwebengine-chromium-0e6f6c964256358e4970442d130c09a1320b1666.tar.gz
Reland two changes for establishing gpu channel
244709: Stop orphan child processes from staying alive on Windows https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/244709 Stop orphan child processes from staying alive on Windows Starting with Qt 5.11, on Windows, when the main WebEngine process crashed, the child render process would stay alive and use a whole CPU core trying to do something. What happened was that an existing layer tree frame sink was invalidated, and a request to create a new one was issued via RequestNewLayerTreeFrameSink, which failed due to the main process being dead, which scheduled a new request, and so on, which caused the child process main thread message loop to never exit. In Qt 5.10, this did not happen, because when the first request to create the sink failed, a new "software sink" was successfully created that did not depend on the host GPU process thread (see RenderThreadImpl::RequestNewLayerTreeFrameSink in render_thread_impl.cc). Thus the message loop ran out of tasks to execute, and could gracefully quit. The "software sink" code branch was removed in Qt 5.11+. Thus the hacky fix is to try and create the sink only a certain amount of times, and stop scheduling new requests after that. ------------------------------------------------------------------ 426757: Fix endless loop on race condition on qemu startup https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/426757 Fix endless loop on race condition on qemu startup Fix a weird race condition which ends in endless loop with a single-process, when gpu_channel_host is not ready in WidgetBase::RequestNewLayerTreeFrameSink and calls callbeck with nullptr, which ends in LayerTreeView::DidFailToInitializeLayerTreeFrameSink which again calls RequestNewLayerTreeFrameSink without giving a chance to initialize channel and round repeats itself. Give 10ms delay to cover the issue. ------------------------------------------------------------------ Fixes: QTBUG-105063 Task-number: QTBUG-69030 Task-number: QTBUG-105342 Pick-to: 98-based Change-Id: Icf3e4c75e009ae7b171a9e9ce2a394f8de421737 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h1
2 files changed, 15 insertions, 2 deletions
diff --git a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
index 347430db1cc..0b450603a27 100644
--- a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
@@ -153,6 +153,7 @@ void LayerTreeView::SetLayerTreeFrameSink(
layer_tree_host_->SetRenderFrameObserver(
std::move(render_frame_metadata_observer));
}
+ layer_tree_frame_sink_init_failures = 0;
layer_tree_host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
}
@@ -271,9 +272,20 @@ void LayerTreeView::DidFailToInitializeLayerTreeFrameSink() {
return;
}
layer_tree_frame_sink_request_failed_while_invisible_ = false;
- layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
+
+ // Guard against infinite loop of trying to request a new sink, and constantly failing,
+ // and trying again, when the child's main process was killed / crashed. This allows the
+ // orhpan render processes to quit gracefully, isntead of spinning the CPU forever.
+ ++layer_tree_frame_sink_init_failures;
+ if (layer_tree_frame_sink_init_failures > 10) {
+ DCHECK(false); // should not really happen, better to crash then stay forver.
+ return;
+ }
+
+ //in case of dead gpu channel there no chance to recover without some delay
+ layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostDelayedTask(
FROM_HERE, base::BindOnce(&LayerTreeView::RequestNewLayerTreeFrameSink,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr()), base::Milliseconds(10));
}
void LayerTreeView::WillCommit(const cc::CommitState&) {
diff --git a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h
index 19fc0b267d3..dfad2b3a9cd 100644
--- a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h
+++ b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h
@@ -168,6 +168,7 @@ class PLATFORM_EXPORT LayerTreeView
// This class should do nothing and access no pointers once this value becomes
// true.
bool layer_tree_frame_sink_request_failed_while_invisible_ = false;
+ int layer_tree_frame_sink_init_failures = 0;
base::circular_deque<
std::pair<uint32_t,