diff options
author | Michal Klocek <michal.klocek@qt.io> | 2022-08-15 17:10:40 +0200 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2022-10-24 12:21:31 +0000 |
commit | 5a0df5283f589e44b58f1741d1f50da5783cc006 (patch) | |
tree | e463954997503b44a707fa875395f224ce8a3c2e | |
parent | 941c6a6c4524f1d7c926d5f3e9bb3974610917d2 (diff) | |
download | qtwebengine-chromium-98-based.tar.gz |
Reland two changes for establishing gpu channel98-based
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
Change-Id: Icf3e4c75e009ae7b171a9e9ce2a394f8de421737
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f07fb08039600e78bac0d8ac998bec5617650a2e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc | 16 | ||||
-rw-r--r-- | chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h | 1 |
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 ed4af1277ae..cfb36087beb 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)); } @@ -270,9 +271,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 ddd785f00b8..56f8fc07f35 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 @@ -151,6 +151,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, |