Title: [242496] trunk/Source/WebKit
Revision
242496
Author
cdu...@apple.com
Date
2019-03-05 12:14:54 -0800 (Tue, 05 Mar 2019)

Log Message

Drop cached WebProcesses for a given session when this session is destroyed
https://bugs.webkit.org/show_bug.cgi?id=195212
<rdar://problem/48301483>

Reviewed by Geoffrey Garen.

Drop cached WebProcesses for a give session when this session is destroyed. This way, when you close
your private browsing window, all the processes it used get cleared and it cannot leave any state
behind.

* UIProcess/WebProcessCache.cpp:
(WebKit::WebProcessCache::canCacheProcess const):
(WebKit::WebProcessCache::addProcessIfPossible):
(WebKit::WebProcessCache::addProcess):
(WebKit::WebProcessCache::clearAllProcessesForSession):
* UIProcess/WebProcessCache.h:
(WebKit::WebProcessCache::capacity const):
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::pageEndUsingWebsiteDataStore):
(WebKit::WebProcessPool::hasPagesUsingWebsiteDataStore const):
* UIProcess/WebProcessPool.h:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (242495 => 242496)


--- trunk/Source/WebKit/ChangeLog	2019-03-05 19:44:33 UTC (rev 242495)
+++ trunk/Source/WebKit/ChangeLog	2019-03-05 20:14:54 UTC (rev 242496)
@@ -1,3 +1,27 @@
+2019-03-05  Chris Dumez  <cdu...@apple.com>
+
+        Drop cached WebProcesses for a given session when this session is destroyed
+        https://bugs.webkit.org/show_bug.cgi?id=195212
+        <rdar://problem/48301483>
+
+        Reviewed by Geoffrey Garen.
+
+        Drop cached WebProcesses for a give session when this session is destroyed. This way, when you close
+        your private browsing window, all the processes it used get cleared and it cannot leave any state
+        behind.
+
+        * UIProcess/WebProcessCache.cpp:
+        (WebKit::WebProcessCache::canCacheProcess const):
+        (WebKit::WebProcessCache::addProcessIfPossible):
+        (WebKit::WebProcessCache::addProcess):
+        (WebKit::WebProcessCache::clearAllProcessesForSession):
+        * UIProcess/WebProcessCache.h:
+        (WebKit::WebProcessCache::capacity const):
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::pageEndUsingWebsiteDataStore):
+        (WebKit::WebProcessPool::hasPagesUsingWebsiteDataStore const):
+        * UIProcess/WebProcessPool.h:
+
 2019-03-05  Brady Eidson  <beid...@apple.com>
 
         Correctly handle sandbox extensions when the same WKWebView loads multiple file:// URLs.

Modified: trunk/Source/WebKit/UIProcess/WebProcessCache.cpp (242495 => 242496)


--- trunk/Source/WebKit/UIProcess/WebProcessCache.cpp	2019-03-05 19:44:33 UTC (rev 242495)
+++ trunk/Source/WebKit/UIProcess/WebProcessCache.cpp	2019-03-05 20:14:54 UTC (rev 242496)
@@ -44,26 +44,35 @@
     platformInitialize();
 }
 
-bool WebProcessCache::addProcessIfPossible(const String& registrableDomain, Ref<WebProcessProxy>&& process)
+bool WebProcessCache::canCacheProcess(WebProcessProxy& process) const
 {
-    ASSERT(!registrableDomain.isEmpty());
-    ASSERT(!process->pageCount());
-    ASSERT(!process->provisionalPageCount());
-    ASSERT(!process->suspendedPageCount());
-
     if (!capacity())
         return false;
 
     if (MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
-        RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Not caching process %i because we are under memory pressure", this, process->processIdentifier());
+        RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::canCacheProcess(): Not caching process %i because we are under memory pressure", this, process.processIdentifier());
         return false;
     }
 
-    if (m_processesPerRegistrableDomain.contains(registrableDomain)) {
-        RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Not caching process %i because we already have a cached process for this domain", this, process->processIdentifier());
+    auto sessionID = process.websiteDataStore().sessionID();
+    if (sessionID != PAL::SessionID::defaultSessionID() && !process.processPool().hasPagesUsingWebsiteDataStore(process.websiteDataStore())) {
+        RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::canCacheProcess(): Not caching process %i because this session has been destroyed", this, process.processIdentifier());
         return false;
     }
 
+    return true;
+}
+
+bool WebProcessCache::addProcessIfPossible(const String& registrableDomain, Ref<WebProcessProxy>&& process)
+{
+    ASSERT(!registrableDomain.isEmpty());
+    ASSERT(!process->pageCount());
+    ASSERT(!process->provisionalPageCount());
+    ASSERT(!process->suspendedPageCount());
+
+    if (!canCacheProcess(process))
+        return false;
+
     RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Checking if process %i is responsive before caching it...", this, process->processIdentifier());
     process->setIsInProcessCache(true);
     process->isResponsive([process = process.copyRef(), processPool = makeRef(process->processPool()), registrableDomain](bool isResponsive) {
@@ -85,14 +94,9 @@
     ASSERT(!process->provisionalPageCount());
     ASSERT(!process->suspendedPageCount());
 
-    if (!capacity())
+    if (!canCacheProcess(process))
         return false;
 
-    if (MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
-        RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess(): Not caching process %i because we are under memory pressure", this, process->processIdentifier());
-        return false;
-    }
-
     while (m_processesPerRegistrableDomain.size() >= capacity()) {
         auto it = m_processesPerRegistrableDomain.random();
         RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess(): Evicting process %i from WebProcess cache", this, it->value->process().processIdentifier());
@@ -99,15 +103,9 @@
         m_processesPerRegistrableDomain.remove(it);
     }
 
-    auto addResult = m_processesPerRegistrableDomain.ensure(registrableDomain, [process = process.copyRef()]() mutable {
-        return std::make_unique<CachedProcess>(WTFMove(process));
-    });
-    if (!addResult.isNewEntry) {
-        RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess(): Not caching process %i because we already have a cached process for this domain", this, process->processIdentifier());
-        return false;
-    }
+    m_processesPerRegistrableDomain.set(registrableDomain, std::make_unique<CachedProcess>(process.copyRef()));
+    RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess: Adding process %i to WebProcess cache, cache size: [%u / %u]", this, process->processIdentifier(), size(), capacity());
 
-    RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess: Adding process %i to WebProcess cache, cache size: [%u / %u]", this, process->processIdentifier(), size(), capacity());
     return true;
 }
 
@@ -164,6 +162,19 @@
     m_processesPerRegistrableDomain.clear();
 }
 
+void WebProcessCache::clearAllProcessesForSession(PAL::SessionID sessionID)
+{
+    Vector<String> keysToRemove;
+    for (auto& pair : m_processesPerRegistrableDomain) {
+        if (pair.value->process().websiteDataStore().sessionID() == sessionID) {
+            RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::clearAllProcessesForSession() evicting process %i because its session was destroyed", this, pair.value->process().processIdentifier());
+            keysToRemove.append(pair.key);
+        }
+    }
+    for (auto& key : keysToRemove)
+        m_processesPerRegistrableDomain.remove(key);
+}
+
 void WebProcessCache::setApplicationIsActive(bool isActive)
 {
     RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::setApplicationIsActive(%d)", this, isActive);

Modified: trunk/Source/WebKit/UIProcess/WebProcessCache.h (242495 => 242496)


--- trunk/Source/WebKit/UIProcess/WebProcessCache.h	2019-03-05 19:44:33 UTC (rev 242495)
+++ trunk/Source/WebKit/UIProcess/WebProcessCache.h	2019-03-05 20:14:54 UTC (rev 242496)
@@ -26,6 +26,7 @@
 
 #pragma once
 
+#include <pal/SessionID.h>
 #include <wtf/HashMap.h>
 #include <wtf/RunLoop.h>
 #include <wtf/text/WTFString.h>
@@ -45,7 +46,7 @@
     RefPtr<WebProcessProxy> takeProcess(const String& registrableDomain, WebsiteDataStore&);
 
     void updateCapacity(WebProcessPool&);
-    unsigned capacity() { return m_capacity; }
+    unsigned capacity() const { return m_capacity; }
 
     unsigned size() const { return m_processesPerRegistrableDomain.size(); }
 
@@ -52,10 +53,13 @@
     void clear();
     void setApplicationIsActive(bool);
 
+    void clearAllProcessesForSession(PAL::SessionID);
+
 private:
     static Seconds cachedProcessLifetime;
     static Seconds clearingDelayAfterApplicationResignsActive;
 
+    bool canCacheProcess(WebProcessProxy&) const;
     void evictProcess(WebProcessProxy&);
     void platformInitialize();
     bool addProcess(const String& registrableDomain, Ref<WebProcessProxy>&&);

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (242495 => 242496)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2019-03-05 19:44:33 UTC (rev 242495)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2019-03-05 20:14:54 UTC (rev 242496)
@@ -1265,9 +1265,16 @@
         // The last user of this non-default PAL::SessionID is gone, so clean it up in the child processes.
         if (networkProcess())
             networkProcess()->removeSession(sessionID);
+
+        m_webProcessCache->clearAllProcessesForSession(sessionID);
     }
 }
 
+bool WebProcessPool::hasPagesUsingWebsiteDataStore(WebsiteDataStore& dataStore) const
+{
+    return m_sessionToPageIDsMap.contains(dataStore.sessionID());
+}
+
 DownloadProxy* WebProcessPool::download(WebPageProxy* initiatingPage, const ResourceRequest& request, const String& suggestedFilename)
 {
     auto* downloadProxy = createDownloadProxy(request, initiatingPage);

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (242495 => 242496)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.h	2019-03-05 19:44:33 UTC (rev 242495)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h	2019-03-05 20:14:54 UTC (rev 242496)
@@ -189,6 +189,7 @@
 
     void pageBeginUsingWebsiteDataStore(uint64_t pageID, WebsiteDataStore&);
     void pageEndUsingWebsiteDataStore(uint64_t pageID, WebsiteDataStore&);
+    bool hasPagesUsingWebsiteDataStore(WebsiteDataStore&) const;
 
     const String& injectedBundlePath() const { return m_configuration->injectedBundlePath(); }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to