<!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>[177291] 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/177291">177291</a></dd>
<dt>Author</dt> <dd>barraclough@apple.com</dd>
<dt>Date</dt> <dd>2014-12-15 11:05:11 -0800 (Mon, 15 Dec 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Simplify tracking of process suppression disabled for PluginProcessManager
https://bugs.webkit.org/show_bug.cgi?id=139611

Reviewed by Darin Adler.

Previously if process suppression state changed for any context we would
iterate over all contexts to recompute.

There was also an inconsistency in the code. When plugin processes are
created they called processSuppressionIsEnabledForAllContexts(), which
checked WebContext::processSuppressionEnabled(), which in turn checks
two things - whether any page is currently visible, and whether the
suppression is currently disabled for any page. However when updating
process supression state we would call
processSuppressionPreferenceIsEnabledForAllContexts(), which would just
check the value of the key from the context's default PageGroup.

We shouldn't be taking visibility into account (this is handled from the
content, where we know which pages have instances of which plugins), but
we should be checking the current pref value of each page.

We already track in each context whether any page has teh pref set to
disable throttling; add a counter to the shared PluginProcessManager to
coallesce across all contexts.

* UIProcess/Plugins/PluginProcessManager.cpp:
(WebKit::PluginProcessManager::PluginProcessManager):
    - added m_processSuppressionDisabledForPageCounter, m_processSuppressionEnabled.
* UIProcess/Plugins/PluginProcessManager.h:
(WebKit::PluginProcessManager::processSuppressionDisabledForPageCount):
    - accessor for WebContext to increment count.
(WebKit::PluginProcessManager::processSuppressionEnabled):
    - accessor for PluginProcessProxy.
* UIProcess/Plugins/PluginProcessProxy.cpp:
(WebKit::PluginProcessProxy::didFinishLaunching):
    - get initial supression state from the PluginProcessManager, not WebContext.
* UIProcess/Plugins/mac/PluginProcessManagerMac.mm:
(WebKit::PluginProcessManager::updateProcessSuppressionState):
(WebKit::PluginProcessManager::setProcessSuppressionEnabled): Deleted.
    - setProcessSuppressionEnabled -&gt; updateProcessSuppressionState
      rather than WebContext setting suppression state, PluginProcessManager detects
      when this may need to change &amp; determines a new value for itself.
* UIProcess/WebContext.h:
    - removed processSuppressionIsEnabledForAllContexts, processSuppressionPreferenceIsEnabledForAllContexts
      updateProcessSuppressionState is no longer const (updates m_pluginProcessManagerProcessSuppressionDisabledCount).
* UIProcess/mac/WebContextMac.mm:
(WebKit::WebContext::updateProcessSuppressionState):
    - instead of explicitly recomputing plugin throttling state from Within the WebContext, just update
      m_pluginProcessManagerProcessSuppressionDisabledCount to count a RefCounter on the shared PluginProcessManager.
(WebKit::WebContext::processSuppressionIsEnabledForAllContexts): Deleted.
(WebKit::WebContext::processSuppressionPreferenceIsEnabledForAllContexts): Deleted.
    - removed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPluginsPluginProcessManagercpp">trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPluginsPluginProcessManagerh">trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPluginsPluginProcessProxycpp">trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPluginsmacPluginProcessManagerMacmm">trunk/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessManagerMac.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebContexth">trunk/Source/WebKit2/UIProcess/WebContext.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacWebContextMacmm">trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (177290 => 177291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-12-15 18:58:32 UTC (rev 177290)
+++ trunk/Source/WebKit2/ChangeLog        2014-12-15 19:05:11 UTC (rev 177291)
</span><span class="lines">@@ -1,3 +1,58 @@
</span><ins>+2014-12-15  Gavin Barraclough  &lt;barraclough@apple.com&gt;
+
+        Simplify tracking of process suppression disabled for PluginProcessManager
+        https://bugs.webkit.org/show_bug.cgi?id=139611
+
+        Reviewed by Darin Adler.
+
+        Previously if process suppression state changed for any context we would
+        iterate over all contexts to recompute.
+
+        There was also an inconsistency in the code. When plugin processes are
+        created they called processSuppressionIsEnabledForAllContexts(), which
+        checked WebContext::processSuppressionEnabled(), which in turn checks
+        two things - whether any page is currently visible, and whether the
+        suppression is currently disabled for any page. However when updating
+        process supression state we would call
+        processSuppressionPreferenceIsEnabledForAllContexts(), which would just
+        check the value of the key from the context's default PageGroup.
+
+        We shouldn't be taking visibility into account (this is handled from the
+        content, where we know which pages have instances of which plugins), but
+        we should be checking the current pref value of each page.
+
+        We already track in each context whether any page has teh pref set to
+        disable throttling; add a counter to the shared PluginProcessManager to
+        coallesce across all contexts.
+
+        * UIProcess/Plugins/PluginProcessManager.cpp:
+        (WebKit::PluginProcessManager::PluginProcessManager):
+            - added m_processSuppressionDisabledForPageCounter, m_processSuppressionEnabled.
+        * UIProcess/Plugins/PluginProcessManager.h:
+        (WebKit::PluginProcessManager::processSuppressionDisabledForPageCount):
+            - accessor for WebContext to increment count.
+        (WebKit::PluginProcessManager::processSuppressionEnabled):
+            - accessor for PluginProcessProxy.
+        * UIProcess/Plugins/PluginProcessProxy.cpp:
+        (WebKit::PluginProcessProxy::didFinishLaunching):
+            - get initial supression state from the PluginProcessManager, not WebContext.
+        * UIProcess/Plugins/mac/PluginProcessManagerMac.mm:
+        (WebKit::PluginProcessManager::updateProcessSuppressionState):
+        (WebKit::PluginProcessManager::setProcessSuppressionEnabled): Deleted.
+            - setProcessSuppressionEnabled -&gt; updateProcessSuppressionState
+              rather than WebContext setting suppression state, PluginProcessManager detects
+              when this may need to change &amp; determines a new value for itself.
+        * UIProcess/WebContext.h:
+            - removed processSuppressionIsEnabledForAllContexts, processSuppressionPreferenceIsEnabledForAllContexts
+              updateProcessSuppressionState is no longer const (updates m_pluginProcessManagerProcessSuppressionDisabledCount).
+        * UIProcess/mac/WebContextMac.mm:
+        (WebKit::WebContext::updateProcessSuppressionState):
+            - instead of explicitly recomputing plugin throttling state from Within the WebContext, just update
+              m_pluginProcessManagerProcessSuppressionDisabledCount to count a RefCounter on the shared PluginProcessManager.
+        (WebKit::WebContext::processSuppressionIsEnabledForAllContexts): Deleted.
+        (WebKit::WebContext::processSuppressionPreferenceIsEnabledForAllContexts): Deleted.
+            - removed.
+
</ins><span class="cx"> 2014-12-15  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Use API::LoaderClient instead of WKPageLoaderClient
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPluginsPluginProcessManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp (177290 => 177291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp        2014-12-15 18:58:32 UTC (rev 177290)
+++ trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp        2014-12-15 19:05:11 UTC (rev 177291)
</span><span class="lines">@@ -43,6 +43,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PluginProcessManager::PluginProcessManager()
</span><ins>+#if PLATFORM(COCOA)
+    : m_processSuppressionDisabledForPageCounter([this]() { updateProcessSuppressionState(); })
+#endif
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPluginsPluginProcessManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h (177290 => 177291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h        2014-12-15 18:58:32 UTC (rev 177290)
+++ trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h        2014-12-15 19:05:11 UTC (rev 177291)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><ins>+#include &lt;wtf/RefCounter.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace IPC {
</span><span class="lines">@@ -64,7 +65,9 @@
</span><span class="cx">     void clearSiteData(const PluginModuleInfo&amp;, WebPluginSiteDataManager*, const Vector&lt;String&gt;&amp; sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID);
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    void setProcessSuppressionEnabled(bool);
</del><ins>+    inline PassRefPtr&lt;RefCounter::Count&gt; processSuppressionDisabledForPageCount();
+    inline bool processSuppressionEnabled() const;
+    void updateProcessSuppressionState();
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -76,8 +79,23 @@
</span><span class="cx">     HashSet&lt;uint64_t&gt; m_knownTokens;
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;RefPtr&lt;PluginProcessProxy&gt;&gt; m_pluginProcesses;
</span><ins>+
+#if PLATFORM(COCOA)
+    RefCounter m_processSuppressionDisabledForPageCounter;
+    bool m_processSuppressionEnabled { true };
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+inline PassRefPtr&lt;RefCounter::Count&gt; PluginProcessManager::processSuppressionDisabledForPageCount()
+{
+    return m_processSuppressionDisabledForPageCounter.count();
+}
+
+inline bool PluginProcessManager::processSuppressionEnabled() const
+{
+    return m_processSuppressionEnabled;
+}
+
</ins><span class="cx"> } // namespace WebKit
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(NETSCAPE_PLUGIN_API)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPluginsPluginProcessProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp (177290 => 177291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp        2014-12-15 18:58:32 UTC (rev 177290)
+++ trunk/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp        2014-12-15 19:05:11 UTC (rev 177291)
</span><span class="lines">@@ -229,7 +229,7 @@
</span><span class="cx">     m_numPendingConnectionRequests = 0;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    if (WebContext::processSuppressionIsEnabledForAllContexts())
</del><ins>+    if (PluginProcessManager::shared().processSuppressionEnabled())
</ins><span class="cx">         setProcessSuppressionEnabled(true);
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPluginsmacPluginProcessManagerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessManagerMac.mm (177290 => 177291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessManagerMac.mm        2014-12-15 18:58:32 UTC (rev 177290)
+++ trunk/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessManagerMac.mm        2014-12-15 19:05:11 UTC (rev 177291)
</span><span class="lines">@@ -32,8 +32,13 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-void PluginProcessManager::setProcessSuppressionEnabled(bool processSuppressionEnabled)
</del><ins>+void PluginProcessManager::updateProcessSuppressionState()
</ins><span class="cx"> {
</span><ins>+    bool processSuppressionEnabled = !m_processSuppressionDisabledForPageCounter.value();
+    if (m_processSuppressionEnabled == processSuppressionEnabled)
+        return;
+    
+    m_processSuppressionEnabled = processSuppressionEnabled;
</ins><span class="cx">     for (auto&amp; pluginProcess : m_pluginProcesses)
</span><span class="cx">         pluginProcess-&gt;setProcessSuppressionEnabled(processSuppressionEnabled);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebContext.h (177290 => 177291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebContext.h        2014-12-15 18:58:32 UTC (rev 177290)
+++ trunk/Source/WebKit2/UIProcess/WebContext.h        2014-12-15 19:05:11 UTC (rev 177291)
</span><span class="lines">@@ -314,8 +314,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     bool processSuppressionEnabled() const;
</span><del>-    static bool processSuppressionIsEnabledForAllContexts();
-    static bool processSuppressionPreferenceIsEnabledForAllContexts();
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void windowServerConnectionStateChanged();
</span><span class="lines">@@ -346,7 +344,7 @@
</span><span class="cx">     static void unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&amp;);
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    void updateProcessSuppressionState() const;
</del><ins>+    void updateProcessSuppressionState();
</ins><span class="cx"> 
</span><span class="cx">     NSMutableDictionary *ensureBundleParameters();
</span><span class="cx">     NSMutableDictionary *bundleParameters() { return m_bundleParameters.get(); }
</span><span class="lines">@@ -575,6 +573,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     RetainPtr&lt;NSMutableDictionary&gt; m_bundleParameters;
</span><ins>+    RefPtr&lt;RefCounter::Count&gt; m_pluginProcessManagerProcessSuppressionDisabledCount;
</ins><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacWebContextMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm (177290 => 177291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm        2014-12-15 18:58:32 UTC (rev 177290)
+++ trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm        2014-12-15 19:05:11 UTC (rev 177291)
</span><span class="lines">@@ -103,14 +103,18 @@
</span><span class="cx">     [[NSUserDefaults standardUserDefaults] registerDefaults:registrationDictionary];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebContext::updateProcessSuppressionState() const
</del><ins>+void WebContext::updateProcessSuppressionState()
</ins><span class="cx"> {
</span><span class="cx"> #if ENABLE(NETWORK_PROCESS)
</span><span class="cx">     if (m_usesNetworkProcess &amp;&amp; m_networkProcess)
</span><span class="cx">         m_networkProcess-&gt;setProcessSuppressionEnabled(processSuppressionEnabled());
</span><span class="cx"> #endif
</span><ins>+
</ins><span class="cx"> #if ENABLE(NETSCAPE_PLUGIN_API)
</span><del>-    PluginProcessManager::shared().setProcessSuppressionEnabled(processSuppressionPreferenceIsEnabledForAllContexts());
</del><ins>+    if (!m_processSuppressionDisabledForPageCounter.value())
+        m_pluginProcessManagerProcessSuppressionDisabledCount = nullptr;
+    else if (!m_pluginProcessManagerProcessSuppressionDisabledCount)
+        m_pluginProcessManagerProcessSuppressionDisabledCount = PluginProcessManager::shared().processSuppressionDisabledForPageCount();
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -515,24 +519,6 @@
</span><span class="cx">     return !m_userObservablePageCounter.value() &amp;&amp; !m_processSuppressionDisabledForPageCounter.value();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebContext::processSuppressionIsEnabledForAllContexts()
-{
-    for (const auto* context : WebContext::allContexts()) {
-        if (!context-&gt;processSuppressionEnabled())
-            return false;
-    }
-    return true;
-}
-
-bool WebContext::processSuppressionPreferenceIsEnabledForAllContexts()
-{
-    for (const auto* context : WebContext::allContexts()) {
-        if (!context-&gt;m_defaultPageGroup-&gt;preferences().store().getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey()))
-            return false;
-    }
-    return true;
-}
-    
</del><span class="cx"> void WebContext::registerNotificationObservers()
</span><span class="cx"> {
</span><span class="cx"> #if !PLATFORM(IOS)
</span></span></pre>
</div>
</div>

</body>
</html>