Reduce timeout for page to handle beforeunload events when trying to close a page
https://bugs.webkit.org/show_bug.cgi?id=204950
<rdar://problem/57700419>

Reviewed by Ryosuke Niwa.

Reduce timeout for page to handle beforeunload events when trying to close a page. It would previously
take up to 3 seconds to actually close a tab after the user would click on the "X" to close it. This
is because we would wait for the page to fire and handle the beforeunload events and only give up after
3 seconds. This patch reduces this timeout to something more reasonable from a user standpoint (500ms).

* UIProcess/WebPageProxy.cpp:
(WebKit::m_tryCloseTimeoutTimer):
(WebKit::WebPageProxy::tryClose):
(WebKit::WebPageProxy::tryCloseTimedOut):
(WebKit::WebPageProxy::closePage):
(WebKit::m_resetRecentCrashCountTimer): Deleted.
* UIProcess/WebPageProxy.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@253224 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index dcfee81..5df1f83 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,24 @@
+2019-12-06  Chris Dumez  <cdumez@apple.com>
+
+        Reduce timeout for page to handle beforeunload events when trying to close a page
+        https://bugs.webkit.org/show_bug.cgi?id=204950
+        <rdar://problem/57700419>
+
+        Reviewed by Ryosuke Niwa.
+
+        Reduce timeout for page to handle beforeunload events when trying to close a page. It would previously
+        take up to 3 seconds to actually close a tab after the user would click on the "X" to close it. This
+        is because we would wait for the page to fire and handle the beforeunload events and only give up after
+        3 seconds. This patch reduces this timeout to something more reasonable from a user standpoint (500ms).
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::m_tryCloseTimeoutTimer):
+        (WebKit::WebPageProxy::tryClose):
+        (WebKit::WebPageProxy::tryCloseTimedOut):
+        (WebKit::WebPageProxy::closePage):
+        (WebKit::m_resetRecentCrashCountTimer): Deleted.
+        * UIProcess/WebPageProxy.h:
+
 2019-12-06  Jonathan Bedard  <jbedard@apple.com>
 
         Python 3: Add support in webkitpy.test
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
index e290149..d841d3d 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
@@ -271,6 +271,7 @@
 static const Seconds resetRecentCrashCountDelay = 30_s;
 static unsigned maximumWebProcessRelaunchAttempts = 1;
 static const Seconds audibleActivityClearDelay = 10_s;
+static const Seconds tryCloseTimeoutDelay = 500_ms;
 
 namespace WebKit {
 using namespace WebCore;
@@ -449,6 +450,7 @@
     , m_inspectorDebuggable(makeUnique<WebPageDebuggable>(*this))
 #endif
     , m_resetRecentCrashCountTimer(RunLoop::main(), this, &WebPageProxy::resetRecentCrashCount)
+    , m_tryCloseTimeoutTimer(RunLoop::main(), this, &WebPageProxy::tryCloseTimedOut)
 {
     RELEASE_LOG_IF_ALLOWED(Loading, "constructor:");
 
@@ -1074,25 +1076,31 @@
     if (!hasRunningProcess())
         return true;
 
-    RELEASE_LOG_IF_ALLOWED(Loading, "tryClose:");
+    RELEASE_LOG_IF_ALLOWED(Process, "tryClose:");
 
     // Close without delay if the process allows it. Our goal is to terminate
     // the process, so we check a per-process status bit.
     if (m_process->isSuddenTerminationEnabled())
         return true;
 
-    m_process->responsivenessTimer().start();
+    m_tryCloseTimeoutTimer.startOneShot(tryCloseTimeoutDelay);
     sendWithAsyncReply(Messages::WebPage::TryClose(), [this, weakThis = makeWeakPtr(*this)](bool shouldClose) {
         if (!weakThis)
             return;
 
-        m_process->responsivenessTimer().stop();
+        m_tryCloseTimeoutTimer.stop();
         if (shouldClose)
             closePage();
     });
     return false;
 }
 
+void WebPageProxy::tryCloseTimedOut()
+{
+    RELEASE_LOG_ERROR_IF_ALLOWED(Process, "tryCloseTimedOut: Timed out waiting for the process to respond to the WebPage::TryClose IPC, closing the page now");
+    closePage();
+}
+
 void WebPageProxy::maybeInitializeSandboxExtensionHandle(WebProcessProxy& process, const URL& url, const URL& resourceDirectoryURL, SandboxExtension::Handle& sandboxExtensionHandle, bool checkAssumedReadAccessToResourceURL)
 {
     if (!url.isLocalFile())
@@ -5321,6 +5329,10 @@
 
 void WebPageProxy::closePage()
 {
+    if (isClosed())
+        return;
+
+    RELEASE_LOG_IF_ALLOWED(Process, "closePage:");
     pageClient().clearAllEditCommands();
     m_uiClient->close(this);
 }
diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h
index 0fb531f..ed83bbf 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.h
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
@@ -2177,6 +2177,7 @@
     void clearAudibleActivity();
 #endif
 
+    void tryCloseTimedOut();
     void makeStorageSpaceRequest(WebCore::FrameIdentifier, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&&);
 
     const Identifier m_identifier;
@@ -2594,6 +2595,8 @@
     bool m_needsFontAttributes { false };
     bool m_mayHaveUniversalFileReadSandboxExtension { false };
 
+    RunLoop::Timer<WebPageProxy> m_tryCloseTimeoutTimer;
+
     std::unique_ptr<ProvisionalPageProxy> m_provisionalPage;
     std::unique_ptr<SuspendedPageProxy> m_suspendedPageKeptToPreventFlashing;
     WeakPtr<SuspendedPageProxy> m_lastSuspendedPage;