<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[168312] trunk/Source/WebKit2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/168312">168312</a></dd>
<dt>Author</dt> <dd>barraclough@apple.com</dd>
<dt>Date</dt> <dd>2014-05-05 13:14:11 -0700 (Mon, 05 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>https://bugs.webkit.org/show_bug.cgi?id=132522
Clean up ProcessThrottler

Reviewed by Geoffrey Garen.

The initial implementation of ProcessThrottler relied on the reply from the
SetViewState message to ensure the page visibility notifications have a chance
to be delivered. This resulted in:
    - unnecessarily complicated interface to ProcessThrottler (in VisibilityState class)
    - complexity bleeding out into WebPageProxy (handling 'hiding' state).
    - for cases other than view hiding, no suspension notification in the WebContent.

To fix these issues add an explicit handshake from the ProcessThrottler to the WebPage.
This gives us two things:
    - All previously posted messages (e.g. SetViewState) will be processed before suspension.
    - WebContent is always (bar timeout) notified before suspension.

Since this interlock ensures the SetViewState message will be processed, the WKContentView no
longer needs to request a reply from SetViewState, and WebPageProxy can lose all the 'hiding'
state tracking. In turn, we can simplify VisibilityToken to a couple of simpler types, without
the interface to change state - just acquire/release to keep the process runnable or permit
suspension.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _snapshotRect:intoImageOfWidth:completionHandler:]):
    - VisibilityToken -&gt; BackgroundActivityToken
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::WebPageProxy):
    - m_visibilityToken -&gt; m_activityToken, remove m_pendingViewStateUpdates
      updateVisibilityToken -&gt; updateActivityToken
(WebKit::WebPageProxy::reattachToWebProcess):
    - updateVisibilityToken -&gt; updateActivityToken
(WebKit::WebPageProxy::viewStateDidChange):
    - remove m_pendingViewStateUpdates, updateActivityToken after sending SetViewState
(WebKit::WebPageProxy::updateActivityToken):
    - m_visibilityToken -&gt; m_activityToken, no need to handle 'hiding' state.
(WebKit::WebPageProxy::updateVisibilityToken): Deleted.
    - renamed to updateActivityToken
(WebKit::WebPageProxy::didUpdateViewState): Deleted.
    - implementation moved back into header.
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::didUpdateViewState):
    - implementation moved back into header.
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::WebProcessProxy):
    - ProcessThrottler constructor now passed WebProcessProxy.
* UIProcess/WebProcessProxy.h:
    - added ProcessWillSuspend/ProcessReadyToSuspend
* UIProcess/WebProcessProxy.messages.in:
    - added ProcessWillSuspend/ProcessReadyToSuspend
* UIProcess/ios/ProcessAssertion.h:
(WebKit::ProcessAssertion::state):
    - accessor
* UIProcess/ios/ProcessThrottler.h:
(WebKit::ProcessThrottler::VisibilityToken::visibility): Deleted.
(WebKit::ProcessThrottler::VisibilityToken::setVisibility): Deleted.
    - removed VisibilityToken class, replaced with ForegroundActivityToken/BackgroundActivityToken.
(WebKit::ProcessThrottler::ProcessThrottler): Deleted.
(WebKit::ProcessThrottler::visibilityToken): Deleted.
(WebKit::ProcessThrottler::didConnnectToProcess): Deleted.
(WebKit::ProcessThrottler::assertionState): Deleted.
(WebKit::ProcessThrottler::updateAssertion): Deleted.
    - moved implementations to .mm.
* UIProcess/ios/ProcessThrottler.mm:
(WebKit::ProcessThrottler::ForegroundActivityToken::ForegroundActivityToken):
(WebKit::ProcessThrottler::ForegroundActivityToken::~ForegroundActivityToken):
(WebKit::ProcessThrottler::BackgroundActivityToken::BackgroundActivityToken):
(WebKit::ProcessThrottler::BackgroundActivityToken::~BackgroundActivityToken):
    - new, simpler replacement for VisibilityToken. Instantiate to keep a processes running, release to suspend.
(WebKit::ProcessThrottler::ProcessThrottler):
    - constructor, now initializes WebProcessProxy pointer &amp; timer mechanism
(WebKit::ProcessThrottler::assertionState):
    - select the appropriate AssertionState give current ActivityTokens.
(WebKit::ProcessThrottler::updateAssertionNow):
    - update the current ProcessAssertion.
(WebKit::ProcessThrottler::updateAssertion):
    - update the current ProcessAssertion, delay running-&gt;suspended transitions to give the process a chance to clean up.
(WebKit::ProcessThrottler::didConnnectToProcess):
    - moved from header.
(WebKit::ProcessThrottler::suspendTimerFired):
    - timeout to prevent processes from running in the background for too long.
(WebKit::ProcessThrottler::processReadyToSuspend):
    - handshake from the WebContent process to acknowledge it is ready to suspend.
(WebKit::ProcessThrottler::VisibilityToken::VisibilityToken): Deleted.
(WebKit::ProcessThrottler::VisibilityToken::~VisibilityToken): Deleted.
(WebKit::ProcessThrottler::VisibilityToken::hideTimerFired): Deleted.
(WebKit::ProcessThrottler::VisibilityToken::setVisibilityInternal): Deleted.
    - removed VisibilityToken class, replaced with ForegroundActivityToken/BackgroundActivityToken.
* UIProcess/ios/WKContentView.mm:
(-[WKContentView didMoveToWindow]):
    - no longer necessary to request a response from SetViewState; this interlock is now managed by the ProcessThrottler.
* UIProcess/ios/WebProcessProxyIOS.mm:
(WebKit::WebProcessProxy::sendProcessWillSuspend):
(WebKit::WebProcessProxy::processReadyToSuspend):
    - added ProcessWillSuspend/ProcessReadyToSuspend
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::processWillSuspend):
    - notification from the WebContent process that we will be suspended; for now just send back an ack.
* WebProcess/WebProcess.h:
    - added ProcessWillSuspend/ProcessReadyToSuspend
* WebProcess/WebProcess.messages.in:
    - added ProcessWillSuspend/ProcessReadyToSuspend</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessProxycpp">trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessProxyh">trunk/Source/WebKit2/UIProcess/WebProcessProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessProxymessagesin">trunk/Source/WebKit2/UIProcess/WebProcessProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosProcessAssertionh">trunk/Source/WebKit2/UIProcess/ios/ProcessAssertion.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosProcessThrottlerh">trunk/Source/WebKit2/UIProcess/ios/ProcessThrottler.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosProcessThrottlermm">trunk/Source/WebKit2/UIProcess/ios/ProcessThrottler.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewmm">trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebProcessProxyIOSmm">trunk/Source/WebKit2/UIProcess/ios/WebProcessProxyIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcesscpp">trunk/Source/WebKit2/WebProcess/WebProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcessh">trunk/Source/WebKit2/WebProcess/WebProcess.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcessmessagesin">trunk/Source/WebKit2/WebProcess/WebProcess.messages.in</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/ChangeLog        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -1,3 +1,108 @@
</span><ins>+2014-05-02  Gavin Barraclough  &lt;baraclough@apple.com&gt;
+
+        https://bugs.webkit.org/show_bug.cgi?id=132522
+        Clean up ProcessThrottler
+
+        Reviewed by Geoffrey Garen.
+
+        The initial implementation of ProcessThrottler relied on the reply from the
+        SetViewState message to ensure the page visibility notifications have a chance
+        to be delivered. This resulted in:
+            - unnecessarily complicated interface to ProcessThrottler (in VisibilityState class)
+            - complexity bleeding out into WebPageProxy (handling 'hiding' state).
+            - for cases other than view hiding, no suspension notification in the WebContent.
+
+        To fix these issues add an explicit handshake from the ProcessThrottler to the WebPage.
+        This gives us two things:
+            - All previously posted messages (e.g. SetViewState) will be processed before suspension.
+            - WebContent is always (bar timeout) notified before suspension.
+
+        Since this interlock ensures the SetViewState message will be processed, the WKContentView no
+        longer needs to request a reply from SetViewState, and WebPageProxy can lose all the 'hiding'
+        state tracking. In turn, we can simplify VisibilityToken to a couple of simpler types, without
+        the interface to change state - just acquire/release to keep the process runnable or permit
+        suspension.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _snapshotRect:intoImageOfWidth:completionHandler:]):
+            - VisibilityToken -&gt; BackgroundActivityToken
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::WebPageProxy):
+            - m_visibilityToken -&gt; m_activityToken, remove m_pendingViewStateUpdates
+              updateVisibilityToken -&gt; updateActivityToken
+        (WebKit::WebPageProxy::reattachToWebProcess):
+            - updateVisibilityToken -&gt; updateActivityToken
+        (WebKit::WebPageProxy::viewStateDidChange):
+            - remove m_pendingViewStateUpdates, updateActivityToken after sending SetViewState
+        (WebKit::WebPageProxy::updateActivityToken):
+            - m_visibilityToken -&gt; m_activityToken, no need to handle 'hiding' state.
+        (WebKit::WebPageProxy::updateVisibilityToken): Deleted.
+            - renamed to updateActivityToken
+        (WebKit::WebPageProxy::didUpdateViewState): Deleted.
+            - implementation moved back into header.
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::didUpdateViewState):
+            - implementation moved back into header.
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::WebProcessProxy):
+            - ProcessThrottler constructor now passed WebProcessProxy.
+        * UIProcess/WebProcessProxy.h:
+            - added ProcessWillSuspend/ProcessReadyToSuspend
+        * UIProcess/WebProcessProxy.messages.in:
+            - added ProcessWillSuspend/ProcessReadyToSuspend
+        * UIProcess/ios/ProcessAssertion.h:
+        (WebKit::ProcessAssertion::state):
+            - accessor
+        * UIProcess/ios/ProcessThrottler.h:
+        (WebKit::ProcessThrottler::VisibilityToken::visibility): Deleted.
+        (WebKit::ProcessThrottler::VisibilityToken::setVisibility): Deleted.
+            - removed VisibilityToken class, replaced with ForegroundActivityToken/BackgroundActivityToken.
+        (WebKit::ProcessThrottler::ProcessThrottler): Deleted.
+        (WebKit::ProcessThrottler::visibilityToken): Deleted.
+        (WebKit::ProcessThrottler::didConnnectToProcess): Deleted.
+        (WebKit::ProcessThrottler::assertionState): Deleted.
+        (WebKit::ProcessThrottler::updateAssertion): Deleted.
+            - moved implementations to .mm.
+        * UIProcess/ios/ProcessThrottler.mm:
+        (WebKit::ProcessThrottler::ForegroundActivityToken::ForegroundActivityToken):
+        (WebKit::ProcessThrottler::ForegroundActivityToken::~ForegroundActivityToken):
+        (WebKit::ProcessThrottler::BackgroundActivityToken::BackgroundActivityToken):
+        (WebKit::ProcessThrottler::BackgroundActivityToken::~BackgroundActivityToken):
+            - new, simpler replacement for VisibilityToken. Instantiate to keep a processes running, release to suspend.
+        (WebKit::ProcessThrottler::ProcessThrottler):
+            - constructor, now initializes WebProcessProxy pointer &amp; timer mechanism
+        (WebKit::ProcessThrottler::assertionState):
+            - select the appropriate AssertionState give current ActivityTokens.
+        (WebKit::ProcessThrottler::updateAssertionNow):
+            - update the current ProcessAssertion.
+        (WebKit::ProcessThrottler::updateAssertion):
+            - update the current ProcessAssertion, delay running-&gt;suspended transitions to give the process a chance to clean up.
+        (WebKit::ProcessThrottler::didConnnectToProcess):
+            - moved from header.
+        (WebKit::ProcessThrottler::suspendTimerFired):
+            - timeout to prevent processes from running in the background for too long.
+        (WebKit::ProcessThrottler::processReadyToSuspend):
+            - handshake from the WebContent process to acknowledge it is ready to suspend.
+        (WebKit::ProcessThrottler::VisibilityToken::VisibilityToken): Deleted.
+        (WebKit::ProcessThrottler::VisibilityToken::~VisibilityToken): Deleted.
+        (WebKit::ProcessThrottler::VisibilityToken::hideTimerFired): Deleted.
+        (WebKit::ProcessThrottler::VisibilityToken::setVisibilityInternal): Deleted.
+            - removed VisibilityToken class, replaced with ForegroundActivityToken/BackgroundActivityToken.
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView didMoveToWindow]):
+            - no longer necessary to request a response from SetViewState; this interlock is now managed by the ProcessThrottler.
+        * UIProcess/ios/WebProcessProxyIOS.mm:
+        (WebKit::WebProcessProxy::sendProcessWillSuspend):
+        (WebKit::WebProcessProxy::processReadyToSuspend):
+            - added ProcessWillSuspend/ProcessReadyToSuspend
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::processWillSuspend):
+            - notification from the WebContent process that we will be suspended; for now just send back an ack.
+        * WebProcess/WebProcess.h:
+            - added ProcessWillSuspend/ProcessReadyToSuspend
+        * WebProcess/WebProcess.messages.in:
+            - added ProcessWillSuspend/ProcessReadyToSuspend
+
</ins><span class="cx"> 2014-05-05  Jeremy Jones  &lt;jeremyj@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Implement beginScrubbing and endScrubbing for video fullscreen.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -1541,14 +1541,14 @@
</span><span class="cx">     CGSize imageSize = CGSizeMake(imageWidth, imageHeight);
</span><span class="cx">     
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    WebKit::ProcessThrottler::VisibilityToken* visibilityToken = new WebKit::ProcessThrottler::VisibilityToken(_page-&gt;process().throttler(), WebKit::ProcessThrottler::Visibility::Hiding);
</del><ins>+    WebKit::ProcessThrottler::BackgroundActivityToken* activityToken = new WebKit::ProcessThrottler::BackgroundActivityToken(_page-&gt;process().throttler());
</ins><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx">     void(^copiedCompletionHandler)(CGImageRef) = [completionHandler copy];
</span><span class="cx">     _page-&gt;takeSnapshot(WebCore::enclosingIntRect(snapshotRectInContentCoordinates), WebCore::expandedIntSize(WebCore::FloatSize(imageSize)), WebKit::SnapshotOptionsExcludeDeviceScaleFactor, [=](bool, const WebKit::ShareableBitmap::Handle&amp; imageHandle) {
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">         // Automatically delete when this goes out of scope.
</span><del>-        auto uniqueVisibilityToken = std::unique_ptr&lt;WebKit::ProcessThrottler::VisibilityToken&gt;(visibilityToken);
</del><ins>+        auto uniqueActivityToken = std::unique_ptr&lt;WebKit::ProcessThrottler::BackgroundActivityToken&gt;(activityToken);
</ins><span class="cx"> #endif
</span><span class="cx">         
</span><span class="cx">         if (imageHandle.isNull()) {
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -270,7 +270,7 @@
</span><span class="cx">     , m_notificationPermissionRequestManager(*this)
</span><span class="cx">     , m_viewState(ViewState::NoFlags)
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    , m_visibilityToken(process.throttler().visibilityToken(ProcessThrottler::Visibility::Hidden))
</del><ins>+    , m_activityToken(nullptr)
</ins><span class="cx"> #endif
</span><span class="cx">     , m_backForwardList(WebBackForwardList::create(*this))
</span><span class="cx">     , m_loadStateAtProcessExit(FrameLoadState::State::Finished)
</span><span class="lines">@@ -355,7 +355,6 @@
</span><span class="cx">     , m_mediaVolume(1)
</span><span class="cx">     , m_mayStartMediaWhenInWindow(true)
</span><span class="cx">     , m_waitingForDidUpdateViewState(false)
</span><del>-    , m_pendingViewStateUpdates(0)
</del><span class="cx">     , m_scrollPinningBehavior(DoNotPin)
</span><span class="cx">     , m_navigationID(0)
</span><span class="cx"> {
</span><span class="lines">@@ -363,7 +362,7 @@
</span><span class="cx">         m_visitedLinkProvider-&gt;addProcess(m_process.get());
</span><span class="cx"> 
</span><span class="cx">     updateViewState();
</span><del>-    updateVisibilityToken();
</del><ins>+    updateActivityToken();
</ins><span class="cx">     
</span><span class="cx"> #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
</span><span class="cx">     m_layerHostingMode = m_viewState &amp; ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
</span><span class="lines">@@ -522,7 +521,7 @@
</span><span class="cx">     ASSERT(m_process-&gt;state() == WebProcessProxy::State::Terminated);
</span><span class="cx"> 
</span><span class="cx">     updateViewState();
</span><del>-    updateVisibilityToken();
</del><ins>+    updateActivityToken();
</ins><span class="cx">     
</span><span class="cx">     m_isValid = true;
</span><span class="cx"> 
</span><span class="lines">@@ -1062,16 +1061,12 @@
</span><span class="cx">     updateViewState(mayHaveChanged);
</span><span class="cx">     ViewState::Flags changed = m_viewState ^ previousViewState;
</span><span class="cx"> 
</span><del>-    if (changed) {
-        bool requestReply = wantsReply == WantsReplyOrNot::DoesWantReply;
-        if (requestReply)
-            ++m_pendingViewStateUpdates;
</del><ins>+    if (changed)
+        m_process-&gt;send(Messages::WebPage::SetViewState(m_viewState, wantsReply == WantsReplyOrNot::DoesWantReply), m_pageID);
</ins><span class="cx">     
</span><del>-        updateVisibilityToken();
-        
-        m_process-&gt;send(Messages::WebPage::SetViewState(m_viewState, requestReply), m_pageID);
-    }
-
</del><ins>+    // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
+    updateActivityToken();
+    
</ins><span class="cx">     if (changed &amp; ViewState::IsVisuallyIdle)
</span><span class="cx">         m_process-&gt;pageSuppressibilityChanged(this);
</span><span class="cx"> 
</span><span class="lines">@@ -1100,25 +1095,16 @@
</span><span class="cx">     updateBackingStoreDiscardableState();
</span><span class="cx"> }
</span><span class="cx">     
</span><del>-void WebPageProxy::updateVisibilityToken()
</del><ins>+void WebPageProxy::updateActivityToken()
</ins><span class="cx"> {
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    if (isViewVisible())
-        m_visibilityToken-&gt;setVisibility(ProcessThrottler::Visibility::Visible);
-    else if (m_visibilityToken-&gt;visibility() != ProcessThrottler::Visibility::Hidden &amp;&amp; m_pendingViewStateUpdates)
-        m_visibilityToken-&gt;setVisibility(ProcessThrottler::Visibility::Hiding);
-    else
-        m_visibilityToken-&gt;setVisibility(ProcessThrottler::Visibility::Hidden);
</del><ins>+    if (!isViewVisible())
+        m_activityToken = nullptr;
+    else if (!m_activityToken)
+        m_activityToken = std::make_unique&lt;ProcessThrottler::ForegroundActivityToken&gt;(m_process-&gt;throttler());
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::didUpdateViewState()
-{
-    m_waitingForDidUpdateViewState = false;
-    --m_pendingViewStateUpdates;
-    updateVisibilityToken();
-}
-    
</del><span class="cx"> void WebPageProxy::layerHostingModeDidChange()
</span><span class="cx"> {
</span><span class="cx">     if (!isValid())
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -764,7 +764,7 @@
</span><span class="cx"> 
</span><span class="cx">     void listenForLayoutMilestones(WebCore::LayoutMilestones);
</span><span class="cx"> 
</span><del>-    void didUpdateViewState();
</del><ins>+    void didUpdateViewState() { m_waitingForDidUpdateViewState = false; }
</ins><span class="cx"> 
</span><span class="cx">     bool hasHorizontalScrollbar() const { return m_mainFrameHasHorizontalScrollbar; }
</span><span class="cx">     bool hasVerticalScrollbar() const { return m_mainFrameHasVerticalScrollbar; }
</span><span class="lines">@@ -1084,7 +1084,7 @@
</span><span class="cx">     void platformInitialize();
</span><span class="cx"> 
</span><span class="cx">     void updateViewState(WebCore::ViewState::Flags flagsToUpdate = WebCore::ViewState::AllFlags);
</span><del>-    void updateVisibilityToken();
</del><ins>+    void updateActivityToken();
</ins><span class="cx">         
</span><span class="cx">     void resetState();
</span><span class="cx">     void resetStateAfterProcessExited();
</span><span class="lines">@@ -1514,7 +1514,7 @@
</span><span class="cx">     WebCore::ViewState::Flags m_viewState;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    std::unique_ptr&lt;ProcessThrottler::VisibilityToken&gt; m_visibilityToken;
</del><ins>+    std::unique_ptr&lt;ProcessThrottler::ForegroundActivityToken&gt; m_activityToken;
</ins><span class="cx"> #endif
</span><span class="cx">         
</span><span class="cx">     bool m_canGoBack;
</span><span class="lines">@@ -1676,7 +1676,6 @@
</span><span class="cx">     bool m_mayStartMediaWhenInWindow;
</span><span class="cx"> 
</span><span class="cx">     bool m_waitingForDidUpdateViewState;
</span><del>-    unsigned m_pendingViewStateUpdates;
</del><span class="cx">         
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     HashMap&lt;String, String&gt; m_temporaryPDFFiles;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     , m_numberOfTimesSuddenTerminationWasDisabled(0)
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    , m_throttler(std::make_unique&lt;ProcessThrottler&gt;())
</del><ins>+    , m_throttler(std::make_unique&lt;ProcessThrottler&gt;(this))
</ins><span class="cx"> #endif
</span><span class="cx"> {
</span><span class="cx">     connect();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessProxy.h (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessProxy.h        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/WebProcessProxy.h        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -136,6 +136,9 @@
</span><span class="cx">     void windowServerConnectionStateChanged();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><ins>+    void sendProcessWillSuspend();
+    void processReadyToSuspend();
+    
</ins><span class="cx">     ProcessThrottler&amp; throttler() { return *m_throttler; }
</span><span class="cx"> #endif
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessProxy.messages.in (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessProxy.messages.in        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/WebProcessProxy.messages.in        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -47,4 +47,7 @@
</span><span class="cx"> #if ENABLE(DATABASE_PROCESS)
</span><span class="cx">     GetDatabaseProcessConnection() -&gt; (IPC::Attachment connectionHandle) Delayed
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(IOS)
+    ProcessReadyToSuspend()
+#endif
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosProcessAssertionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/ProcessAssertion.h (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/ProcessAssertion.h        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/ios/ProcessAssertion.h        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -44,6 +44,8 @@
</span><span class="cx"> public:
</span><span class="cx">     ProcessAssertion(pid_t, AssertionState);
</span><span class="cx">     
</span><ins>+    AssertionState state() const { return m_assertionState; }
+    
</ins><span class="cx">     void setState(AssertionState);
</span><span class="cx">     
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosProcessThrottlerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/ProcessThrottler.h (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/ProcessThrottler.h        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/ios/ProcessThrottler.h        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -35,84 +35,50 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx">     
</span><ins>+class WebProcessProxy;
+    
</ins><span class="cx"> class ProcessThrottler {
</span><span class="cx"> public:
</span><del>-    enum class Visibility {
-        Visible,
-        Hiding,
-        Hidden
</del><ins>+    class ForegroundActivityToken {
+    public:
+        ForegroundActivityToken(ProcessThrottler&amp;);
+        ~ForegroundActivityToken();
+        
+    private:
+        WeakPtr&lt;ProcessThrottler&gt; m_throttler;
</ins><span class="cx">     };
</span><span class="cx">     
</span><del>-    class VisibilityToken {
</del><ins>+    class BackgroundActivityToken {
</ins><span class="cx">     public:
</span><del>-        VisibilityToken(ProcessThrottler&amp;, Visibility);
-        ~VisibilityToken();
</del><ins>+        BackgroundActivityToken(ProcessThrottler&amp;);
+        ~BackgroundActivityToken();
</ins><span class="cx">         
</span><del>-        Visibility visibility() const
-        {
-            return m_visibility;
-        }
-        
-        void setVisibility(Visibility visibility)
-        {
-            if (m_visibility != visibility)
-                setVisibilityInternal(visibility);
-            
-            if (visibility == Visibility::Hiding)
-                m_hideTimer.startOneShot(30);
-            else
-                m_hideTimer.stop();
-        }
-        
</del><span class="cx">     private:
</span><del>-        void hideTimerFired(WebCore::Timer&lt;VisibilityToken&gt;*);
-        void setVisibilityInternal(Visibility);
-        
</del><span class="cx">         WeakPtr&lt;ProcessThrottler&gt; m_throttler;
</span><del>-        Visibility m_visibility;
-        WebCore::Timer&lt;VisibilityToken&gt; m_hideTimer;
</del><span class="cx">     };
</span><span class="cx">     
</span><del>-    ProcessThrottler()
-        : m_weakPtrFactory(this)
-        , m_visibleCount(0)
-        , m_hidingCount(0)
-    {
-    }
</del><ins>+    ProcessThrottler(WebProcessProxy*);
</ins><span class="cx">     
</span><del>-    std::unique_ptr&lt;VisibilityToken&gt; visibilityToken(Visibility visibility)
-    {
-        return std::make_unique&lt;VisibilityToken&gt;(*this, visibility);
-    }
</del><ins>+    void didConnnectToProcess(pid_t);
+    void processReadyToSuspend();
</ins><span class="cx">     
</span><del>-    void didConnnectToProcess(pid_t pid)
-    {
-        m_assertion = std::make_unique&lt;ProcessAssertion&gt;(pid, assertionState());
-    }
-    
</del><span class="cx"> private:
</span><del>-    friend class VisibilityToken;
</del><ins>+    friend class ForegroundActivityToken;
+    friend class BackgroundActivityToken;
</ins><span class="cx">     WeakPtr&lt;ProcessThrottler&gt; weakPtr() { return m_weakPtrFactory.createWeakPtr(); }
</span><span class="cx">     
</span><del>-    AssertionState assertionState()
-    {
-        if (m_visibleCount)
-            return AssertionState::Foreground;
-        if (m_hidingCount)
-            return AssertionState::Background;
-        return AssertionState::Suspended;
-    }
</del><ins>+    AssertionState assertionState();
+    void updateAssertion();
+    void updateAssertionNow();
+    void suspendTimerFired(WebCore::Timer&lt;ProcessThrottler&gt;*);
</ins><span class="cx">     
</span><del>-    void updateAssertion()
-    {
-        if (m_assertion)
-            m_assertion-&gt;setState(assertionState());
-    }
-    
</del><ins>+    WebProcessProxy* m_process;
</ins><span class="cx">     WeakPtrFactory&lt;ProcessThrottler&gt; m_weakPtrFactory;
</span><span class="cx">     std::unique_ptr&lt;ProcessAssertion&gt; m_assertion;
</span><del>-    unsigned m_visibleCount;
-    unsigned m_hidingCount;
</del><ins>+    WebCore::Timer&lt;ProcessThrottler&gt; m_suspendTimer;
+    unsigned m_foregroundCount;
+    unsigned m_backgroundCount;
+    unsigned m_suspendMessageCount;
</ins><span class="cx"> };
</span><span class="cx">     
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosProcessThrottlermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/ProcessThrottler.mm (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/ProcessThrottler.mm        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/ios/ProcessThrottler.mm        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -28,50 +28,101 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> 
</span><ins>+#import &quot;WebProcessProxy.h&quot;
+
</ins><span class="cx"> namespace WebKit {
</span><del>-
-ProcessThrottler::VisibilityToken::VisibilityToken(ProcessThrottler&amp; throttler, Visibility visibility)
</del><ins>+    
+static const unsigned processSuspensionTimeout = 30;
+    
+ProcessThrottler::ForegroundActivityToken::ForegroundActivityToken(ProcessThrottler&amp; throttler)
</ins><span class="cx">     : m_throttler(throttler.weakPtr())
</span><del>-    , m_visibility(Visibility::Hidden)
-    , m_hideTimer(this, &amp;VisibilityToken::hideTimerFired)
</del><span class="cx"> {
</span><del>-    setVisibility(visibility);
</del><ins>+    throttler.m_foregroundCount++;
+    throttler.updateAssertion();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ProcessThrottler::VisibilityToken::~VisibilityToken()
</del><ins>+ProcessThrottler::ForegroundActivityToken::~ForegroundActivityToken()
</ins><span class="cx"> {
</span><del>-    setVisibility(Visibility::Hidden);
</del><ins>+    if (ProcessThrottler* throttler = m_throttler.get()) {
+        throttler-&gt;m_foregroundCount--;
+        throttler-&gt;updateAssertion();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ProcessThrottler::VisibilityToken::hideTimerFired(WebCore::Timer&lt;VisibilityToken&gt;*)
</del><ins>+ProcessThrottler::BackgroundActivityToken::BackgroundActivityToken(ProcessThrottler&amp; throttler)
+    : m_throttler(throttler.weakPtr())
</ins><span class="cx"> {
</span><del>-    ASSERT(m_visibility == Visibility::Hiding);
-    m_visibility = Visibility::Hidden;
</del><ins>+    throttler.m_backgroundCount++;
+    throttler.updateAssertion();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ProcessThrottler::VisibilityToken::setVisibilityInternal(Visibility visibility)
</del><ins>+ProcessThrottler::BackgroundActivityToken::~BackgroundActivityToken()
</ins><span class="cx"> {
</span><del>-    ProcessThrottler* throttler = m_throttler.get();
-    if (!throttler) {
-        m_visibility = visibility;
-        return;
</del><ins>+    if (ProcessThrottler* throttler = m_throttler.get()) {
+        throttler-&gt;m_backgroundCount--;
+        throttler-&gt;updateAssertion();
</ins><span class="cx">     }
</span><ins>+}
+
+ProcessThrottler::ProcessThrottler(WebProcessProxy* process)
+    : m_process(process)
+    , m_weakPtrFactory(this)
+    , m_suspendTimer(this, &amp;ProcessThrottler::suspendTimerFired)
+    , m_foregroundCount(0)
+    , m_backgroundCount(0)
+    , m_suspendMessageCount(0)
+{
+}
</ins><span class="cx">     
</span><del>-    if (m_visibility == Visibility::Visible)
-        throttler-&gt;m_visibleCount--;
-    else if (m_visibility == Visibility::Hiding)
-        throttler-&gt;m_hidingCount--;
</del><ins>+AssertionState ProcessThrottler::assertionState()
+{
+    ASSERT(!m_suspendTimer.isActive());
</ins><span class="cx">     
</span><del>-    m_visibility = visibility;
</del><ins>+    if (m_foregroundCount)
+        return AssertionState::Foreground;
+    if (m_backgroundCount)
+        return AssertionState::Background;
+    return AssertionState::Suspended;
+}
</ins><span class="cx">     
</span><del>-    if (m_visibility == Visibility::Visible)
-        throttler-&gt;m_visibleCount++;
-    else if (m_visibility == Visibility::Hiding)
-        throttler-&gt;m_hidingCount++;
</del><ins>+void ProcessThrottler::updateAssertionNow()
+{
+    m_suspendTimer.stop();
+    if (m_assertion)
+        m_assertion-&gt;setState(assertionState());
+}
</ins><span class="cx">     
</span><del>-    throttler-&gt;updateAssertion();
</del><ins>+void ProcessThrottler::updateAssertion()
+{
+    // If the process is currently runnable but will be suspended then first give it a chance to complete what it was doing
+    // and clean up - move it to the background and send it a message to notify. Schedule a timeout so it can't stay running
+    // in the background for too long.
+    if (m_assertion &amp;&amp; m_assertion-&gt;state() != AssertionState::Suspended &amp;&amp; !m_foregroundCount &amp;&amp; !m_backgroundCount) {
+        ++m_suspendMessageCount;
+        m_process-&gt;sendProcessWillSuspend();
+        m_suspendTimer.startOneShot(processSuspensionTimeout);
+        m_assertion-&gt;setState(AssertionState::Background);
+    } else
+        updateAssertionNow();
</ins><span class="cx"> }
</span><ins>+
+void ProcessThrottler::didConnnectToProcess(pid_t pid)
+{
+    m_suspendTimer.stop();
+    m_assertion = std::make_unique&lt;ProcessAssertion&gt;(pid, assertionState());
+}
</ins><span class="cx">     
</span><ins>+void ProcessThrottler::suspendTimerFired(WebCore::Timer&lt;ProcessThrottler&gt;*)
+{
+    updateAssertionNow();
</ins><span class="cx"> }
</span><ins>+    
+void ProcessThrottler::processReadyToSuspend()
+{
+    if (!--m_suspendMessageCount)
+        updateAssertionNow();
+}
</ins><span class="cx"> 
</span><ins>+}
+
</ins><span class="cx"> #endif // PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -251,7 +251,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (self.window)
</span><span class="cx">         [self _updateForScreen:self.window.screen];
</span><del>-    _page-&gt;viewStateDidChange(ViewState::AllFlags, self.window ? WebPageProxy::WantsReplyOrNot::DoesNotWantReply : WebPageProxy::WantsReplyOrNot::DoesWantReply);
</del><ins>+    _page-&gt;viewStateDidChange(ViewState::AllFlags);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (WKBrowsingContextController *)browsingContextController
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebProcessProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebProcessProxyIOS.mm (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebProcessProxyIOS.mm        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/UIProcess/ios/WebProcessProxyIOS.mm        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -30,6 +30,8 @@
</span><span class="cx"> 
</span><span class="cx"> #import &lt;WebCore/NotImplemented.h&gt;
</span><span class="cx"> 
</span><ins>+#import &quot;WebProcessMessages.h&quot;
+
</ins><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><span class="cx"> bool WebProcessProxy::fullKeyboardAccessEnabled()
</span><span class="lines">@@ -70,6 +72,17 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx">     
</span><ins>+void WebProcessProxy::sendProcessWillSuspend()
+{
+    if (canSendMessage())
+        send(Messages::WebProcess::ProcessWillSuspend(), 0);
+}
+    
+void WebProcessProxy::processReadyToSuspend()
+{
+    m_throttler-&gt;processReadyToSuspend();
+}
+    
</ins><span class="cx"> } // namespace WebKit
</span><span class="cx"> 
</span><span class="cx"> #endif // PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -1153,6 +1153,12 @@
</span><span class="cx">             mainFrame-&gt;resetAllGeolocationPermission();
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+    
+void WebProcess::processWillSuspend()
+{
+    parentProcessConnection()-&gt;send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0);
+}
+    
</ins><span class="cx"> #endif // PLATFORM(IOS)
</span><span class="cx"> 
</span><span class="cx"> void WebProcess::pageDidEnterWindow(uint64_t pageID)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.h (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.h        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.h        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -176,6 +176,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     void resetAllGeolocationPermissions();
</span><ins>+    void processWillSuspend();
</ins><span class="cx"> #endif // PLATFORM(IOS)
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;API::Object&gt; apiObjectByConvertingFromHandles(API::Object*);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcessmessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.messages.in (168311 => 168312)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.messages.in        2014-05-05 20:02:56 UTC (rev 168311)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.messages.in        2014-05-05 20:14:11 UTC (rev 168312)
</span><span class="lines">@@ -92,4 +92,8 @@
</span><span class="cx"> #if ENABLE(SERVICE_CONTROLS)
</span><span class="cx">     SetEnabledServices(bool hasImageServices, bool hasSelectionServices)
</span><span class="cx"> #endif
</span><ins>+
+#if PLATFORM(IOS)
+    ProcessWillSuspend()
+#endif
</ins><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>