Diff
Modified: trunk/Source/WebKit/ChangeLog (276847 => 276848)
--- trunk/Source/WebKit/ChangeLog 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Source/WebKit/ChangeLog 2021-04-30 18:58:03 UTC (rev 276848)
@@ -1,3 +1,21 @@
+2021-04-30 Miguel Gomez <[email protected]>
+
+ [GTK][WPE] Properly recover from unresponsive web processes
+ https://bugs.webkit.org/show_bug.cgi?id=224533
+
+ Reviewed by Carlos Garcia Campos.
+
+ Add a new method to the GLib API to terminate the web process associated to a
+ WebKitWebView.
+
+ * UIProcess/API/glib/WebKitNavigationClient.cpp:
+ * UIProcess/API/glib/WebKitWebView.cpp:
+ (webkit_web_view_terminate_web_process):
+ * UIProcess/API/gtk/WebKitWebView.h:
+ * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
+ * UIProcess/API/wpe/WebKitWebView.h:
+ * UIProcess/API/wpe/docs/wpe-1.0-sections.txt:
+
2021-04-30 Per Arne <[email protected]>
Enforce IOKit filtering
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitNavigationClient.cpp (276847 => 276848)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitNavigationClient.cpp 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitNavigationClient.cpp 2021-04-30 18:58:03 UTC (rev 276848)
@@ -115,8 +115,10 @@
case ProcessTerminationReason::ExceededMemoryLimit:
webkitWebViewWebProcessTerminated(m_webView, WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT);
return true;
+ case ProcessTerminationReason::RequestedByClient:
+ webkitWebViewWebProcessTerminated(m_webView, WEBKIT_WEB_PROCESS_TERMINATED_BY_API);
+ return true;
case ProcessTerminationReason::ExceededCPULimit:
- case ProcessTerminationReason::RequestedByClient:
case ProcessTerminationReason::RequestedByNetworkProcess:
case ProcessTerminationReason::NavigationSwap:
case ProcessTerminationReason::RequestedByGPUProcess:
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp (276847 => 276848)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp 2021-04-30 18:58:03 UTC (rev 276848)
@@ -28,6 +28,7 @@
#include "APISerializedScriptValue.h"
#include "DataReference.h"
#include "ImageOptions.h"
+#include "ProvisionalPageProxy.h"
#include "WebCertificateInfo.h"
#include "WebContextMenuItem.h"
#include "WebContextMenuItemData.h"
@@ -4752,3 +4753,31 @@
return webView->priv->isWebProcessResponsive;
}
+
+/**
+ * webkit_web_view_terminate_web_process:
+ * @web_view: a #WebKitWebView
+ *
+ * Terminates the web process associated to @web_view. When the web process gets terminated
+ * using this method, the #WebKitWebView::web-process-terminated signal is emitted with
+ * %WEBKIT_WEB_PROCESS_TERMINATED_BY_API as the reason for termination.
+ *
+ * Since: 2.34
+ */
+void webkit_web_view_terminate_web_process(WebKitWebView* webView)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
+
+ auto& page = getPage(webView);
+
+ Ref<WebKit::WebProcessProxy> protectedProcessProxy(page.process());
+ protectedProcessProxy->requestTermination(WebKit::ProcessTerminationReason::RequestedByClient);
+
+ if (auto* provisionalPageProxy = page.provisionalPageProxy()) {
+ Ref<WebKit::WebProcessProxy> protectedProcessProxy(provisionalPageProxy->process());
+ protectedProcessProxy->requestTermination(WebKit::ProcessTerminationReason::RequestedByClient);
+ }
+
+ // Reset the state of the responsiveness property.
+ webkitWebViewSetIsWebProcessResponsive(webView, true);
+}
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebView.h (276847 => 276848)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebView.h 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebView.h 2021-04-30 18:58:03 UTC (rev 276848)
@@ -193,6 +193,7 @@
* WebKitWebProcessTerminationReason:
* @WEBKIT_WEB_PROCESS_CRASHED: the web process crashed.
* @WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT: the web process exceeded the memory limit.
+ * @WEBKIT_WEB_PROCESS_TERMINATED_BY_API: the web process termination was requested by an API call. Since: 2.34
*
* Enum values used to specify the reason why the web process terminated abnormally.
*
@@ -200,7 +201,8 @@
*/
typedef enum {
WEBKIT_WEB_PROCESS_CRASHED,
- WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT
+ WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT,
+ WEBKIT_WEB_PROCESS_TERMINATED_BY_API
} WebKitWebProcessTerminationReason;
struct _WebKitWebView {
@@ -592,6 +594,9 @@
WEBKIT_API gboolean
webkit_web_view_get_is_web_process_responsive (WebKitWebView *web_view);
+WEBKIT_API void
+webkit_web_view_terminate_web_process (WebKitWebView *web_view);
+
G_END_DECLS
#endif
Modified: trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (276847 => 276848)
--- trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2021-04-30 18:58:03 UTC (rev 276848)
@@ -291,6 +291,7 @@
webkit_web_view_get_input_method_context
webkit_web_view_get_website_policies
webkit_web_view_get_is_web_process_responsive
+webkit_web_view_terminate_web_process
<SUBSECTION WebKitJavascriptResult>
WebKitJavascriptResult
Modified: trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebView.h (276847 => 276848)
--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebView.h 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebView.h 2021-04-30 18:58:03 UTC (rev 276848)
@@ -162,6 +162,7 @@
* WebKitWebProcessTerminationReason:
* @WEBKIT_WEB_PROCESS_CRASHED: the web process crashed.
* @WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT: the web process exceeded the memory limit.
+ * @WEBKIT_WEB_PROCESS_TERMINATED_BY_API: the web process termination was requested by an API call. Since: 2.34
*
* Enum values used to specify the reason why the web process terminated abnormally.
*
@@ -169,7 +170,8 @@
*/
typedef enum {
WEBKIT_WEB_PROCESS_CRASHED,
- WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT
+ WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT,
+ WEBKIT_WEB_PROCESS_TERMINATED_BY_API
} WebKitWebProcessTerminationReason;
/**
@@ -568,6 +570,9 @@
WEBKIT_API gboolean
webkit_web_view_get_is_web_process_responsive (WebKitWebView *web_view);
+WEBKIT_API void
+webkit_web_view_terminate_web_process (WebKitWebView *web_view);
+
G_END_DECLS
#endif
Modified: trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt (276847 => 276848)
--- trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt 2021-04-30 18:58:03 UTC (rev 276848)
@@ -263,6 +263,7 @@
webkit_web_view_get_input_method_context
webkit_web_view_get_website_policies
webkit_web_view_get_is_web_process_responsive
+webkit_web_view_terminate_web_process
<SUBSECTION WebKitJavascriptResult>
WebKitJavascriptResult
Modified: trunk/Tools/ChangeLog (276847 => 276848)
--- trunk/Tools/ChangeLog 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Tools/ChangeLog 2021-04-30 18:58:03 UTC (rev 276848)
@@ -1,3 +1,24 @@
+2021-04-30 Miguel Gomez <[email protected]>
+
+ [GTK][WPE] Properly recover from unresponsive web processes
+ https://bugs.webkit.org/show_bug.cgi?id=224533
+
+ Reviewed by Carlos Garcia Campos.
+
+ Add unit tests for the new webkit_web_view_terminate_web_process GLib API method. Also move
+ the methods used to wait for responsiveness changes to WebViewTest, as they are used by more
+ than a single test.
+
+ * TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp:
+ (testWebViewIsWebProcessResponsive):
+ (testWebViewTerminateWebProcess):
+ (testWebViewTerminateUnresponsiveWebProcess):
+ (beforeAll):
+ * TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp:
+ (isWebProcessResponsiveChanged):
+ (WebViewTest::waitUntilIsWebProcessResponsiveChanged):
+ * TestWebKitAPI/glib/WebKitGLib/WebViewTest.h:
+
2021-04-30 Jonathan Bedard <[email protected]>
[webkitpy] Support pickling platforminfo
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp (276847 => 276848)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp 2021-04-30 18:58:03 UTC (rev 276848)
@@ -1177,24 +1177,7 @@
g_assert_cmpint(webkit_website_policies_get_autoplay_policy(policies), ==, WEBKIT_AUTOPLAY_ALLOW_WITHOUT_SOUND);
}
-class WebViewIsWebProcessResponsiveTest: public WebViewTest {
-public:
- MAKE_GLIB_TEST_FIXTURE(WebViewIsWebProcessResponsiveTest);
-
- static void isWebProcessResponsiveChanged(WebKitWebView* view, GParamSpec*, WebViewIsWebProcessResponsiveTest* test)
- {
- g_signal_handlers_disconnect_by_func(test->m_webView, reinterpret_cast<void*>(isWebProcessResponsiveChanged), test);
- g_main_loop_quit(test->m_mainLoop);
- }
-
- void waitUntilIsWebProcessResponsiveChanged()
- {
- g_signal_connect(m_webView, "notify::is-web-process-responsive", G_CALLBACK(isWebProcessResponsiveChanged), this);
- g_main_loop_run(m_mainLoop);
- }
-};
-
-static void testWebViewIsWebProcessResponsive(WebViewIsWebProcessResponsiveTest* test, gconstpointer)
+static void testWebViewIsWebProcessResponsive(WebViewTest* test, gconstpointer)
{
static const char* hangHTML =
"<html>"
@@ -1561,6 +1544,70 @@
}
#endif
+class WebViewTerminateWebProcessTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(WebViewTerminateWebProcessTest);
+
+ static void webProcessTerminatedCallback(WebKitWebView* webView, WebKitWebProcessTerminationReason reason, WebViewTerminateWebProcessTest* test)
+ {
+ test->m_terminationReason = reason;
+ }
+
+ WebViewTerminateWebProcessTest()
+ {
+ g_signal_connect_after(m_webView, "web-process-terminated", G_CALLBACK(WebViewTerminateWebProcessTest::webProcessTerminatedCallback), this);
+ }
+
+ ~WebViewTerminateWebProcessTest()
+ {
+ g_signal_handlers_disconnect_by_data(m_webView, this);
+ }
+
+ WebKitWebProcessTerminationReason m_terminationReason { WEBKIT_WEB_PROCESS_CRASHED };
+};
+
+static void testWebViewTerminateWebProcess(WebViewTerminateWebProcessTest* test, gconstpointer)
+{
+ test->loadHtml("<html></html>", nullptr);
+ test->waitUntilLoadFinished();
+ test->m_expectedWebProcessCrash = true;
+ webkit_web_view_terminate_web_process(test->m_webView);
+ g_assert_cmpuint(test->m_terminationReason, ==, WEBKIT_WEB_PROCESS_TERMINATED_BY_API);
+ g_assert_true(webkit_web_view_get_is_web_process_responsive(test->m_webView));
+}
+
+static void testWebViewTerminateUnresponsiveWebProcess(WebViewTerminateWebProcessTest* test, gconstpointer)
+{
+ static const char* hangHTML =
+ "<html>"
+ " <body>"
+ " <script>"
+ " setTimeout(function() {"
+ " while(true) { }"
+ " }, 500);"
+ " </script>"
+ " </body>"
+ "</html>";
+
+ test->loadHtml(hangHTML, nullptr);
+ test->waitUntilLoadFinished();
+ g_assert_true(webkit_web_view_get_is_web_process_responsive(test->m_webView));
+ // Wait 1 second, so the js while loop kicks in and blocks the web process, and try to load a new page.
+ // As the web process is busy this won't work, and after 3 seconds the web process will be marked
+ // as unresponsive.
+ test->wait(1);
+ test->loadHtml("<html></html>", nullptr);
+ test->waitUntilIsWebProcessResponsiveChanged();
+ g_assert_false(webkit_web_view_get_is_web_process_responsive(test->m_webView));
+
+ // Now that the process is unresponsive, terminate it.
+ test->m_expectedWebProcessCrash = true;
+ test->m_terminationReason = WEBKIT_WEB_PROCESS_CRASHED;
+ webkit_web_view_terminate_web_process(test->m_webView);
+ g_assert_cmpuint(test->m_terminationReason, ==, WEBKIT_WEB_PROCESS_TERMINATED_BY_API);
+ g_assert_true(webkit_web_view_get_is_web_process_responsive(test->m_webView));
+}
+
#if USE(SOUP2)
static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
#else
@@ -1628,7 +1675,9 @@
#if PLATFORM(WPE) && USE(WPEBACKEND_FDO_AUDIO_EXTENSION)
AudioRenderingWebViewTest::add("WebKitWebView", "external-audio-rendering", testWebViewExternalAudioRendering);
#endif
- WebViewIsWebProcessResponsiveTest::add("WebKitWebView", "is-web-process-responsive", testWebViewIsWebProcessResponsive);
+ WebViewTest::add("WebKitWebView", "is-web-process-responsive", testWebViewIsWebProcessResponsive);
+ WebViewTerminateWebProcessTest::add("WebKitWebView", "terminate-web-process", testWebViewTerminateWebProcess);
+ WebViewTerminateWebProcessTest::add("WebKitWebView", "terminate-unresponsive-web-process", testWebViewTerminateUnresponsiveWebProcess);
}
void afterAll()
Modified: trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp (276847 => 276848)
--- trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp 2021-04-30 18:58:03 UTC (rev 276848)
@@ -223,6 +223,18 @@
waitUntilTitleChangedTo(0);
}
+static void isWebProcessResponsiveChanged(WebKitWebView* webView, GParamSpec*, WebViewTest* test)
+{
+ g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(isWebProcessResponsiveChanged), test);
+ g_main_loop_quit(test->m_mainLoop);
+}
+
+void WebViewTest::waitUntilIsWebProcessResponsiveChanged()
+{
+ g_signal_connect(m_webView, "notify::is-web-process-responsive", G_CALLBACK(isWebProcessResponsiveChanged), this);
+ g_main_loop_run(m_mainLoop);
+}
+
void WebViewTest::selectAll()
{
webkit_web_view_execute_editing_command(m_webView, "SelectAll");
Modified: trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.h (276847 => 276848)
--- trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.h 2021-04-30 18:39:44 UTC (rev 276847)
+++ trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.h 2021-04-30 18:58:03 UTC (rev 276848)
@@ -53,6 +53,7 @@
void waitUntilTitleChangedTo(const char* expectedTitle);
void waitUntilTitleChanged();
void waitUntilFileChanged(const char*, GFileMonitorEvent);
+ void waitUntilIsWebProcessResponsiveChanged();
void resizeView(int width, int height);
void hideView();
void selectAll();