summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2018-11-06 11:17:53 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-20 13:50:53 +0100
commit51bf89d179a7240e79dcf95642f365e9f127c619 (patch)
tree4c763f952cd8c6df0777d5755865a93e5ab8233b
parentd1868af2444ed405e2b2bf5bcac271f91baddbec (diff)
downloadqtwebengine-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.cc9
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view.h2
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_;