Title: [202696] trunk/Source/WebKit2
Revision
202696
Author
cdu...@apple.com
Date
2016-06-30 13:17:30 -0700 (Thu, 30 Jun 2016)

Log Message

[iOS] Process suspension is prevented for 30 seconds after closing a tab
https://bugs.webkit.org/show_bug.cgi?id=159280
<rdar://problem/27014867>

Reviewed by Gavin Barraclough.

When closing a tab, ConnectionTerminationWatchdog takes a background
assertion on behalf of the WebContent process and only releases it
after 30 seconds, allowing for the WebContent process to exit cleanly
without worrying about getting suspended too early.

However, the child process normally exits much sooner than this and
we end up holding a process assertion for no reason for a full 30
seconds anyway. This patch addresses the issue by registering an
invalidation handler with the BKSProcessAssertion and releasing our
our assertion in such case. The invalidation handler gets called
as soon as the child process exits.

* Platform/spi/ios/AssertionServicesSPI.h:
* UIProcess/ProcessAssertion.cpp:
(WebKit::ProcessAssertion::ProcessAssertion):
* UIProcess/ProcessAssertion.h:
(WebKit::ProcessAssertion::ProcessAssertion):
(WebKit::ProcessAssertion::validity):
* UIProcess/ios/ProcessAssertionIOS.mm:
(WebKit::ProcessAssertion::ProcessAssertion):
(WebKit::ProcessAssertion::~ProcessAssertion):
(WebKit::ProcessAndUIAssertion::updateRunInBackgroundCount):
(WebKit::ProcessAndUIAssertion::ProcessAndUIAssertion):
(WebKit::ProcessAssertion::setState): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (202695 => 202696)


--- trunk/Source/WebKit2/ChangeLog	2016-06-30 19:15:15 UTC (rev 202695)
+++ trunk/Source/WebKit2/ChangeLog	2016-06-30 20:17:30 UTC (rev 202696)
@@ -1,3 +1,36 @@
+2016-06-30  Chris Dumez  <cdu...@apple.com>
+
+        [iOS] Process suspension is prevented for 30 seconds after closing a tab
+        https://bugs.webkit.org/show_bug.cgi?id=159280
+        <rdar://problem/27014867>
+
+        Reviewed by Gavin Barraclough.
+
+        When closing a tab, ConnectionTerminationWatchdog takes a background
+        assertion on behalf of the WebContent process and only releases it
+        after 30 seconds, allowing for the WebContent process to exit cleanly
+        without worrying about getting suspended too early.
+
+        However, the child process normally exits much sooner than this and
+        we end up holding a process assertion for no reason for a full 30
+        seconds anyway. This patch addresses the issue by registering an
+        invalidation handler with the BKSProcessAssertion and releasing our
+        our assertion in such case. The invalidation handler gets called
+        as soon as the child process exits.
+
+        * Platform/spi/ios/AssertionServicesSPI.h:
+        * UIProcess/ProcessAssertion.cpp:
+        (WebKit::ProcessAssertion::ProcessAssertion):
+        * UIProcess/ProcessAssertion.h:
+        (WebKit::ProcessAssertion::ProcessAssertion):
+        (WebKit::ProcessAssertion::validity):
+        * UIProcess/ios/ProcessAssertionIOS.mm:
+        (WebKit::ProcessAssertion::ProcessAssertion):
+        (WebKit::ProcessAssertion::~ProcessAssertion):
+        (WebKit::ProcessAndUIAssertion::updateRunInBackgroundCount):
+        (WebKit::ProcessAndUIAssertion::ProcessAndUIAssertion):
+        (WebKit::ProcessAssertion::setState): Deleted.
+
 2016-06-30  Tim Horton  <timothy_hor...@apple.com>
 
         Keep track of when a WKWebView is blank before the initial non-empty layout

Modified: trunk/Source/WebKit2/Platform/spi/ios/AssertionServicesSPI.h (202695 => 202696)


--- trunk/Source/WebKit2/Platform/spi/ios/AssertionServicesSPI.h	2016-06-30 19:15:15 UTC (rev 202695)
+++ trunk/Source/WebKit2/Platform/spi/ios/AssertionServicesSPI.h	2016-06-30 20:17:30 UTC (rev 202696)
@@ -72,6 +72,7 @@
 };
 typedef uint32_t BKSProcessAssertionReason;
 
+typedef void (^BKSProcessAssertionInvalidationHandler)(void);
 typedef void (^BKSProcessAssertionAcquisitionHandler)(BOOL acquired);
 
 @interface BKSProcessAssertion : NSObject
@@ -80,6 +81,8 @@
 @interface BKSProcessAssertion ()
 @property (nonatomic, assign) BKSProcessAssertionFlags flags;
 - (id)initWithPID:(pid_t)pid flags:(BKSProcessAssertionFlags)flags reason:(BKSProcessAssertionReason)reason name:(NSString *)name withHandler:(BKSProcessAssertionAcquisitionHandler)handler;
+
+@property (nonatomic, copy) BKSProcessAssertionInvalidationHandler invalidationHandler;
 - (void)invalidate;
 @end
 

Modified: trunk/Source/WebKit2/UIProcess/ProcessAssertion.cpp (202695 => 202696)


--- trunk/Source/WebKit2/UIProcess/ProcessAssertion.cpp	2016-06-30 19:15:15 UTC (rev 202695)
+++ trunk/Source/WebKit2/UIProcess/ProcessAssertion.cpp	2016-06-30 20:17:30 UTC (rev 202696)
@@ -30,7 +30,7 @@
 
 namespace WebKit {
 
-ProcessAssertion::ProcessAssertion(pid_t, AssertionState assertionState)
+ProcessAssertion::ProcessAssertion(pid_t, AssertionState assertionState, std::function<void()>)
     : m_assertionState(assertionState)
 {
 }

Modified: trunk/Source/WebKit2/UIProcess/ProcessAssertion.h (202695 => 202696)


--- trunk/Source/WebKit2/UIProcess/ProcessAssertion.h	2016-06-30 19:15:15 UTC (rev 202695)
+++ trunk/Source/WebKit2/UIProcess/ProcessAssertion.h	2016-06-30 20:17:30 UTC (rev 202696)
@@ -26,6 +26,8 @@
 #ifndef ProcessAssertion_h
 #define ProcessAssertion_h
 
+#include <functional>
+
 #if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR)
 #include <wtf/RetainPtr.h>
 OBJC_CLASS BKSProcessAssertion;
@@ -47,7 +49,7 @@
 
 class ProcessAssertion {
 public:
-    ProcessAssertion(pid_t, AssertionState);
+    ProcessAssertion(pid_t, AssertionState, std::function<void()> invalidationCallback = { });
     ~ProcessAssertion();
 
     void setClient(ProcessAssertionClient& client) { m_client = &client; }
@@ -56,9 +58,16 @@
     AssertionState state() const { return m_assertionState; }
     void setState(AssertionState);
 
+#if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR)
+protected:
+    enum class Validity { No, Yes, Unset };
+    Validity validity() const { return m_validity; }
+#endif
+
 private:
 #if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR)
     RetainPtr<BKSProcessAssertion> m_assertion;
+    Validity m_validity { Validity::Unset };
 #endif
     AssertionState m_assertionState;
     ProcessAssertionClient* m_client { nullptr };

Modified: trunk/Source/WebKit2/UIProcess/ios/ProcessAssertionIOS.mm (202695 => 202696)


--- trunk/Source/WebKit2/UIProcess/ios/ProcessAssertionIOS.mm	2016-06-30 19:15:15 UTC (rev 202695)
+++ trunk/Source/WebKit2/UIProcess/ios/ProcessAssertionIOS.mm	2016-06-30 20:17:30 UTC (rev 202696)
@@ -143,21 +143,28 @@
     }
 }
 
-ProcessAssertion::ProcessAssertion(pid_t pid, AssertionState assertionState)
+ProcessAssertion::ProcessAssertion(pid_t pid, AssertionState assertionState, std::function<void()> invalidationCallback)
+    : m_assertionState(assertionState)
 {
-    m_assertionState = assertionState;
-    
     BKSProcessAssertionAcquisitionHandler handler = ^(BOOL acquired) {
         if (!acquired) {
-            LOG_ERROR("Unable to acquire assertion for process %d", pid);
+            LOG_ALWAYS_ERROR(true, "Unable to acquire assertion for process %d", pid);
             ASSERT_NOT_REACHED();
+            m_validity = Validity::No;
+            invalidationCallback();
         }
     };
     m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForState(assertionState) reason:BKSProcessAssertionReasonExtension name:@"Web content visible" withHandler:handler]);
+    m_assertion.get().invalidationHandler = ^() {
+        m_validity = Validity::No;
+        invalidationCallback();
+    };
 }
 
 ProcessAssertion::~ProcessAssertion()
 {
+    m_assertion.get().invalidationHandler = nil;
+
     if (ProcessAssertionClient* client = this->client())
         [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*client];
     [m_assertion invalidate];
@@ -174,7 +181,7 @@
 
 void ProcessAndUIAssertion::updateRunInBackgroundCount()
 {
-    bool shouldHoldBackgroundAssertion = state() != AssertionState::Suspended;
+    bool shouldHoldBackgroundAssertion = validity() != Validity::No && state() != AssertionState::Suspended;
 
     if (shouldHoldBackgroundAssertion) {
         if (!m_isHoldingBackgroundAssertion)
@@ -188,7 +195,7 @@
 }
 
 ProcessAndUIAssertion::ProcessAndUIAssertion(pid_t pid, AssertionState assertionState)
-    : ProcessAssertion(pid, assertionState)
+    : ProcessAssertion(pid, assertionState, [this] { updateRunInBackgroundCount(); })
 {
     updateRunInBackgroundCount();
 }
@@ -219,7 +226,7 @@
 
 namespace WebKit {
 
-ProcessAssertion::ProcessAssertion(pid_t, AssertionState assertionState)
+ProcessAssertion::ProcessAssertion(pid_t, AssertionState assertionState, std::function<void()>)
     : m_assertionState(assertionState)
 {
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to