Title: [240099] trunk/Source/WebKit
Revision
240099
Author
you...@apple.com
Date
2019-01-16 17:16:07 -0800 (Wed, 16 Jan 2019)

Log Message

Pipe cache quota request from Network Process to UIProcess
https://bugs.webkit.org/show_bug.cgi?id=193296

Reviewed by Alex Christensen.

When cache storage hits quota for a given origin, pipe the request back to NetworkProcess.
No record will be put until the quota request is answered.
The request is sent from CacheStorage::Caches to CacheStorage::Engine and to NetworkProcess.
NetworkProcess then sends it to NetworkProcessProxy.
Currently NetworkProcessProxy just answers by keeping the quota as it is.
In the future, NetworkProcessProxy should make a delegate call to let the app using WebKit
make a decision on the quota. This will allow prompting user to bump it as done for other data.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::requestCacheStorageSpace):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/cache/CacheStorageEngine.cpp:
(WebKit::CacheStorage::Engine::~Engine):
(WebKit::CacheStorage::Engine::from):
(WebKit::CacheStorage::Engine::Engine):
(WebKit::CacheStorage::Engine::requestSpace):
(WebKit::CacheStorage::Engine::requestSpaceCompleted):
* NetworkProcess/cache/CacheStorageEngine.h:
* NetworkProcess/cache/CacheStorageEngineCache.cpp:
(WebKit::CacheStorage::Cache::put):
(WebKit::CacheStorage::Cache::retryPuttingPendingRecords):
* NetworkProcess/cache/CacheStorageEngineCache.h:
* NetworkProcess/cache/CacheStorageEngineCaches.cpp:
(WebKit::CacheStorage::Caches::requestSpace):
(WebKit::CacheStorage::Caches::notifyCachesOfRequestSpaceEnd):
* NetworkProcess/cache/CacheStorageEngineCaches.h:
(WebKit::CacheStorage::Caches::isRequestingSpace const):
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::requestCacheStorageSpace):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (240098 => 240099)


--- trunk/Source/WebKit/ChangeLog	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/ChangeLog	2019-01-17 01:16:07 UTC (rev 240099)
@@ -1,3 +1,42 @@
+2019-01-16  Youenn Fablet  <you...@apple.com>
+
+        Pipe cache quota request from Network Process to UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=193296
+
+        Reviewed by Alex Christensen.
+
+        When cache storage hits quota for a given origin, pipe the request back to NetworkProcess.
+        No record will be put until the quota request is answered.
+        The request is sent from CacheStorage::Caches to CacheStorage::Engine and to NetworkProcess.
+        NetworkProcess then sends it to NetworkProcessProxy.
+        Currently NetworkProcessProxy just answers by keeping the quota as it is.
+        In the future, NetworkProcessProxy should make a delegate call to let the app using WebKit
+        make a decision on the quota. This will allow prompting user to bump it as done for other data.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::requestCacheStorageSpace):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/cache/CacheStorageEngine.cpp:
+        (WebKit::CacheStorage::Engine::~Engine):
+        (WebKit::CacheStorage::Engine::from):
+        (WebKit::CacheStorage::Engine::Engine):
+        (WebKit::CacheStorage::Engine::requestSpace):
+        (WebKit::CacheStorage::Engine::requestSpaceCompleted):
+        * NetworkProcess/cache/CacheStorageEngine.h:
+        * NetworkProcess/cache/CacheStorageEngineCache.cpp:
+        (WebKit::CacheStorage::Cache::put):
+        (WebKit::CacheStorage::Cache::retryPuttingPendingRecords):
+        * NetworkProcess/cache/CacheStorageEngineCache.h:
+        * NetworkProcess/cache/CacheStorageEngineCaches.cpp:
+        (WebKit::CacheStorage::Caches::requestSpace):
+        (WebKit::CacheStorage::Caches::notifyCachesOfRequestSpaceEnd):
+        * NetworkProcess/cache/CacheStorageEngineCaches.h:
+        (WebKit::CacheStorage::Caches::isRequestingSpace const):
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::requestCacheStorageSpace):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+
 2019-01-16  Alex Christensen  <achristen...@webkit.org>
 
         sendBeacon to previously-unvisited https domain always fails

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (240098 => 240099)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-01-17 01:16:07 UTC (rev 240099)
@@ -1413,6 +1413,11 @@
 }
 #endif // ENABLE(SERVICE_WORKER)
 
+void NetworkProcess::requestCacheStorageSpace(PAL::SessionID sessionID, const ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t>)>&& callback)
+{
+    parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::RequestCacheStorageSpace { sessionID, origin, quota, currentSize, spaceRequired }, WTFMove(callback), 0);
+}
+
 #if !PLATFORM(COCOA)
 void NetworkProcess::initializeProcess(const ChildProcessInitializationParameters&)
 {

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (240098 => 240099)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2019-01-17 01:16:07 UTC (rev 240099)
@@ -44,6 +44,7 @@
 #include <wtf/MemoryPressureHandler.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/RetainPtr.h>
+#include <wtf/WeakPtr.h>
 
 namespace IPC {
 class FormDataReference;
@@ -61,6 +62,7 @@
 class ResourceError;
 class SWServer;
 enum class StoredCredentialsPolicy : bool;
+struct ClientOrigin;
 struct MessageWithMessagePorts;
 struct SecurityOriginData;
 struct SoupNetworkProxySettings;
@@ -96,6 +98,7 @@
 #if ENABLE(INDEXED_DATABASE)
     , public WebCore::IDBServer::IDBBackingStoreTemporaryFileHandler
 #endif
+    , public CanMakeWeakPtr<NetworkProcess>
 {
     WTF_MAKE_NONCOPYABLE(NetworkProcess);
 public:
@@ -222,11 +225,12 @@
 
     void ref() const override { ThreadSafeRefCounted<NetworkProcess>::ref(); }
     void deref() const override { ThreadSafeRefCounted<NetworkProcess>::deref(); }
-    
+
     CacheStorage::Engine* findCacheEngine(const PAL::SessionID&);
     CacheStorage::Engine& ensureCacheEngine(const PAL::SessionID&, Function<Ref<CacheStorage::Engine>()>&&);
     void removeCacheEngine(const PAL::SessionID&);
-    
+    void requestCacheStorageSpace(PAL::SessionID, const WebCore::ClientOrigin&, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t>)>&&);
+
 private:
     NetworkProcess();
 

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp (240098 => 240099)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2019-01-17 01:16:07 UTC (rev 240099)
@@ -82,7 +82,7 @@
 
     networkProcess.cacheStorageParameters(sessionID, [networkProcess = makeRef(networkProcess), sessionID, callback = WTFMove(callback)] (auto&& rootPath, auto quota) mutable {
         callback(networkProcess->ensureCacheEngine(sessionID, [&] {
-            return adoptRef(*new Engine { String { rootPath }, quota });
+            return adoptRef(*new Engine { sessionID, networkProcess.get(), String { rootPath }, quota });
         }));
     });
 }
@@ -185,8 +185,10 @@
     });
 }
 
-Engine::Engine(String&& rootPath, uint64_t quota)
-    : m_rootPath(WTFMove(rootPath))
+Engine::Engine(PAL::SessionID sessionID, NetworkProcess& process, String&& rootPath, uint64_t quota)
+    : m_sessionID(sessionID)
+    , m_networkProcess(makeWeakPtr(process))
+    , m_rootPath(WTFMove(rootPath))
     , m_quota(quota)
 {
     if (!m_rootPath.isNull())
@@ -648,6 +650,15 @@
     return builder.toString();
 }
 
+void Engine::requestSpace(const WebCore::ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, RequestSpaceCallback&& callback)
+{
+    if (!m_networkProcess) {
+        callback({ });
+        return;
+    }
+    m_networkProcess->requestCacheStorageSpace(m_sessionID, origin, quota, currentSize, spaceRequired, WTFMove(callback));
+}
+
 } // namespace CacheStorage
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h (240098 => 240099)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h	2019-01-17 01:16:07 UTC (rev 240099)
@@ -90,8 +90,11 @@
     const NetworkCache::Salt& salt() const { return m_salt.value(); }
     uint64_t nextCacheIdentifier() { return ++m_nextCacheIdentifier; }
 
+    using RequestSpaceCallback = CompletionHandler<void(Optional<uint64_t>)>;
+    void requestSpace(const WebCore::ClientOrigin&, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, RequestSpaceCallback&&);
+
 private:
-    Engine(String&& rootPath, uint64_t quota);
+    Engine(PAL::SessionID, NetworkProcess&, String&& rootPath, uint64_t quota);
 
     void open(const WebCore::ClientOrigin&, const String& cacheName, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
     void remove(uint64_t cacheIdentifier, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
@@ -129,6 +132,8 @@
 
     Cache* cache(uint64_t cacheIdentifier);
 
+    PAL::SessionID m_sessionID;
+    WeakPtr<NetworkProcess> m_networkProcess;
     HashMap<WebCore::ClientOrigin, RefPtr<Caches>> m_caches;
     uint64_t m_nextCacheIdentifier { 0 };
     String m_rootPath;

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.cpp (240098 => 240099)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.cpp	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.cpp	2019-01-17 01:16:07 UTC (rev 240099)
@@ -400,10 +400,15 @@
     }
 }
 
-void Cache::put(Vector<Record>&& records, RecordIdentifiersCallback&& callback)
+void Cache::put(Vector<Record>&& records, RecordIdentifiersCallback&& callback, CanRequestMoreSpace canRequestMoreSpace)
 {
     ASSERT(m_state == State::Open);
 
+    if (m_caches.isRequestingSpace()) {
+        m_pendingPutRequests.append({ WTFMove(records), WTFMove(callback) });
+        return;
+    }
+
     WebCore::CacheQueryOptions options;
     uint64_t spaceRequired = 0;
 
@@ -423,6 +428,11 @@
         return;
     }
 
+    if (canRequestMoreSpace == CanRequestMoreSpace::No) {
+        callback(makeUnexpected(DOMCacheEngine::Error::QuotaExceeded));
+        return;
+    }
+
     m_caches.requestSpace(spaceRequired, [caches = makeRef(m_caches), identifier = m_identifier, records = WTFMove(records), callback = WTFMove(callback)](Optional<DOMCacheEngine::Error>&& error) mutable {
         if (error) {
             callback(makeUnexpected(error.value()));
@@ -429,13 +439,22 @@
             return;
         }
         auto* cache = caches->find(identifier);
-        if (!cache)
+        if (!cache) {
+            callback(makeUnexpected(DOMCacheEngine::Error::Internal));
             return;
+        }
 
-        cache->storeRecords(WTFMove(records), WTFMove(callback));
+        cache->put(WTFMove(records), WTFMove(callback), CanRequestMoreSpace::No);
     });
 }
 
+void Cache::retryPuttingPendingRecords()
+{
+    auto pendingPutRequests = WTFMove(m_pendingPutRequests);
+    for (auto& request : pendingPutRequests)
+        put(WTFMove(request.records), WTFMove(request.callback));
+}
+
 void Cache::remove(WebCore::ResourceRequest&& request, WebCore::CacheQueryOptions&& options, RecordIdentifiersCallback&& callback)
 {
     ASSERT(m_state == State::Open);

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.h (240098 => 240099)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.h	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.h	2019-01-17 01:16:07 UTC (rev 240099)
@@ -69,7 +69,8 @@
     void retrieveRecords(const URL&, WebCore::DOMCacheEngine::RecordsCallback&&);
     WebCore::DOMCacheEngine::CacheInfo info() const { return { m_identifier, m_name }; }
 
-    void put(Vector<WebCore::DOMCacheEngine::Record>&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
+    enum class CanRequestMoreSpace { No, Yes };
+    void put(Vector<WebCore::DOMCacheEngine::Record>&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&, CanRequestMoreSpace = CanRequestMoreSpace::Yes);
     void remove(WebCore::ResourceRequest&&, WebCore::CacheQueryOptions&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
 
     Vector<NetworkCache::Key> keys() const;
@@ -77,6 +78,8 @@
     void dispose();
     void clearMemoryRepresentation();
 
+    void retryPuttingPendingRecords();
+
     static Optional<WebCore::DOMCacheEngine::Record> decode(const NetworkCache::Storage::Record&);
     static NetworkCache::Storage::Record encode(const RecordInformation&, const WebCore::DOMCacheEngine::Record&);
 
@@ -120,6 +123,12 @@
     HashMap<String, Vector<RecordInformation>> m_records;
     uint64_t m_nextRecordIdentifier { 0 };
     Vector<WebCore::DOMCacheEngine::CompletionCallback> m_pendingOpeningCallbacks;
+
+    struct PendingPutRequest {
+        Vector<WebCore::DOMCacheEngine::Record> records;
+        WebCore::DOMCacheEngine::RecordIdentifiersCallback callback;
+    };
+    Vector<PendingPutRequest> m_pendingPutRequests;
 };
 
 } // namespace CacheStorage

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp (240098 => 240099)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp	2019-01-17 01:16:07 UTC (rev 240099)
@@ -481,11 +481,37 @@
 
 void Caches::requestSpace(uint64_t spaceRequired, WebCore::DOMCacheEngine::CompletionCallback&& callback)
 {
-    // FIXME: Implement quota increase request.
+    ASSERT(!m_isRequestingSpace);
+
     ASSERT(m_quota < m_size + spaceRequired);
-    callback(Error::QuotaExceeded);
+
+    if (!m_engine) {
+        callback(Error::QuotaExceeded);
+        return;
+    }
+
+    m_isRequestingSpace = true;
+    m_engine->requestSpace(m_origin, m_quota, m_size, spaceRequired, [this, protectedThis = makeRef(*this), callback = WTFMove(callback)] (Optional<uint64_t> newQuota) {
+        m_isRequestingSpace = false;
+        if (!newQuota) {
+            callback(Error::QuotaExceeded);
+            notifyCachesOfRequestSpaceEnd();
+            return;
+        }
+        m_quota = *newQuota;
+        callback({ });
+        notifyCachesOfRequestSpaceEnd();
+    });
 }
 
+void Caches::notifyCachesOfRequestSpaceEnd()
+{
+    for (auto& cache : m_caches)
+        cache.retryPuttingPendingRecords();
+    for (auto& cache : m_removedCaches)
+        cache.retryPuttingPendingRecords();
+}
+
 void Caches::writeRecord(const Cache& cache, const RecordInformation& recordInformation, Record&& record, uint64_t previousRecordSize, CompletionCallback&& callback)
 {
     ASSERT(m_isInitialized);

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h (240098 => 240099)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h	2019-01-17 01:16:07 UTC (rev 240099)
@@ -61,6 +61,7 @@
     void readRecord(const NetworkCache::Key&, WTF::Function<void(Expected<WebCore::DOMCacheEngine::Record, WebCore::DOMCacheEngine::Error>&&)>&&);
 
     bool hasEnoughSpace(uint64_t spaceRequired) const { return m_quota >= m_size + spaceRequired; }
+    bool isRequestingSpace() const { return m_isRequestingSpace; }
     void requestSpace(uint64_t spaceRequired, WebCore::DOMCacheEngine::CompletionCallback&&);
     void writeRecord(const Cache&, const RecordInformation&, WebCore::DOMCacheEngine::Record&&, uint64_t previousRecordSize, WebCore::DOMCacheEngine::CompletionCallback&&);
 
@@ -93,7 +94,10 @@
     void makeDirty() { ++m_updateCounter; }
     bool isDirty(uint64_t updateCounter) const;
 
+    void notifyCachesOfRequestSpaceEnd();
+
     bool m_isInitialized { false };
+    bool m_isRequestingSpace { false };
     Engine* m_engine { nullptr };
     uint64_t m_updateCounter { 0 };
     WebCore::ClientOrigin m_origin;

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (240098 => 240099)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2019-01-17 01:16:07 UTC (rev 240099)
@@ -734,6 +734,19 @@
 }
 #endif
 
+void NetworkProcessProxy::requestCacheStorageSpace(PAL::SessionID sessionID, const WebCore::ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&& completionHandler)
+{
+    auto* store = websiteDataStoreFromSessionID(sessionID);
+
+    if (!store) {
+        completionHandler({ });
+        return;
+    }
+
+    // FIXME: Ask WebsiteDataStore about updating the quota for this origin.
+    completionHandler(quota);
+}
+
 } // namespace WebKit
 
 #undef MESSAGE_CHECK

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (240098 => 240099)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2019-01-17 01:16:07 UTC (rev 240099)
@@ -166,6 +166,8 @@
     void establishWorkerContextConnectionToNetworkProcessForExplicitSession(WebCore::SecurityOriginData&&, PAL::SessionID);
 #endif
 
+    void requestCacheStorageSpace(PAL::SessionID, const WebCore::ClientOrigin&, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&&);
+
     WebsiteDataStore* websiteDataStoreFromSessionID(PAL::SessionID);
 
     // ProcessLauncher::Client

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in (240098 => 240099)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2019-01-17 01:08:27 UTC (rev 240098)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2019-01-17 01:16:07 UTC (rev 240099)
@@ -63,4 +63,6 @@
     EstablishWorkerContextConnectionToNetworkProcess(struct WebCore::SecurityOriginData origin)
     EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(struct WebCore::SecurityOriginData origin, PAL::SessionID explicitSession)
 #endif
+
+    RequestCacheStorageSpace(PAL::SessionID sessionID, struct WebCore::ClientOrigin origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired) -> (Optional<uint64_t> newQuota) Async
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to