[Cache API] Implement Worker connection to the Cache storage engine
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Aug 2017 22:09:34 +0000 (22:09 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Aug 2017 22:09:34 +0000 (22:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175599

Patch by Youenn Fablet <youenn@apple.com> on 2017-08-16
Reviewed by Chris Dumez.

Covered by existing tests.

Adding a WorkerCacheStorageConnection to connect workers Cache/CacheStorage
to the cache storage engine.
WorkerCacheStorageConnection does this by hopping to the main thread to call the document cache storage connection to do the actual job.
Doing some CacheStorageConnection refactoring to share code with WK2 implementation of the cache storage connection.

* Modules/cache/CacheQueryOptions.h:
(WebCore::CacheQueryOptions::isolatedCopy const):
* Modules/cache/CacheStorageConnection.cpp:
(WebCore::CacheStorageConnection::open):
(WebCore::CacheStorageConnection::remove):
(WebCore::CacheStorageConnection::retrieveCaches):
(WebCore::CacheStorageConnection::retrieveRecords):
(WebCore::CacheStorageConnection::batchDeleteOperation):
(WebCore::CacheStorageConnection::batchPutOperation):
(WebCore::CacheStorageConnection::openOrRemoveCompleted):
(WebCore::CacheStorageConnection::updateCaches):
(WebCore::CacheStorageConnection::updateRecords):
(WebCore::CacheStorageConnection::removeRecordsCompleted):
(WebCore::CacheStorageConnection::putRecordsCompleted):
* Modules/cache/CacheStorageConnection.h:
(WebCore::CacheStorageConnection::openCompleted):
(WebCore::CacheStorageConnection::removeCompleted):
(WebCore::CacheStorageConnection::doOpen):
(WebCore::CacheStorageConnection::doRemove):
(WebCore::CacheStorageConnection::doRetrieveCaches):
(WebCore::CacheStorageConnection::doRetrieveRecords):
(WebCore::CacheStorageConnection::doBatchDeleteOperation):
(WebCore::CacheStorageConnection::doBatchPutOperation):
* Modules/cache/WorkerCacheStorageConnection.cpp: Added.
(WebCore::toCrossThreadRecordData):
(WebCore::fromCrossThreadRecordData):
(WebCore::WorkerCacheStorageConnection::create):
(WebCore::WorkerCacheStorageConnection::WorkerCacheStorageConnection):
(WebCore::WorkerCacheStorageConnection::doOpen):
(WebCore::WorkerCacheStorageConnection::doRemove):
(WebCore::WorkerCacheStorageConnection::doRetrieveCaches):
(WebCore::WorkerCacheStorageConnection::doRetrieveRecords):
(WebCore::WorkerCacheStorageConnection::doBatchDeleteOperation):
(WebCore::WorkerCacheStorageConnection::doBatchPutOperation):
* Modules/cache/WorkerCacheStorageConnection.h: Added.
* Modules/cache/WorkerGlobalScopeCaches.cpp:
(WebCore::WorkerGlobalScopeCaches::caches const):
* WebCore.xcodeproj/project.pbxproj:
* loader/FetchOptions.h:
(WebCore::FetchOptions::isolatedCopy const):
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::cacheStorageConnection):
* workers/WorkerGlobalScope.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220810 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/cache/CacheQueryOptions.h
Source/WebCore/Modules/cache/CacheStorageConnection.cpp
Source/WebCore/Modules/cache/CacheStorageConnection.h
Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp [new file with mode: 0644]
Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h [new file with mode: 0644]
Source/WebCore/Modules/cache/WorkerGlobalScopeCaches.cpp
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/loader/FetchOptions.h
Source/WebCore/workers/WorkerGlobalScope.cpp
Source/WebCore/workers/WorkerGlobalScope.h

index 067dd7d4c840f4d7a5add663e52b5d5344a9994e..4c7ae909be3c41fe94e7882fa0e9ff00a77b88eb 100644 (file)
@@ -898,6 +898,7 @@ set(WebCore_SOURCES
     Modules/cache/CacheStorage.cpp
     Modules/cache/CacheStorageConnection.cpp
     Modules/cache/DOMWindowCaches.cpp
+    Modules/cache/WorkerCacheStorageConnection.cpp
     Modules/cache/WorkerGlobalScopeCaches.cpp
 
     Modules/credentials/BasicCredential.cpp
index 823a0fc5e140a11fb1e4f5cab9787d05ebdabd0c..9db400add8add84cc79a37d8fa2e396287947582 100644 (file)
@@ -1,3 +1,61 @@
+2017-08-16  Youenn Fablet  <youenn@apple.com>
+
+        [Cache API] Implement Worker connection to the Cache storage engine
+        https://bugs.webkit.org/show_bug.cgi?id=175599
+
+        Reviewed by Chris Dumez.
+
+        Covered by existing tests.
+
+        Adding a WorkerCacheStorageConnection to connect workers Cache/CacheStorage
+        to the cache storage engine.
+        WorkerCacheStorageConnection does this by hopping to the main thread to call the document cache storage connection to do the actual job.
+        Doing some CacheStorageConnection refactoring to share code with WK2 implementation of the cache storage connection. 
+
+        * Modules/cache/CacheQueryOptions.h:
+        (WebCore::CacheQueryOptions::isolatedCopy const):
+        * Modules/cache/CacheStorageConnection.cpp:
+        (WebCore::CacheStorageConnection::open):
+        (WebCore::CacheStorageConnection::remove):
+        (WebCore::CacheStorageConnection::retrieveCaches):
+        (WebCore::CacheStorageConnection::retrieveRecords):
+        (WebCore::CacheStorageConnection::batchDeleteOperation):
+        (WebCore::CacheStorageConnection::batchPutOperation):
+        (WebCore::CacheStorageConnection::openOrRemoveCompleted):
+        (WebCore::CacheStorageConnection::updateCaches):
+        (WebCore::CacheStorageConnection::updateRecords):
+        (WebCore::CacheStorageConnection::removeRecordsCompleted):
+        (WebCore::CacheStorageConnection::putRecordsCompleted):
+        * Modules/cache/CacheStorageConnection.h:
+        (WebCore::CacheStorageConnection::openCompleted):
+        (WebCore::CacheStorageConnection::removeCompleted):
+        (WebCore::CacheStorageConnection::doOpen):
+        (WebCore::CacheStorageConnection::doRemove):
+        (WebCore::CacheStorageConnection::doRetrieveCaches):
+        (WebCore::CacheStorageConnection::doRetrieveRecords):
+        (WebCore::CacheStorageConnection::doBatchDeleteOperation):
+        (WebCore::CacheStorageConnection::doBatchPutOperation):
+        * Modules/cache/WorkerCacheStorageConnection.cpp: Added.
+        (WebCore::toCrossThreadRecordData):
+        (WebCore::fromCrossThreadRecordData):
+        (WebCore::WorkerCacheStorageConnection::create):
+        (WebCore::WorkerCacheStorageConnection::WorkerCacheStorageConnection):
+        (WebCore::WorkerCacheStorageConnection::doOpen):
+        (WebCore::WorkerCacheStorageConnection::doRemove):
+        (WebCore::WorkerCacheStorageConnection::doRetrieveCaches):
+        (WebCore::WorkerCacheStorageConnection::doRetrieveRecords):
+        (WebCore::WorkerCacheStorageConnection::doBatchDeleteOperation):
+        (WebCore::WorkerCacheStorageConnection::doBatchPutOperation):
+        * Modules/cache/WorkerCacheStorageConnection.h: Added.
+        * Modules/cache/WorkerGlobalScopeCaches.cpp:
+        (WebCore::WorkerGlobalScopeCaches::caches const):
+        * WebCore.xcodeproj/project.pbxproj:
+        * loader/FetchOptions.h:
+        (WebCore::FetchOptions::isolatedCopy const):
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::cacheStorageConnection):
+        * workers/WorkerGlobalScope.h:
+
 2017-08-16  Yoshiaki Jitsukawa  <Yoshiaki.Jitsukawa@sony.com>
 
         [PAL] Move spi/ios and spi/win directories into PAL
index 68f67facf356871eef4e5546958b727a6593693b..7427b8dbb07f06805d6b146fc089586cbb7f26f1 100644 (file)
 namespace WebCore {
 
 struct CacheQueryOptions {
+    CacheQueryOptions() = default;
+    CacheQueryOptions(bool ignoreSearch, bool ignoreMethod, bool ignoreVary, String cacheName);
+    CacheQueryOptions isolatedCopy() const { return { ignoreSearch, ignoreMethod, ignoreVary, cacheName.isolatedCopy() }; }
+
     bool ignoreSearch { false };
     bool ignoreMethod { false };
     bool ignoreVary { false };
     String cacheName;
 };
 
+inline CacheQueryOptions::CacheQueryOptions(bool ignoreSearch, bool ignoreMethod, bool ignoreVary, String cacheName)
+    : ignoreSearch(ignoreSearch)
+    , ignoreMethod(ignoreMethod)
+    , ignoreVary(ignoreVary)
+    , cacheName(cacheName.isolatedCopy())
+{
+}
+
 } // namespace WebCore
index f44f9e417d43caef3b22939e3232d9fadac5d0b1..53f0b6571300fed8fb0d5272c472f9eecf843195 100644 (file)
@@ -78,5 +78,82 @@ bool CacheStorageConnection::queryCacheMatch(const ResourceRequest& request, con
     return true;
 }
 
-} // namespace WebCore
+void CacheStorageConnection::open(const String& origin, const String& cacheName, OpenRemoveCallback&& callback)
+{
+    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
+    m_openAndRemoveCachePendingRequests.add(requestIdentifier, WTFMove(callback));
+
+    doOpen(requestIdentifier, origin, cacheName);
+}
+
+void CacheStorageConnection::remove(uint64_t cacheIdentifier, OpenRemoveCallback&& callback)
+{
+    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
+    m_openAndRemoveCachePendingRequests.add(requestIdentifier, WTFMove(callback));
+
+    doRemove(requestIdentifier, cacheIdentifier);
+}
+
+void CacheStorageConnection::retrieveCaches(const String& origin, CachesCallback&& callback)
+{
+    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
+    m_retrieveCachesPendingRequests.add(requestIdentifier, WTFMove(callback));
+
+    doRetrieveCaches(requestIdentifier, origin);
+}
+
+void CacheStorageConnection::retrieveRecords(uint64_t cacheIdentifier, RecordsCallback&& callback)
+{
+    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
+    m_retrieveRecordsPendingRequests.add(requestIdentifier, WTFMove(callback));
+
+    doRetrieveRecords(requestIdentifier, cacheIdentifier);
+}
+
+void CacheStorageConnection::batchDeleteOperation(uint64_t cacheIdentifier, const WebCore::ResourceRequest& request, WebCore::CacheQueryOptions&& options, BatchOperationCallback&& callback)
+{
+    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
+    m_batchDeleteAndPutPendingRequests.add(requestIdentifier, WTFMove(callback));
+
+    doBatchDeleteOperation(requestIdentifier, cacheIdentifier, request, WTFMove(options));
+}
 
+void CacheStorageConnection::batchPutOperation(uint64_t cacheIdentifier, Vector<WebCore::CacheStorageConnection::Record>&& records, BatchOperationCallback&& callback)
+{
+    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
+    m_batchDeleteAndPutPendingRequests.add(requestIdentifier, WTFMove(callback));
+
+    doBatchPutOperation(requestIdentifier, cacheIdentifier, WTFMove(records));
+}
+
+void CacheStorageConnection::openOrRemoveCompleted(uint64_t requestIdentifier, uint64_t cacheIdentifier, Error error)
+{
+    if (auto callback = m_openAndRemoveCachePendingRequests.take(requestIdentifier))
+        callback(cacheIdentifier, error);
+}
+
+void CacheStorageConnection::updateCaches(uint64_t requestIdentifier, Vector<CacheInfo>&& caches)
+{
+    if (auto callback = m_retrieveCachesPendingRequests.take(requestIdentifier))
+        callback(WTFMove(caches));
+}
+
+void CacheStorageConnection::updateRecords(uint64_t requestIdentifier, Vector<Record>&& records)
+{
+    if (auto callback = m_retrieveRecordsPendingRequests.take(requestIdentifier))
+        callback(WTFMove(records));
+}
+
+void CacheStorageConnection::deleteRecordsCompleted(uint64_t requestIdentifier, Vector<uint64_t>&& records, Error error)
+{
+    if (auto callback = m_batchDeleteAndPutPendingRequests.take(requestIdentifier))
+        callback(WTFMove(records), error);
+}
+
+void CacheStorageConnection::putRecordsCompleted(uint64_t requestIdentifier, Vector<uint64_t>&& records, Error error)
+{
+    if (auto callback = m_batchDeleteAndPutPendingRequests.take(requestIdentifier))
+        callback(WTFMove(records), error);
+}
+
+} // namespace WebCore
index 23ed3e588a83d52f8cb604e3e741fa5c208fb4b8..2bf69e5ac5d22ba2d0a49ba88d540d37f37ea29a 100644 (file)
@@ -30,6 +30,7 @@
 #include "FetchOptions.h"
 #include "ResourceRequest.h"
 #include "ResourceResponse.h"
+#include <wtf/HashMap.h>
 #include <wtf/ThreadSafeRefCounted.h>
 
 namespace WebCore {
@@ -68,20 +69,46 @@ public:
     };
 
     using OpenRemoveCallback = WTF::Function<void(uint64_t, Error)>;
-    using CacheMapCallback = WTF::Function<void(Vector<CacheInfo>&&)>;
+    using CachesCallback = WTF::Function<void(Vector<CacheInfo>&&)>;
     using RecordsCallback = WTF::Function<void(Vector<Record>&&)>;
     using BatchOperationCallback = WTF::Function<void(Vector<uint64_t>&&, Error)>;
 
-    virtual void open(const String& /* origin */, const String& /* cacheName */, OpenRemoveCallback&& callback) { callback(0, Error::NotImplemented); }
-    virtual void remove(uint64_t /* cacheIdentifier */, OpenRemoveCallback&& callback) { callback(0, Error::NotImplemented); }
-    virtual void retrieveCaches(const String& /* origin */, CacheMapCallback&& callback) { callback({ }); }
+    void open(const String& /* origin */, const String& /* cacheName */, OpenRemoveCallback&&);
+    void remove(uint64_t /* cacheIdentifier */, OpenRemoveCallback&&);
+    void retrieveCaches(const String& /* origin */, CachesCallback&&);
 
-    virtual void retrieveRecords(uint64_t /* cacheIdentifier */, RecordsCallback&& callback) { callback({ }); }
-    virtual void batchDeleteOperation(uint64_t /* cacheIdentifier */, const ResourceRequest&, CacheQueryOptions&&, BatchOperationCallback&& callback) { callback({ }, Error::NotImplemented); }
-    virtual void batchPutOperation(uint64_t /* cacheIdentifier */, Vector<Record>&&, BatchOperationCallback&& callback) { callback({ }, Error::NotImplemented); }
+    void retrieveRecords(uint64_t /* cacheIdentifier */, RecordsCallback&&);
+    void batchDeleteOperation(uint64_t /* cacheIdentifier */, const ResourceRequest&, CacheQueryOptions&&, BatchOperationCallback&&);
+    void batchPutOperation(uint64_t /* cacheIdentifier */, Vector<Record>&&, BatchOperationCallback&&);
 
 protected:
     CacheStorageConnection() =  default;
+
+    void openCompleted(uint64_t identifier, uint64_t cacheIdentifier, Error error) { openOrRemoveCompleted(identifier, cacheIdentifier, error); }
+    void removeCompleted(uint64_t identifier, uint64_t cacheIdentifier, Error error) { openOrRemoveCompleted(identifier, cacheIdentifier, error); }
+    WEBCORE_EXPORT void updateCaches(uint64_t requestIdentifier, Vector<CacheInfo>&&);
+
+    WEBCORE_EXPORT void updateRecords(uint64_t requestIdentifier, Vector<Record>&&);
+    WEBCORE_EXPORT void deleteRecordsCompleted(uint64_t requestIdentifier, Vector<uint64_t>&&, Error);
+    WEBCORE_EXPORT void putRecordsCompleted(uint64_t requestIdentifier, Vector<uint64_t>&&, Error);
+
+private:
+    virtual void doOpen(uint64_t requestIdentifier, const String& /* origin */, const String& /* cacheName */) { openCompleted(requestIdentifier, 0, Error::NotImplemented); }
+    virtual void doRemove(uint64_t requestIdentifier, uint64_t /* cacheIdentifier */) { removeCompleted(requestIdentifier, 0, Error::NotImplemented); }
+    virtual void doRetrieveCaches(uint64_t requestIdentifier, const String& /* origin */) { updateCaches(requestIdentifier, { }); }
+
+    virtual void doRetrieveRecords(uint64_t requestIdentifier, uint64_t /* cacheIdentifier */) { updateRecords(requestIdentifier, { }); }
+    virtual void doBatchDeleteOperation(uint64_t requestIdentifier, uint64_t /* cacheIdentifier */, const ResourceRequest&, CacheQueryOptions&&) { deleteRecordsCompleted(requestIdentifier, { }, Error::NotImplemented); }
+    virtual void doBatchPutOperation(uint64_t requestIdentifier, uint64_t /* cacheIdentifier */, Vector<Record>&&) { putRecordsCompleted(requestIdentifier, { }, Error::NotImplemented); }
+
+    WEBCORE_EXPORT void openOrRemoveCompleted(uint64_t requestIdentifier, uint64_t cacheIdentifier, Error);
+
+    HashMap<uint64_t, OpenRemoveCallback> m_openAndRemoveCachePendingRequests;
+    HashMap<uint64_t, CachesCallback> m_retrieveCachesPendingRequests;
+    HashMap<uint64_t, RecordsCallback> m_retrieveRecordsPendingRequests;
+    HashMap<uint64_t, BatchOperationCallback> m_batchDeleteAndPutPendingRequests;
+
+    uint64_t m_lastRequestIdentifier { 0 };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp b/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp
new file mode 100644 (file)
index 0000000..29c9fad
--- /dev/null
@@ -0,0 +1,222 @@
+
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WorkerCacheStorageConnection.h"
+
+#include "CacheQueryOptions.h"
+#include "CacheStorageProvider.h"
+#include "Document.h"
+#include "Page.h"
+#include "WorkerGlobalScope.h"
+#include "WorkerLoaderProxy.h"
+#include "WorkerRunLoop.h"
+#include "WorkerThread.h"
+
+namespace WebCore {
+
+struct CrossThreadRecordData {
+    uint64_t identifier;
+
+    FetchHeaders::Guard requestHeadersGuard;
+    ResourceRequest request;
+
+    FetchOptions options;
+    String referrer;
+
+    FetchHeaders::Guard responseHeadersGuard;
+    ResourceResponse::CrossThreadData response;
+};
+
+static CrossThreadRecordData toCrossThreadRecordData(const CacheStorageConnection::Record& record)
+{
+    return CrossThreadRecordData {
+        record.identifier,
+        record.requestHeadersGuard,
+        record.request.isolatedCopy(),
+        record.options.isolatedCopy(),
+        record.referrer.isolatedCopy(),
+        record.responseHeadersGuard,
+        record.response.crossThreadData()
+    };
+}
+
+static CacheStorageConnection::Record fromCrossThreadRecordData(CrossThreadRecordData&& data)
+{
+    return CacheStorageConnection::Record {
+        data.identifier,
+        data.requestHeadersGuard,
+        WTFMove(data.request),
+        WTFMove(data.options),
+        WTFMove(data.referrer),
+        data.responseHeadersGuard,
+        ResourceResponse::fromCrossThreadData(WTFMove(data.response))
+    };
+}
+
+Ref<WorkerCacheStorageConnection> WorkerCacheStorageConnection::create(WorkerGlobalScope& scope)
+{
+    auto connection = adoptRef(*new WorkerCacheStorageConnection(scope));
+    connection->m_proxy.postTaskToLoader([protectedConnection = makeRef(connection.get())](ScriptExecutionContext& context) mutable {
+        ASSERT(isMainThread());
+        Document& document = downcast<Document>(context);
+
+        ASSERT(document.page());
+        protectedConnection->m_mainThreadConnection = document.page()->cacheStorageProvider().createCacheStorageConnection(document.page()->sessionID());
+    });
+    return connection;
+}
+
+WorkerCacheStorageConnection::WorkerCacheStorageConnection(WorkerGlobalScope& scope)
+    : m_scope(scope)
+    , m_proxy(m_scope.thread().workerLoaderProxy())
+    , m_taskMode(WorkerRunLoop::defaultMode().isolatedCopy())
+{
+}
+
+WorkerCacheStorageConnection::~WorkerCacheStorageConnection()
+{
+    if (m_mainThreadConnection)
+        m_proxy.postTaskToLoader([mainThreadConnection = WTFMove(m_mainThreadConnection)](ScriptExecutionContext&) mutable { });
+}
+
+void WorkerCacheStorageConnection::doOpen(uint64_t requestIdentifier, const String& origin, const String& cacheName)
+{
+    m_proxy.postTaskToLoader([this, protectedThis = makeRef(*this), requestIdentifier, origin = origin.isolatedCopy(), cacheName = cacheName.isolatedCopy()](ScriptExecutionContext&) mutable {
+        ASSERT(isMainThread());
+        ASSERT(m_mainThreadConnection);
+
+        m_mainThreadConnection->open(origin, cacheName, [this, protectedThis = WTFMove(protectedThis), requestIdentifier](uint64_t cacheIdentifier, Error error) mutable {
+            m_proxy.postTaskForModeToWorkerGlobalScope([this, error, cacheIdentifier, protectedThis = WTFMove(protectedThis), requestIdentifier](ScriptExecutionContext& context) mutable {
+                ASSERT_UNUSED(context, context.isWorkerGlobalScope());
+                openCompleted(requestIdentifier, cacheIdentifier, error);
+            }, m_taskMode);
+        });
+    });
+}
+
+void WorkerCacheStorageConnection::doRemove(uint64_t requestIdentifier, uint64_t cacheIdentifier)
+{
+    m_proxy.postTaskToLoader([this, protectedThis = makeRef(*this), requestIdentifier, cacheIdentifier](ScriptExecutionContext&) mutable {
+        ASSERT(isMainThread());
+        ASSERT(m_mainThreadConnection);
+
+        m_mainThreadConnection->remove(cacheIdentifier, [this, protectedThis = WTFMove(protectedThis), requestIdentifier, cacheIdentifier](uint64_t removedCacheIdentifier, Error error) mutable {
+            ASSERT_UNUSED(removedCacheIdentifier, removedCacheIdentifier == cacheIdentifier);
+            m_proxy.postTaskForModeToWorkerGlobalScope([this, protectedThis = WTFMove(protectedThis), requestIdentifier, cacheIdentifier, error](ScriptExecutionContext& context) mutable {
+                ASSERT_UNUSED(context, context.isWorkerGlobalScope());
+                removeCompleted(requestIdentifier, cacheIdentifier, error);
+            }, m_taskMode);
+        });
+    });
+}
+
+void WorkerCacheStorageConnection::doRetrieveCaches(uint64_t requestIdentifier, const String& origin)
+{
+    m_proxy.postTaskToLoader([this, protectedThis = makeRef(*this), requestIdentifier, origin = origin.isolatedCopy()](ScriptExecutionContext&) mutable {
+        ASSERT(isMainThread());
+        ASSERT(m_mainThreadConnection);
+
+        m_mainThreadConnection->retrieveCaches(origin, [this, protectedThis = WTFMove(protectedThis), requestIdentifier](const Vector<CacheInfo>& caches) mutable {
+            Vector<CacheInfo> isolatedCaches;
+            isolatedCaches.reserveInitialCapacity(caches.size());
+            for (const auto& cache : caches)
+                isolatedCaches.uncheckedAppend(CacheInfo { cache.identifier, cache.name.isolatedCopy() });
+
+            m_proxy.postTaskForModeToWorkerGlobalScope([this, protectedThis = WTFMove(protectedThis), caches = WTFMove(isolatedCaches), requestIdentifier](ScriptExecutionContext& context) mutable {
+                ASSERT_UNUSED(context, context.isWorkerGlobalScope());
+                updateCaches(requestIdentifier, WTFMove(caches));
+            }, m_taskMode);
+        });
+    });
+}
+
+static inline Vector<CrossThreadRecordData> recordsDataFromRecords(const Vector<CacheStorageConnection::Record>& records)
+{
+    Vector<CrossThreadRecordData> recordsData;
+    recordsData.reserveInitialCapacity(records.size());
+    for (const auto& record : records)
+        recordsData.uncheckedAppend(toCrossThreadRecordData(record));
+    return recordsData;
+}
+
+static inline Vector<CacheStorageConnection::Record> recordsFromRecordsData(Vector<CrossThreadRecordData>&& recordsData)
+{
+    Vector<CacheStorageConnection::Record> records;
+    records.reserveInitialCapacity(recordsData.size());
+    for (auto& recordData : recordsData)
+        records.uncheckedAppend(fromCrossThreadRecordData(WTFMove(recordData)));
+    return records;
+}
+
+void WorkerCacheStorageConnection::doRetrieveRecords(uint64_t requestIdentifier, uint64_t cacheIdentifier)
+{
+    m_proxy.postTaskToLoader([this, protectedThis = makeRef(*this), requestIdentifier, cacheIdentifier](ScriptExecutionContext&) mutable {
+        ASSERT(isMainThread());
+        ASSERT(m_mainThreadConnection);
+
+        m_mainThreadConnection->retrieveRecords(cacheIdentifier, [this, protectedThis = WTFMove(protectedThis), requestIdentifier](Vector<Record>&& records) mutable {
+            m_proxy.postTaskForModeToWorkerGlobalScope([this, protectedThis = WTFMove(protectedThis), recordsData = recordsDataFromRecords(records), requestIdentifier](ScriptExecutionContext& context) mutable {
+                ASSERT_UNUSED(context, context.isWorkerGlobalScope());
+                updateRecords(requestIdentifier, recordsFromRecordsData(WTFMove(recordsData)));
+            }, m_taskMode);
+        });
+    });
+}
+
+void WorkerCacheStorageConnection::doBatchDeleteOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, const ResourceRequest& request, CacheQueryOptions&& options)
+{
+    m_proxy.postTaskToLoader([this, protectedThis = makeRef(*this), requestIdentifier, cacheIdentifier, request = request.isolatedCopy(), options = options.isolatedCopy()](ScriptExecutionContext&) mutable {
+        ASSERT(isMainThread());
+        ASSERT(m_mainThreadConnection);
+
+        m_mainThreadConnection->batchDeleteOperation(cacheIdentifier, request, WTFMove(options), [this, protectedThis = WTFMove(protectedThis), requestIdentifier](Vector<uint64_t>&& records, Error error) mutable {
+
+            m_proxy.postTaskForModeToWorkerGlobalScope([this, protectedThis = WTFMove(protectedThis), records = WTFMove(records), error, requestIdentifier](ScriptExecutionContext& context) mutable {
+                ASSERT_UNUSED(context, context.isWorkerGlobalScope());
+                deleteRecordsCompleted(requestIdentifier, WTFMove(records), error);
+            }, m_taskMode);
+        });
+    });
+}
+
+void WorkerCacheStorageConnection::doBatchPutOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, Vector<Record>&& records)
+{
+    m_proxy.postTaskToLoader([this, protectedThis = makeRef(*this), requestIdentifier, cacheIdentifier, recordsData = recordsDataFromRecords(records)](ScriptExecutionContext&) mutable {
+        ASSERT(isMainThread());
+        ASSERT(m_mainThreadConnection);
+
+        m_mainThreadConnection->batchPutOperation(cacheIdentifier, recordsFromRecordsData(WTFMove(recordsData)), [this, protectedThis = WTFMove(protectedThis), requestIdentifier](Vector<uint64_t>&& records, Error error) mutable {
+
+            m_proxy.postTaskForModeToWorkerGlobalScope([this, protectedThis = WTFMove(protectedThis), records = WTFMove(records), error, requestIdentifier](ScriptExecutionContext& context) mutable {
+                ASSERT_UNUSED(context, context.isWorkerGlobalScope());
+                putRecordsCompleted(requestIdentifier, WTFMove(records), error);
+            }, m_taskMode);
+        });
+    });
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h b/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h
new file mode 100644 (file)
index 0000000..9f48af2
--- /dev/null
@@ -0,0 +1,60 @@
+
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CacheStorageConnection.h"
+
+namespace WebCore {
+
+class WorkerGlobalScope;
+class WorkerLoaderProxy;
+
+class WorkerCacheStorageConnection final : public CacheStorageConnection {
+public:
+    static Ref<WorkerCacheStorageConnection> create(WorkerGlobalScope&);
+    ~WorkerCacheStorageConnection();
+
+private:
+    explicit WorkerCacheStorageConnection(WorkerGlobalScope&);
+
+    // WebCore::CacheStorageConnection
+    void doOpen(uint64_t requestIdentifier, const String& /* origin */, const String& /* cacheName */) final;
+    void doRemove(uint64_t requestIdentifier, uint64_t /* cacheIdentifier */) final;
+    void doRetrieveCaches(uint64_t requestIdentifier, const String& /* origin */) final;
+
+    void doRetrieveRecords(uint64_t requestIdentifier, uint64_t cacheIdentifier) final;
+    void doBatchDeleteOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, const WebCore::ResourceRequest&, WebCore::CacheQueryOptions&&) final;
+    void doBatchPutOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, Vector<Record>&&) final;
+
+    WorkerGlobalScope& m_scope;
+    WorkerLoaderProxy& m_proxy;
+    String m_taskMode;
+
+    RefPtr<CacheStorageConnection> m_mainThreadConnection;
+};
+
+} // namespace WebCore
index c539cde63b4b4d2771c69cff7d59b7f12585b819..c8e4fdc1f59630ca4fd5e5bba3541cc49a28c76d 100644 (file)
@@ -55,7 +55,7 @@ CacheStorage* WorkerGlobalScopeCaches::caches(WorkerGlobalScope& scope)
 CacheStorage* WorkerGlobalScopeCaches::caches() const
 {
     if (!m_caches)
-        m_caches = CacheStorage::create(m_scope, CacheStorageConnection::create());
+        m_caches = CacheStorage::create(m_scope, m_scope.cacheStorageConnection());
     return m_caches.get();
 }
 
index c21aac894e0c80d477391c1e9e1daa07620598e6..f56c4569df0977d034f3c69d12caca84e73dd9ae 100644 (file)
                41A1B01D1E54239E007F3769 /* JSDOMGuardedObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A1B01B1E542396007F3769 /* JSDOMGuardedObject.cpp */; };
                41A3D58E101C152D00316D07 /* DedicatedWorkerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */; };
                41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */; };
+               41A7D3521F438D16008988DE /* WorkerCacheStorageConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A7D34F1F438D10008988DE /* WorkerCacheStorageConnection.cpp */; };
+               41A7D3531F438D16008988DE /* WorkerCacheStorageConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A7D3501F438D10008988DE /* WorkerCacheStorageConnection.h */; };
                41ABE67B1D0580DB006D862D /* CrossOriginPreflightChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 41ABE67A1D0580D5006D862D /* CrossOriginPreflightChecker.h */; };
                41ABE67C1D0580E0006D862D /* CrossOriginPreflightChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41ABE6791D0580D5006D862D /* CrossOriginPreflightChecker.cpp */; };
                41AD753A1CEF6BD100A31486 /* FetchOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 41AD75391CEF6BCE00A31486 /* FetchOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41A48A9D1E8312EB00D2AC2D /* RTCPeerConnectionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCPeerConnectionState.h; sourceTree = "<group>"; };
                41A48AA71E84AEEC00D2AC2D /* RTCRtpParameters.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCRtpParameters.idl; sourceTree = "<group>"; };
                41A48AA81E84AF1D00D2AC2D /* RTCRtpParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCRtpParameters.h; sourceTree = "<group>"; };
+               41A7D34F1F438D10008988DE /* WorkerCacheStorageConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerCacheStorageConnection.cpp; sourceTree = "<group>"; };
+               41A7D3501F438D10008988DE /* WorkerCacheStorageConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerCacheStorageConnection.h; sourceTree = "<group>"; };
                41ABE6791D0580D5006D862D /* CrossOriginPreflightChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrossOriginPreflightChecker.cpp; sourceTree = "<group>"; };
                41ABE67A1D0580D5006D862D /* CrossOriginPreflightChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossOriginPreflightChecker.h; sourceTree = "<group>"; };
                41AD75391CEF6BCE00A31486 /* FetchOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchOptions.h; sourceTree = "<group>"; };
                                41FB278E1F34C28200795487 /* DOMWindowCaches.cpp */,
                                41FB278C1F34C28200795487 /* DOMWindowCaches.h */,
                                41380C2B1F343E2F00155FDA /* DOMWindowCaches.idl */,
+                               41A7D34F1F438D10008988DE /* WorkerCacheStorageConnection.cpp */,
+                               41A7D3501F438D10008988DE /* WorkerCacheStorageConnection.h */,
                                41FB278F1F34C28200795487 /* WorkerGlobalScopeCaches.cpp */,
                                41FB278D1F34C28200795487 /* WorkerGlobalScopeCaches.h */,
                                41380C2A1F343E2F00155FDA /* WorkerGlobalScopeCaches.idl */,
                                A14832C6187F668F00DA63A6 /* WKViewPrivate.h in Headers */,
                                379919971200DDF400EA041C /* WOFFFileFormat.h in Headers */,
                                2E4346460F546A8200B0F1BA /* Worker.h in Headers */,
+                               41A7D3531F438D16008988DE /* WorkerCacheStorageConnection.h in Headers */,
                                A52A68621DBB0F630083373F /* WorkerConsoleAgent.h in Headers */,
                                A55639D11C6F09E300806D8E /* WorkerConsoleClient.h in Headers */,
                                A52A68661DBD4B5D0083373F /* WorkerDebuggerAgent.h in Headers */,
                                E125F83D182411E700D84CD9 /* JSCryptoOperationData.cpp in Sources */,
                                7C9ACABF1F3CF1AF00F3AA09 /* JSCryptoRsaHashedKeyAlgorithm.cpp in Sources */,
                                7C9ACAC11F3CF1AF00F3AA09 /* JSCryptoRsaKeyAlgorithm.cpp in Sources */,
-                               E48284081F44594C00863AC3 /* RenderTreeUpdaterFirstLetter.cpp in Sources */,
                                BC46C1FC0C0DDC8F0020CFC3 /* JSCSSFontFaceRule.cpp in Sources */,
                                BC46C1FE0C0DDC8F0020CFC3 /* JSCSSImportRule.cpp in Sources */,
                                316FE0710E6CCBEE00BF6088 /* JSCSSKeyframeRule.cpp in Sources */,
                                93F19AD508245E59001E9ABC /* RenderTreeAsText.cpp in Sources */,
                                5824ABAA1AE849C8009074B7 /* RenderTreePosition.cpp in Sources */,
                                E461802B1C8A06D90026C02C /* RenderTreeUpdater.cpp in Sources */,
+                               E48284081F44594C00863AC3 /* RenderTreeUpdaterFirstLetter.cpp in Sources */,
                                E44614510CD68A3500FADA75 /* RenderVideo.cpp in Sources */,
                                BCEA4867097D93020094C9E4 /* RenderView.cpp in Sources */,
                                BE20507D18A458BF0080647E /* RenderVTTCue.cpp in Sources */,
                                A14832C5187F668300DA63A6 /* WKView.mm in Sources */,
                                379919961200DDF400EA041C /* WOFFFileFormat.cpp in Sources */,
                                2E4346450F546A8200B0F1BA /* Worker.cpp in Sources */,
+                               41A7D3521F438D16008988DE /* WorkerCacheStorageConnection.cpp in Sources */,
                                A52A68611DBB0F630083373F /* WorkerConsoleAgent.cpp in Sources */,
                                A55639D21C6F09E700806D8E /* WorkerConsoleClient.cpp in Sources */,
                                A52A68651DBD4B5D0083373F /* WorkerDebuggerAgent.cpp in Sources */,
index 7e1a83738d2397f24d724cd0126667fa604e18b8..b173723bd7f7a0ec547671ba01fd094f24b9f738 100644 (file)
@@ -35,28 +35,38 @@ namespace WebCore {
 
 struct FetchOptions {
     enum class Type { EmptyString, Audio, Font, Image, Script, Style, Track, Video };
-    Type type { Type::EmptyString };
-
     enum class Destination { EmptyString, Document, Sharedworker, Subresource, Unknown, Worker };
-    Destination destination { Destination::EmptyString };
-
     enum class Mode { Navigate, SameOrigin, NoCors, Cors };
-    Mode mode { Mode::NoCors };
-
     enum class Credentials { Omit, SameOrigin, Include };
-    Credentials credentials { Credentials::Omit };
-
     enum class Cache { Default, NoStore, Reload, NoCache, ForceCache, OnlyIfCached };
-    Cache cache { Cache::Default };
-
     enum class Redirect { Follow, Error, Manual };
-    Redirect redirect { Redirect::Follow };
 
-    ReferrerPolicy referrerPolicy { ReferrerPolicy::EmptyString };
+    FetchOptions() = default;
+    FetchOptions(Type, Destination, Mode, Credentials, Cache, Redirect, ReferrerPolicy, String&&, bool);
+    FetchOptions isolatedCopy() const { return { type, destination, mode, credentials, cache, redirect, referrerPolicy, integrity.isolatedCopy(), keepAlive }; }
 
+    Type type { Type::EmptyString };
+    Destination destination { Destination::EmptyString };
+    Mode mode { Mode::NoCors };
+    Credentials credentials { Credentials::Omit };
+    Cache cache { Cache::Default };
+    Redirect redirect { Redirect::Follow };
+    ReferrerPolicy referrerPolicy { ReferrerPolicy::EmptyString };
     String integrity;
-
     bool keepAlive { false };
 };
 
+inline FetchOptions::FetchOptions(Type type, Destination destination, Mode mode, Credentials credentials, Cache cache, Redirect redirect, ReferrerPolicy referrerPolicy, String&& integrity, bool keepAlive)
+    : type(type)
+    , destination(destination)
+    , mode(mode)
+    , credentials(credentials)
+    , cache(cache)
+    , redirect(redirect)
+    , referrerPolicy(referrerPolicy)
+    , integrity(WTFMove(integrity))
+    , keepAlive(keepAlive)
+{
+}
+
 } // namespace WebCore
index 180f88e69587e0a043fa6650b03a62014db9952a..d9ad59a25feb039921fd24c193231b2ce4f69a73 100644 (file)
@@ -386,4 +386,11 @@ Performance& WorkerGlobalScope::performance() const
     return *m_performance;
 }
 
+CacheStorageConnection& WorkerGlobalScope::cacheStorageConnection()
+{
+    if (!m_cacheStorageConnection)
+        m_cacheStorageConnection = WorkerCacheStorageConnection::create(*this);
+    return *m_cacheStorageConnection;
+}
+
 } // namespace WebCore
index c5b0d52ab4cacd61a2b99434f7783aeee5822393..0491d7c4fdd0567e1f27a21b48ee6f7556728f5e 100644 (file)
 #pragma once
 
 #include "Base64Utilities.h"
+#include "CacheStorageConnection.h"
 #include "EventTarget.h"
 #include "ScriptExecutionContext.h"
 #include "SessionID.h"
 #include "Supplementable.h"
 #include "URL.h"
+#include "WorkerCacheStorageConnection.h"
 #include "WorkerEventQueue.h"
 #include "WorkerScriptController.h"
 #include <inspector/ConsoleMessage.h>
@@ -66,6 +68,8 @@ public:
     void stopIndexedDatabase();
 #endif
 
+    CacheStorageConnection& cacheStorageConnection();
+
     WorkerScriptController* script() { return m_script.get(); }
     void clearScript() { m_script = nullptr; }
 
@@ -183,6 +187,7 @@ private:
     mutable RefPtr<Crypto> m_crypto;
 
     SessionID m_sessionID;
+    RefPtr<WorkerCacheStorageConnection> m_cacheStorageConnection;
 };
 
 } // namespace WebCore