Diff
Modified: trunk/LayoutTests/ChangeLog (221709 => 221710)
--- trunk/LayoutTests/ChangeLog 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/LayoutTests/ChangeLog 2017-09-07 00:03:13 UTC (rev 221710)
@@ -1,3 +1,14 @@
+2017-09-06 Youenn Fablet <[email protected]>
+
+ NetworkProcess Cache and Caches should be cleared when the last related WebProcess Cache or CacheStorage is destroyed
+ https://bugs.webkit.org/show_bug.cgi?id=176249
+
+ Reviewed by Alex Christensen.
+
+ * http/tests/cache-storage/cache-representation.https-expected.txt: Added.
+ * http/tests/cache-storage/cache-representation.https.html: Added.
+ * http/tests/cache-storage/resources/cache-persistency-iframe.html:
+
2017-09-06 Matt Lewis <[email protected]>
Marked media/video-main-content-allow-then-scroll.html as flaky on macOS and failing on iOS.
Modified: trunk/LayoutTests/http/tests/cache-storage/cache-origins.https.html (221709 => 221710)
--- trunk/LayoutTests/http/tests/cache-storage/cache-origins.https.html 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-origins.https.html 2017-09-07 00:03:13 UTC (rev 221710)
@@ -4,7 +4,6 @@
<title>Cache Storage: testing persistency of different origins</title>
<script src=""
<script src=""
-<script src=""
</head>
<body>
<script>
Added: trunk/LayoutTests/http/tests/cache-storage/cache-representation.https-expected.txt (0 => 221710)
--- trunk/LayoutTests/http/tests/cache-storage/cache-representation.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-representation.https-expected.txt 2017-09-07 00:03:13 UTC (rev 221710)
@@ -0,0 +1,12 @@
+
+
+PASS Cleaning existing caches
+PASS Create a cache storage and look at the representation
+PASS Look at the representation a second time after removing the iframe
+PASS Remove a cache and look at the representation a second time
+PASS Look at the representation a second time after reloading the iframe
+PASS A cache is created
+PASS A cache is persisting
+PASS A cache is going in remove bucket
+PASS A removed cache gets collected
+
Added: trunk/LayoutTests/http/tests/cache-storage/cache-representation.https.html (0 => 221710)
--- trunk/LayoutTests/http/tests/cache-storage/cache-representation.https.html (rev 0)
+++ trunk/LayoutTests/http/tests/cache-storage/cache-representation.https.html 2017-09-07 00:03:13 UTC (rev 221710)
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Cache Storage: testing persistency</title>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+ <div id="check"></div>
+ <script>
+ if (window.testRunner)
+ testRunner.setPrivateBrowsingEnabled(true);
+
+ function checkCaches(hasPersistent, hasRemoved, name, value) {
+ test(() => {
+ var results = JSON.parse(value);
+ var caches = results[0].caches;
+ assert_equals(!!caches["persistent"].length, hasPersistent, "persistent");
+ assert_equals(!!caches["removed"].length, hasRemoved, "removed");
+ }, name);
+ }
+
+ promise_test(test => {
+ return self.caches.keys().then(keys => {
+ var pending = [];
+ for (key of keys)
+ pending.push(self.caches.delete(keys[0]));
+ return Promise.all(pending);
+ });
+ }, "Cleaning existing caches");
+
+ promise_test(test => {
+ if (!window.internals)
+ return Promise.reject("Test requires internals");
+
+ return new Promise((resolve, reject) => {
+ window.addEventListener("message", test.step_func((event) => {
+ return internals.cacheStorageEngineRepresentation().then(value => {
+ checkCaches(true, false, "A cache is created", value);
+ resolve();
+ });
+ }));
+ check.innerHTML = "<iframe src=''></iframe>";
+ })
+ }, "Create a cache storage and look at the representation");
+
+ promise_test(test => {
+ if (!window.internals)
+ return Promise.reject("Test requires internals");
+
+ return new Promise((resolve, reject) => {
+ window.addEventListener("message", test.step_func((event) => {
+ return internals.cacheStorageEngineRepresentation().then(value => {
+ checkCaches(true, false, "A cache is persisting", value);
+ resolve();
+ });
+ }));
+ check.innerHTML = "<iframe src=''></iframe>";
+ })
+ }, "Look at the representation a second time after removing the iframe");
+
+ promise_test(test => {
+ if (!window.internals)
+ return Promise.reject("Test requires internals");
+
+ return new Promise((resolve, reject) => {
+ window.addEventListener("message", test.step_func((event) => {
+ return internals.cacheStorageEngineRepresentation().then(value => {
+ checkCaches(false, true, "A cache is going in remove bucket", value);
+ resolve();
+ });
+ }));
+ check.innerHTML = "<iframe src=''></iframe>";
+ })
+ }, "Remove a cache and look at the representation a second time");
+
+ promise_test(test => {
+ if (!window.internals)
+ return Promise.reject("Test requires internals");
+
+ return new Promise((resolve, reject) => {
+ window.addEventListener("message", test.step_func((event) => {
+ gc();
+ setTimeout(() => {
+ return internals.cacheStorageEngineRepresentation().then(value => {
+ checkCaches(false, false, "A removed cache gets collected", value);
+ resolve();
+ });
+ }, 0);
+ }));
+ check.innerHTML = "<iframe src=''></iframe>";
+ });
+ }, "Look at the representation a second time after reloading the iframe");
+
+ </script>
+</body>
+</html>
+
Modified: trunk/LayoutTests/http/tests/cache-storage/resources/cache-persistency-iframe.html (221709 => 221710)
--- trunk/LayoutTests/http/tests/cache-storage/resources/cache-persistency-iframe.html 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/LayoutTests/http/tests/cache-storage/resources/cache-persistency-iframe.html 2017-09-07 00:03:13 UTC (rev 221710)
@@ -2,6 +2,7 @@
<html>
<body>
<script>
+var cache;
function doTest()
{
if (window.location.hash === "#check") {
@@ -11,6 +12,16 @@
return;
}
+ if (window.location.hash === "#remove") {
+ self.caches.open("testCacheName").then(c => {
+ cache = c
+ self.caches.delete("testCacheName").then(() => {
+ window.parent.postMessage("removed", "*");
+ });
+ });
+ return;
+ }
+
var cacheName = "testCacheName";
if (window.location.hash.indexOf("#name=") === 0)
cacheName = window.location.hash.substring(6);
Modified: trunk/Source/WebCore/ChangeLog (221709 => 221710)
--- trunk/Source/WebCore/ChangeLog 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebCore/ChangeLog 2017-09-07 00:03:13 UTC (rev 221710)
@@ -1,3 +1,32 @@
+2017-09-06 Youenn Fablet <[email protected]>
+
+ NetworkProcess Cache and Caches should be cleared when the last related WebProcess Cache or CacheStorage is destroyed
+ https://bugs.webkit.org/show_bug.cgi?id=176249
+
+ Reviewed by Alex Christensen.
+
+ Test: http/tests/cache-storage/cache-representation.https.html
+
+ Each Cache construction/destruction is notified to the CacheStorageConnection
+ so that the WebKit2 engine can handle memory management accordingly.
+
+ Adding an internal API to grab the representation of an engine at any time.
+
+ * Modules/cache/Cache.cpp:
+ (WebCore::Cache::Cache):
+ (WebCore::Cache::~Cache):
+ * Modules/cache/CacheStorageConnection.h:
+ (WebCore::CacheStorageConnection::reference):
+ (WebCore::CacheStorageConnection::dereference):
+ * Modules/cache/WorkerCacheStorageConnection.cpp:
+ (WebCore::WorkerCacheStorageConnection::reference):
+ (WebCore::WorkerCacheStorageConnection::dereference):
+ * Modules/cache/WorkerCacheStorageConnection.h:
+ * testing/Internals.cpp:
+ (WebCore::Internals::cacheStorageEngineRepresentation):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2017-09-05 Matt Rajca <[email protected]>
Support new autoplay quirk for arbitrary user gestures.
Modified: trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h (221709 => 221710)
--- trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebCore/Modules/cache/CacheStorageConnection.h 2017-09-07 00:03:13 UTC (rev 221710)
@@ -45,8 +45,12 @@
void batchDeleteOperation(uint64_t cacheIdentifier, const ResourceRequest&, CacheQueryOptions&&, DOMCacheEngine::RecordIdentifiersCallback&&);
void batchPutOperation(uint64_t cacheIdentifier, Vector<DOMCacheEngine::Record>&&, DOMCacheEngine::RecordIdentifiersCallback&&);
+ virtual void reference(uint64_t /* cacheIdentifier */) { }
+ virtual void dereference(uint64_t /* cacheIdentifier */) { }
+
// Used only for testing purposes.
virtual void clearMemoryRepresentation(const String& /* origin */, DOMCacheEngine::CompletionCallback&& callback) { callback(DOMCacheEngine::Error::NotImplemented); }
+ virtual void engineRepresentation(WTF::Function<void(const String&)>&& callback) { callback(String { }); }
protected:
CacheStorageConnection() = default;
Modified: trunk/Source/WebCore/Modules/cache/DOMCache.cpp (221709 => 221710)
--- trunk/Source/WebCore/Modules/cache/DOMCache.cpp 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebCore/Modules/cache/DOMCache.cpp 2017-09-07 00:03:13 UTC (rev 221710)
@@ -47,10 +47,12 @@
, m_connection(WTFMove(connection))
{
suspendIfNeeded();
+ m_connection->reference(m_identifier);
}
DOMCache::~DOMCache()
{
+ m_connection->dereference(m_identifier);
}
void DOMCache::match(RequestInfo&& info, CacheQueryOptions&& options, Ref<DeferredPromise>&& promise)
Modified: trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp (221709 => 221710)
--- trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp 2017-09-07 00:03:13 UTC (rev 221710)
@@ -163,6 +163,26 @@
});
}
+void WorkerCacheStorageConnection::reference(uint64_t cacheIdentifier)
+{
+ m_proxy.postTaskToLoader([this, protectedThis = makeRef(*this), cacheIdentifier](ScriptExecutionContext&) {
+ ASSERT(isMainThread());
+ ASSERT(m_mainThreadConnection);
+
+ m_mainThreadConnection->reference(cacheIdentifier);
+ });
+}
+
+void WorkerCacheStorageConnection::dereference(uint64_t cacheIdentifier)
+{
+ m_proxy.postTaskToLoader([this, protectedThis = makeRef(*this), cacheIdentifier](ScriptExecutionContext&) {
+ ASSERT(isMainThread());
+ ASSERT(m_mainThreadConnection);
+
+ m_mainThreadConnection->dereference(cacheIdentifier);
+ });
+}
+
static inline Vector<CrossThreadRecordData> recordsDataFromRecords(const Vector<Record>& records)
{
Vector<CrossThreadRecordData> recordsData;
Modified: trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h (221709 => 221710)
--- trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.h 2017-09-07 00:03:13 UTC (rev 221710)
@@ -47,6 +47,10 @@
void doRetrieveCaches(uint64_t requestIdentifier, const String& origin, uint64_t updateCounter) final;
void doRetrieveRecords(uint64_t requestIdentifier, uint64_t cacheIdentifier, const URL&) final;
+
+ void reference(uint64_t cacheIdentifier) final;
+ void dereference(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<DOMCacheEngine::Record>&&) final;
Modified: trunk/Source/WebCore/testing/Internals.cpp (221709 => 221710)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-09-07 00:03:13 UTC (rev 221710)
@@ -4146,4 +4146,21 @@
m_cacheStorageConnection->clearMemoryRepresentation(document->securityOrigin().toString(), [](std::optional<DOMCacheEngine::Error>&&) { });
}
+void Internals::cacheStorageEngineRepresentation(DOMPromiseDeferred<IDLDOMString>&& promise)
+{
+ auto* document = contextDocument();
+ if (!document)
+ return;
+
+ if (!m_cacheStorageConnection) {
+ if (auto* page = contextDocument()->page())
+ m_cacheStorageConnection = page->cacheStorageProvider().createCacheStorageConnection(page->sessionID());
+ if (!m_cacheStorageConnection)
+ return;
+ }
+ m_cacheStorageConnection->engineRepresentation([promise = WTFMove(promise)](const String& result) mutable {
+ promise.resolve(result);
+ });
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/testing/Internals.h (221709 => 221710)
--- trunk/Source/WebCore/testing/Internals.h 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebCore/testing/Internals.h 2017-09-07 00:03:13 UTC (rev 221710)
@@ -600,6 +600,7 @@
String audioSessionCategory() const;
void clearCacheStorageMemoryRepresentation();
+ void cacheStorageEngineRepresentation(DOMPromiseDeferred<IDLDOMString>&&);
private:
explicit Internals(Document&);
Modified: trunk/Source/WebCore/testing/Internals.idl (221709 => 221710)
--- trunk/Source/WebCore/testing/Internals.idl 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebCore/testing/Internals.idl 2017-09-07 00:03:13 UTC (rev 221710)
@@ -545,6 +545,7 @@
[Conditional=MEDIA_STREAM] void simulateMediaStreamTrackCaptureSourceFailure(MediaStreamTrack track);
void clearCacheStorageMemoryRepresentation();
+ Promise<DOMString> cacheStorageEngineRepresentation();
DOMString audioSessionCategory();
};
Modified: trunk/Source/WebKit/ChangeLog (221709 => 221710)
--- trunk/Source/WebKit/ChangeLog 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/ChangeLog 2017-09-07 00:03:13 UTC (rev 221710)
@@ -1,3 +1,60 @@
+2017-09-06 Youenn Fablet <[email protected]>
+
+ NetworkProcess Cache and Caches should be cleared when the last related WebProcess Cache or CacheStorage is destroyed
+ https://bugs.webkit.org/show_bug.cgi?id=176249
+
+ Reviewed by Alex Christensen.
+
+ CacheStorageEngineConnection will store the number of Caches references for its related WebProcess.
+ For a new reference, CacheStorageEngineConnection will notify its engine to lock the related Cache.
+ When the last reference is gone, CacheStorageEngineConnection will ask the engine to release the lock.
+
+ CacheStorageEngine will keep locks as a counter for each Cache object.
+ When the counter goes to zero, the engine asks the Cache to dispose itself.
+ Disposal is done by its parent Caches as only Caches knows whether the Cache is persistent or has been removed.
+
+ The Caches will remove the Cache from memory.
+ For removed caches, all information will be lost.
+ For caches that are not removed, they will keep their identifiers but all in-memory record information will be discarded.
+ If there is a need to reopen the Cache, it will need to read its information from the filesystem.
+ If the Caches has no longer any active Cache object, it will ask the engine to release itself.
+
+ WebProcess crashing is handled correctly as the CacheStorageEngineConnection will release its locks at destruction
+ time of the connection to the web process.
+
+ Adding the possiblity to grab an engine representation for test purposes.
+
+ * NetworkProcess/cache/CacheStorageEngine.cpp:
+ (WebKit::CacheStorage::Engine::readCachesFromDisk):
+ (WebKit::CacheStorage::Engine::removeCaches):
+ (WebKit::CacheStorage::Engine::lock):
+ (WebKit::CacheStorage::Engine::unlock):
+ * NetworkProcess/cache/CacheStorageEngine.h:
+ * NetworkProcess/cache/CacheStorageEngineCache.cpp:
+ (WebKit::CacheStorage::Cache::Cache):
+ (WebKit::CacheStorage::Cache::dispose):
+ (WebKit::CacheStorage::Cache::clearMemoryRepresentation):
+ * NetworkProcess/cache/CacheStorageEngineCache.h:
+ (WebKit::CacheStorage::Cache::isActive const):
+ * NetworkProcess/cache/CacheStorageEngineCaches.cpp:
+ (WebKit::CacheStorage::Caches::Caches):
+ (WebKit::CacheStorage::Caches::open):
+ (WebKit::CacheStorage::Caches::dispose):
+ (WebKit::CacheStorage::Caches::readCachesFromDisk):
+ (WebKit::CacheStorage::Caches::clearMemoryRepresentation):
+ * NetworkProcess/cache/CacheStorageEngineCaches.h:
+ (WebKit::CacheStorage::Caches::create):
+ * NetworkProcess/cache/CacheStorageEngineConnection.cpp:
+ (WebKit::CacheStorageEngineConnection::~CacheStorageEngineConnection):
+ (WebKit::CacheStorageEngineConnection::reference):
+ (WebKit::CacheStorageEngineConnection::dereference):
+ * NetworkProcess/cache/CacheStorageEngineConnection.h:
+ * NetworkProcess/cache/CacheStorageEngineConnection.messages.in:
+ * WebProcess/Cache/WebCacheStorageConnection.cpp:
+ (WebKit::WebCacheStorageConnection::reference):
+ (WebKit::WebCacheStorageConnection::dereference):
+ * WebProcess/Cache/WebCacheStorageConnection.h:
+
2017-09-06 Alex Christensen <[email protected]>
Add WKUIDelegatePrivate equivalent of WKPageUIClient's pinnedStateDidChange
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp 2017-09-07 00:03:13 UTC (rev 221710)
@@ -32,6 +32,7 @@
#include <pal/SessionID.h>
#include <wtf/MainThread.h>
#include <wtf/NeverDestroyed.h>
+#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringHash.h>
using namespace WebCore::DOMCacheEngine;
@@ -190,7 +191,7 @@
{
initialize([this, origin, callback = WTFMove(callback)](std::optional<Error>&& error) mutable {
auto& caches = m_caches.ensure(origin, [&origin, this] {
- return Caches::create(*this, origin);
+ return Caches::create(*this, String { origin });
}).iterator->value;
if (caches->isInitialized()) {
@@ -289,6 +290,12 @@
});
}
+void Engine::removeCaches(const String& origin)
+{
+ ASSERT(m_caches.contains(origin));
+ m_caches.remove(origin);
+}
+
void Engine::clearMemoryRepresentation(const String& origin)
{
readCachesFromDisk(origin, [](CachesOrError&& result) {
@@ -298,6 +305,54 @@
});
}
+void Engine::lock(uint64_t cacheIdentifier)
+{
+ auto& counter = m_cacheLocks.ensure(cacheIdentifier, []() {
+ return 0;
+ }).iterator->value;
+
+ ++counter;
+}
+
+void Engine::unlock(uint64_t cacheIdentifier)
+{
+ auto lockCount = m_cacheLocks.find(cacheIdentifier);
+ ASSERT(lockCount != m_cacheLocks.end());
+ if (lockCount == m_cacheLocks.end())
+ return;
+
+ ASSERT(lockCount->value);
+ if (--lockCount->value)
+ return;
+
+ readCache(cacheIdentifier, [this](CacheOrError&& result) mutable {
+ if (!result.hasValue())
+ return;
+
+ result.value().get().dispose();
+ });
+}
+
+String Engine::representation()
+{
+ bool isFirst = true;
+ StringBuilder builder;
+ builder.append("[");
+ for (auto& keyValue : m_caches) {
+ if (!isFirst)
+ builder.append(",");
+ isFirst = false;
+
+ builder.append("\n{ \"origin\" : \"");
+ builder.append(keyValue.key);
+ builder.append("\", \"caches\" : ");
+ keyValue.value->appendRepresentation(builder);
+ builder.append("}");
+ }
+ builder.append("\n]");
+ return builder.toString();
+}
+
} // namespace CacheStorage
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h 2017-09-07 00:03:13 UTC (rev 221710)
@@ -43,6 +43,9 @@
namespace CacheStorage {
+using CacheIdentifier = uint64_t;
+using LockCount = uint64_t;
+
class Engine : public ThreadSafeRefCounted<Engine> {
public:
~Engine();
@@ -61,6 +64,9 @@
void putRecords(uint64_t cacheIdentifier, Vector<WebCore::DOMCacheEngine::Record>&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
void deleteMatchingRecords(uint64_t cacheIdentifier, WebCore::ResourceRequest&&, WebCore::CacheQueryOptions&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
+ void lock(uint64_t cacheIdentifier);
+ void unlock(uint64_t cacheIdentifier);
+
void writeFile(const String& filename, NetworkCache::Data&&, WebCore::DOMCacheEngine::CompletionCallback&&);
void readFile(const String& filename, WTF::Function<void(const NetworkCache::Data&, int error)>&&);
void removeFile(const String& filename);
@@ -69,7 +75,10 @@
const NetworkCache::Salt& salt() const { return m_salt.value(); }
uint64_t nextCacheIdentifier() { return ++m_nextCacheIdentifier; }
+ void removeCaches(const String& origin);
+
void clearMemoryRepresentation(const String& origin);
+ String representation();
private:
static Engine& defaultEngine();
@@ -92,6 +101,7 @@
String m_rootPath;
RefPtr<WorkQueue> m_ioQueue;
std::optional<NetworkCache::Salt> m_salt;
+ HashMap<CacheIdentifier, LockCount> m_cacheLocks;
};
} // namespace CacheStorage
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.cpp (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.cpp 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.cpp 2017-09-07 00:03:13 UTC (rev 221710)
@@ -26,6 +26,7 @@
#include "config.h"
#include "CacheStorageEngine.h"
+#include "CacheStorageEngineCaches.h"
#include "NetworkCacheIOChannel.h"
#include "NetworkCacheKey.h"
#include "NetworkProcess.h"
@@ -73,6 +74,18 @@
{
}
+void Cache::dispose()
+{
+ m_caches.dispose(*this);
+}
+
+void Cache::clearMemoryRepresentation()
+{
+ m_records = { };
+ m_nextRecordIdentifier = 0;
+ m_state = State::Uninitialized;
+}
+
void Cache::open(CompletionCallback&& callback)
{
if (m_state == State::Open) {
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.h (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.h 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.h 2017-09-07 00:03:13 UTC (rev 221710)
@@ -44,6 +44,7 @@
uint64_t identifier() const { return m_identifier; }
const String& name() const { return m_name; }
+ bool isActive() const { return m_state != State::Uninitialized; }
Vector<WebCore::DOMCacheEngine::Record> retrieveRecords(const WebCore::URL&) const;
WebCore::DOMCacheEngine::CacheInfo info() const { return { m_identifier, m_name }; }
@@ -51,6 +52,9 @@
void put(Vector<WebCore::DOMCacheEngine::Record>&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
void remove(WebCore::ResourceRequest&&, WebCore::CacheQueryOptions&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
+ void dispose();
+ void clearMemoryRepresentation();
+
private:
Vector<WebCore::DOMCacheEngine::Record>* recordsFromURL(const WebCore::URL&);
const Vector<WebCore::DOMCacheEngine::Record>* recordsFromURL(const WebCore::URL&) const;
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp 2017-09-07 00:03:13 UTC (rev 221710)
@@ -50,9 +50,10 @@
return WebCore::pathByAppendingComponent(cachesRootPath, ASCIILiteral("cacheslist"));
}
-Caches::Caches(Engine& engine, const String& origin)
+Caches::Caches(Engine& engine, String&& origin)
: m_engine(&engine)
- , m_rootPath(cachesRootPath(engine, origin))
+ , m_origin(WTFMove(origin))
+ , m_rootPath(cachesRootPath(engine, m_origin))
{
}
@@ -163,6 +164,20 @@
});
}
+void Caches::dispose(Cache& cache)
+{
+ auto position = m_removedCaches.findMatching([&](const auto& item) { return item.identifier() == cache.identifier(); });
+ if (position != notFound) {
+ m_removedCaches.remove(position);
+ return;
+ }
+ ASSERT(m_caches.findMatching([&](const auto& item) { return item.identifier() == cache.identifier(); }) != notFound);
+ cache.clearMemoryRepresentation();
+
+ if (m_caches.findMatching([](const auto& item) { return item.isActive(); }) == notFound)
+ clearMemoryRepresentation();
+}
+
static inline Data encodeCacheNames(const Vector<Cache>& caches)
{
WTF::Persistence::Encoder encoder;
@@ -260,6 +275,8 @@
m_caches.clear();
m_isInitialized = false;
m_storage = nullptr;
+ if (m_engine)
+ m_engine->removeCaches(m_origin);
}
bool Caches::isDirty(uint64_t updateCounter) const
@@ -279,6 +296,34 @@
return { WTFMove(cacheInfos), m_updateCounter };
}
+void Caches::appendRepresentation(StringBuilder& builder) const
+{
+ builder.append("{ \"persistent\": [");
+
+ bool isFirst = true;
+ for (auto& cache : m_caches) {
+ if (!isFirst)
+ builder.append(", ");
+ isFirst = false;
+ builder.append("\"");
+ builder.append(cache.name());
+ builder.append("\"");
+ }
+
+ builder.append("], \"removed\": [");
+
+ isFirst = true;
+ for (auto& cache : m_removedCaches) {
+ if (!isFirst)
+ builder.append(", ");
+ isFirst = false;
+ builder.append("\"");
+ builder.append(cache.name());
+ builder.append("\"");
+ }
+ builder.append("]}\n");
+}
+
} // namespace CacheStorage
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h 2017-09-07 00:03:13 UTC (rev 221710)
@@ -36,12 +36,13 @@
class Caches : public RefCounted<Caches> {
public:
- static Ref<Caches> create(Engine& engine, const String& origin) { return adoptRef(*new Caches { engine, origin }); }
+ static Ref<Caches> create(Engine& engine, String&& origin) { return adoptRef(*new Caches { engine, WTFMove(origin) }); }
void initialize(WebCore::DOMCacheEngine::CompletionCallback&&);
void open(const String& name, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
void remove(uint64_t identifier, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
void clearMemoryRepresentation();
+ void dispose(Cache&);
void detach();
@@ -49,9 +50,10 @@
WebCore::DOMCacheEngine::CacheInfos cacheInfos(uint64_t updateCounter) const;
Cache* find(uint64_t identifier);
+ void appendRepresentation(StringBuilder&) const;
private:
- Caches(Engine&, const String& rootPath);
+ Caches(Engine&, String&& origin);
void readCachesFromDisk(WTF::Function<void(Expected<Vector<Cache>, WebCore::DOMCacheEngine::Error>&&)>&&);
void writeCachesToDisk(WebCore::DOMCacheEngine::CompletionCallback&&);
@@ -67,6 +69,7 @@
bool m_isInitialized { false };
Engine* m_engine { nullptr };
uint64_t m_updateCounter { 0 };
+ String m_origin;
String m_rootPath;
Vector<Cache> m_caches;
Vector<Cache> m_removedCaches;
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.cpp 2017-09-07 00:03:13 UTC (rev 221710)
@@ -42,6 +42,17 @@
{
}
+CacheStorageEngineConnection::~CacheStorageEngineConnection()
+{
+ for (auto& keyValue : m_cachesLocks) {
+ auto& sessionID = keyValue.key;
+ for (auto& references : keyValue.value) {
+ ASSERT(references.value);
+ Engine::from(sessionID).unlock(references.key);
+ }
+ }
+}
+
void CacheStorageEngineConnection::open(PAL::SessionID sessionID, uint64_t requestIdentifier, const String& origin, const String& cacheName)
{
Engine::from(sessionID).open(origin, cacheName, [protectedThis = makeRef(*this), this, sessionID, requestIdentifier](const CacheIdentifierOrError& result) {
@@ -63,11 +74,6 @@
});
}
-void CacheStorageEngineConnection::clearMemoryRepresentation(PAL::SessionID sessionID, const String& origin)
-{
- Engine::from(sessionID).clearMemoryRepresentation(origin);
-}
-
void CacheStorageEngineConnection::retrieveRecords(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::URL&& url)
{
Engine::from(sessionID).retrieveRecords(cacheIdentifier, WTFMove(url), [protectedThis = makeRef(*this), this, sessionID, requestIdentifier](RecordsOrError&& result) {
@@ -89,4 +95,43 @@
});
}
+void CacheStorageEngineConnection::reference(PAL::SessionID sessionID, uint64_t cacheIdentifier)
+{
+ auto& references = m_cachesLocks.ensure(sessionID, []() {
+ return HashMap<CacheIdentifier, LockCount> { };
+ }).iterator->value;
+ auto& counter = references.ensure(cacheIdentifier, [this]() {
+ return 0;
+ }).iterator->value;
+ if (!counter++)
+ Engine::from(sessionID).lock(cacheIdentifier);
}
+
+void CacheStorageEngineConnection::dereference(PAL::SessionID sessionID, uint64_t cacheIdentifier)
+{
+ ASSERT(m_cachesLocks.contains(sessionID));
+ auto& references = m_cachesLocks.ensure(sessionID, []() {
+ return HashMap<CacheIdentifier, LockCount> { };
+ }).iterator->value;
+
+ auto referenceResult = references.find(cacheIdentifier);
+ ASSERT(referenceResult != references.end());
+ if (referenceResult == references.end())
+ return;
+
+ ASSERT(referenceResult->value);
+ if (!--referenceResult->value)
+ Engine::from(sessionID).unlock(cacheIdentifier);
+}
+
+void CacheStorageEngineConnection::clearMemoryRepresentation(PAL::SessionID sessionID, const String& origin)
+{
+ Engine::from(sessionID).clearMemoryRepresentation(origin);
+}
+
+void CacheStorageEngineConnection::engineRepresentation(PAL::SessionID sessionID, uint64_t requestIdentifier)
+{
+ m_connection.connection().send(Messages::WebCacheStorageConnection::EngineRepresentationCompleted(requestIdentifier, Engine::from(sessionID).representation()), sessionID.sessionID());
+}
+
+}
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.h 2017-09-07 00:03:13 UTC (rev 221710)
@@ -44,7 +44,7 @@
class CacheStorageEngineConnection : public RefCounted<CacheStorageEngineConnection> {
public:
static Ref<CacheStorageEngineConnection> create(NetworkConnectionToWebProcess& connection) { return adoptRef(*new CacheStorageEngineConnection(connection)); }
-
+ ~CacheStorageEngineConnection();
void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
private:
@@ -54,13 +54,18 @@
void remove(PAL::SessionID, uint64_t removeRequestIdentifier, uint64_t cacheIdentifier);
void caches(PAL::SessionID, uint64_t retrieveCachesIdentifier, const String& origin, uint64_t updateCounter);
- void clearMemoryRepresentation(PAL::SessionID, const String& origin);
-
void retrieveRecords(PAL::SessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::URL&&);
void deleteMatchingRecords(PAL::SessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::ResourceRequest&&, WebCore::CacheQueryOptions&&);
void putRecords(PAL::SessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, Vector<WebCore::DOMCacheEngine::Record>&&);
+ void reference(PAL::SessionID, uint64_t cacheIdentifier);
+ void dereference(PAL::SessionID, uint64_t cacheIdentifier);
+
+ void clearMemoryRepresentation(PAL::SessionID, const String& origin);
+ void engineRepresentation(PAL::SessionID, uint64_t requestIdentifier);
+
NetworkConnectionToWebProcess& m_connection;
+ HashMap<PAL::SessionID, HashMap<CacheStorage::CacheIdentifier, CacheStorage::LockCount>> m_cachesLocks;
};
}
Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.messages.in (221709 => 221710)
--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.messages.in 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineConnection.messages.in 2017-09-07 00:03:13 UTC (rev 221710)
@@ -21,11 +21,15 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
messages -> CacheStorageEngineConnection {
+ Reference(PAL::SessionID sessionID, uint64_t cacheIdentifier);
+ Dereference(PAL::SessionID sessionID, uint64_t cacheIdentifier);
+
Open(PAL::SessionID sessionID, uint64_t requestIdentifier, String origin, String cacheName);
Remove(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier);
Caches(PAL::SessionID sessionID, uint64_t requestIdentifier, String origin, uint64_t updateCounter);
ClearMemoryRepresentation(PAL::SessionID sessionID, String origin);
+ EngineRepresentation(PAL::SessionID sessionID, uint64_t requestIdentifier);
RetrieveRecords(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::URL url);
DeleteMatchingRecords(PAL::SessionID sessionID, uint64_t requestIdentifier, uint64_t cacheIdentifier, WebCore::ResourceRequest request, struct WebCore::CacheQueryOptions options);
Modified: trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp (221709 => 221710)
--- trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.cpp 2017-09-07 00:03:13 UTC (rev 221710)
@@ -86,12 +86,16 @@
connection().send(Messages::CacheStorageEngineConnection::PutRecords(m_sessionID, requestIdentifier, cacheIdentifier, records), 0);
}
-void WebCacheStorageConnection::clearMemoryRepresentation(const String& origin, CompletionCallback&& callback)
+void WebCacheStorageConnection::reference(uint64_t cacheIdentifier)
{
- connection().send(Messages::CacheStorageEngineConnection::ClearMemoryRepresentation(m_sessionID, origin), 0);
- callback(std::nullopt);
+ connection().send(Messages::CacheStorageEngineConnection::Reference(m_sessionID, cacheIdentifier), 0);
}
+void WebCacheStorageConnection::dereference(uint64_t cacheIdentifier)
+{
+ connection().send(Messages::CacheStorageEngineConnection::Dereference(m_sessionID, cacheIdentifier), 0);
+}
+
void WebCacheStorageConnection::openCompleted(uint64_t requestIdentifier, const CacheIdentifierOrError& result)
{
CacheStorageConnection::openCompleted(requestIdentifier, result);
@@ -122,4 +126,23 @@
CacheStorageConnection::putRecordsCompleted(requestIdentifier, WTFMove(result));
}
+void WebCacheStorageConnection::clearMemoryRepresentation(const String& origin, CompletionCallback&& callback)
+{
+ connection().send(Messages::CacheStorageEngineConnection::ClearMemoryRepresentation(m_sessionID, origin), 0);
+ callback(std::nullopt);
}
+
+void WebCacheStorageConnection::engineRepresentation(WTF::Function<void(const String&)>&& callback)
+{
+ uint64_t requestIdentifier = ++m_engineRepresentationNextIdentifier;
+ m_engineRepresentationCallbacks.set(requestIdentifier, WTFMove(callback));
+ connection().send(Messages::CacheStorageEngineConnection::EngineRepresentation(m_sessionID, requestIdentifier), 0);
+}
+
+void WebCacheStorageConnection::engineRepresentationCompleted(uint64_t requestIdentifier, const String& result)
+{
+ if (auto callback = m_engineRepresentationCallbacks.take(requestIdentifier))
+ callback(result);
+}
+
+}
Modified: trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h (221709 => 221710)
--- trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.h 2017-09-07 00:03:13 UTC (rev 221710)
@@ -60,7 +60,11 @@
void doBatchDeleteOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, const WebCore::ResourceRequest&, WebCore::CacheQueryOptions&&) final;
void doBatchPutOperation(uint64_t requestIdentifier, uint64_t cacheIdentifier, Vector<WebCore::DOMCacheEngine::Record>&&) final;
+ void reference(uint64_t cacheIdentifier) final;
+ void dereference(uint64_t cacheIdentifier) final;
+
void clearMemoryRepresentation(const String& origin, WebCore::DOMCacheEngine::CompletionCallback&&) final;
+ void engineRepresentation(WTF::Function<void(const String&)>&&) final;
void openCompleted(uint64_t requestIdentifier, const WebCore::DOMCacheEngine::CacheIdentifierOrError&);
void removeCompleted(uint64_t requestIdentifier, const WebCore::DOMCacheEngine::CacheIdentifierOrError&);
@@ -70,8 +74,12 @@
void deleteRecordsCompleted(uint64_t requestIdentifier, WebCore::DOMCacheEngine::RecordIdentifiersOrError&&);
void putRecordsCompleted(uint64_t requestIdentifier, WebCore::DOMCacheEngine::RecordIdentifiersOrError&&);
+ void engineRepresentationCompleted(uint64_t requestIdentifier, const String& representation);
+
WebCacheStorageProvider& m_provider;
PAL::SessionID m_sessionID;
+ uint64_t m_engineRepresentationNextIdentifier { 0 };
+ HashMap<uint64_t, WTF::Function<void(const String&)>> m_engineRepresentationCallbacks;
};
}
Modified: trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.messages.in (221709 => 221710)
--- trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.messages.in 2017-09-07 00:02:27 UTC (rev 221709)
+++ trunk/Source/WebKit/WebProcess/Cache/WebCacheStorageConnection.messages.in 2017-09-07 00:03:13 UTC (rev 221710)
@@ -28,4 +28,6 @@
UpdateRecords(uint64_t requestIdentifier, WebCore::DOMCacheEngine::RecordsOrError result);
DeleteRecordsCompleted(uint64_t requestIdentifier, WebCore::DOMCacheEngine::RecordIdentifiersOrError result);
PutRecordsCompleted(uint64_t requestIdentifier, WebCore::DOMCacheEngine::RecordIdentifiersOrError result);
+
+ EngineRepresentationCompleted(uint64_t requestIdentifier, String representation);
}