diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2018-11-06 11:17:53 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-12-20 13:50:53 +0100 |
commit | 51bf89d179a7240e79dcf95642f365e9f127c619 (patch) | |
tree | 4c763f952cd8c6df0777d5755865a93e5ab8233b | |
parent | d1868af2444ed405e2b2bf5bcac271f91baddbec (diff) | |
download | qtwebengine-chromium-51bf89d179a7240e79dcf95642f365e9f127c619.tar.gz |
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.
Task-number: QTBUG-69030
Change-Id: Iefd302aac48aa8729d8289490ddb310a5037ad96
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r-- | chromium/content/renderer/gpu/layer_tree_view.cc | 9 | ||||
-rw-r--r-- | chromium/content/renderer/gpu/layer_tree_view.h | 2 |
2 files changed, 11 insertions, 0 deletions
diff --git a/chromium/content/renderer/gpu/layer_tree_view.cc b/chromium/content/renderer/gpu/layer_tree_view.cc index c8433165482..7a31aa2b683 100644 --- a/chromium/content/renderer/gpu/layer_tree_view.cc +++ b/chromium/content/renderer/gpu/layer_tree_view.cc @@ -430,6 +430,7 @@ void LayerTreeView::SetLayerTreeFrameSink( DidFailToInitializeLayerTreeFrameSink(); return; } + layer_tree_frame_sink_init_failures = 0; layer_tree_host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink)); } @@ -642,6 +643,14 @@ void LayerTreeView::DidFailToInitializeLayerTreeFrameSink() { return; } layer_tree_frame_sink_request_failed_while_invisible_ = false; + + // 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 > 9) + return; + layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&LayerTreeView::RequestNewLayerTreeFrameSink, weak_factory_.GetWeakPtr())); diff --git a/chromium/content/renderer/gpu/layer_tree_view.h b/chromium/content/renderer/gpu/layer_tree_view.h index daa30344d7e..317d38ce588 100644 --- a/chromium/content/renderer/gpu/layer_tree_view.h +++ b/chromium/content/renderer/gpu/layer_tree_view.h @@ -238,6 +238,8 @@ class CONTENT_EXPORT LayerTreeView bool layer_tree_frame_sink_request_failed_while_invisible_ = false; + int layer_tree_frame_sink_init_failures = 0; + bool in_synchronous_compositor_update_ = false; base::OnceClosure layout_and_paint_async_callback_; |