Title: [220267] trunk/Source/WebKit
Revision
220267
Author
[email protected]
Date
2017-08-04 06:25:02 -0700 (Fri, 04 Aug 2017)

Log Message

Network cache should be usable as non-singleton
https://bugs.webkit.org/show_bug.cgi?id=175139

Reviewed by Sam Weinig.

We might want to use it as a non-singleton in the future (for example as a backend for the cache API).

This patch makes NetworkCache::Cache and NetworkCache::Storage refcounted objects and takes
care to ref them properly during asynchronous operations.

The patch doesn't actually create any non-shared instances, it just adds the capability.

* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::storeDerivedDataToCache):
* NetworkProcess/NetworkProcess.cpp:
(WebKit::fetchDiskCacheEntries):
(WebKit::clearDiskCacheEntries):
(WebKit::NetworkProcess::setCacheModel):
* NetworkProcess/NetworkProcess.h:
(WebKit::NetworkProcess::cache):

    Move the shared cache instance to the network process singleton.

* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::NetworkResourceLoader):

    Include shared cache as a reffed member for non-ephemeral instances.

(WebKit::NetworkResourceLoader::canUseCache const):
(WebKit::NetworkResourceLoader::retrieveCacheEntry):
(WebKit::NetworkResourceLoader::abort):
(WebKit::NetworkResourceLoader::didReceiveResponse):
(WebKit::NetworkResourceLoader::willSendRedirectedRequest):
(WebKit::NetworkResourceLoader::tryStoreAsCacheEntry):
(WebKit::NetworkResourceLoader::didRetrieveCacheEntry):
* NetworkProcess/NetworkResourceLoader.h:
* NetworkProcess/cache/NetworkCache.cpp:
(WebKit::NetworkCache::Cache::open):

    Open now returns null if it fails.
    Add RegisterNotify option to set up notify trigger for the shared instance.

(WebKit::NetworkCache::Cache::Cache):
(WebKit::NetworkCache::Cache::~Cache):

    Add destructor.

(WebKit::NetworkCache::dumpFileChanged):
(WebKit::NetworkCache::Cache::setCapacity):
(WebKit::NetworkCache::Cache::retrieve):

    Protect the cache instance during asynchronous operations.

(WebKit::NetworkCache::Cache::store):
(WebKit::NetworkCache::Cache::storeRedirect):
(WebKit::NetworkCache::Cache::remove):
(WebKit::NetworkCache::Cache::traverse):
(WebKit::NetworkCache::Cache::dumpContentsToFile):
(WebKit::NetworkCache::Cache::clear):
(WebKit::NetworkCache::Cache::recordsPath const):
(WebKit::NetworkCache::Cache::retrieveData):
(WebKit::NetworkCache::Cache::storeData):
(WebKit::NetworkCache::singleton): Deleted.
(WebKit::NetworkCache::Cache::initialize): Deleted.
* NetworkProcess/cache/NetworkCache.h:
(WebKit::NetworkCache::Cache::canUseSharedMemoryForBodyData const):
(WebKit::NetworkCache::Cache::isEnabled const): Deleted.

    Remove isEnabled() state as a cache object now always represents an enabled cache.

* NetworkProcess/cache/NetworkCacheEntry.cpp:
(WebKit::NetworkCache::Entry::initializeShareableResourceHandleFromStorageRecord const):
* NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
(WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):
(WebKit::NetworkCache::SpeculativeLoad::didReceiveResponse):
(WebKit::NetworkCache::SpeculativeLoad::didFinishLoading):
* NetworkProcess/cache/NetworkCacheStatistics.cpp:
(WebKit::NetworkCache::Statistics::initialize):
(WebKit::NetworkCache::Statistics::shrinkIfNeeded):
* NetworkProcess/cache/NetworkCacheStorage.cpp:
(WebKit::NetworkCache::Storage::ReadOperation::ReadOperation):
(WebKit::NetworkCache::Storage::WriteOperation::WriteOperation):
(WebKit::NetworkCache::Storage::TraverseOperation::TraverseOperation):

    Operations now ref the storage. They are already deleted in the main thread so
    proper destruction is taken care of.

(WebKit::NetworkCache::Storage::open):
(WebKit::NetworkCache::Storage::~Storage):
(WebKit::NetworkCache::Storage::synchronize):

    This and other asynchronous methods now protect the Storage instance.

(WebKit::NetworkCache::Storage::remove):
(WebKit::NetworkCache::Storage::retrieve):
(WebKit::NetworkCache::Storage::store):
(WebKit::NetworkCache::Storage::traverse):
(WebKit::NetworkCache::Storage::clear):
(WebKit::NetworkCache::Storage::shrink):
(WebKit::NetworkCache::Storage::deleteOldVersions):
* NetworkProcess/cache/NetworkCacheStorage.h:
* NetworkProcess/cocoa/NetworkProcessCocoa.mm:
(WebKit::NetworkProcess::platformInitializeNetworkProcessCocoa):
(WebKit::NetworkProcess::clearDiskCache):
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
* NetworkProcess/soup/NetworkProcessSoup.cpp:
(WebKit::NetworkProcess::platformInitializeNetworkProcess):
(WebKit::NetworkProcess::clearDiskCache):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (220266 => 220267)


--- trunk/Source/WebKit/ChangeLog	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/ChangeLog	2017-08-04 13:25:02 UTC (rev 220267)
@@ -1,3 +1,115 @@
+2017-08-04  Antti Koivisto  <[email protected]>
+
+        Network cache should be usable as non-singleton
+        https://bugs.webkit.org/show_bug.cgi?id=175139
+
+        Reviewed by Sam Weinig.
+
+        We might want to use it as a non-singleton in the future (for example as a backend for the cache API).
+
+        This patch makes NetworkCache::Cache and NetworkCache::Storage refcounted objects and takes
+        care to ref them properly during asynchronous operations.
+
+        The patch doesn't actually create any non-shared instances, it just adds the capability.
+
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        (WebKit::NetworkConnectionToWebProcess::storeDerivedDataToCache):
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::fetchDiskCacheEntries):
+        (WebKit::clearDiskCacheEntries):
+        (WebKit::NetworkProcess::setCacheModel):
+        * NetworkProcess/NetworkProcess.h:
+        (WebKit::NetworkProcess::cache):
+
+            Move the shared cache instance to the network process singleton.
+
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::NetworkResourceLoader):
+
+            Include shared cache as a reffed member for non-ephemeral instances.
+
+        (WebKit::NetworkResourceLoader::canUseCache const):
+        (WebKit::NetworkResourceLoader::retrieveCacheEntry):
+        (WebKit::NetworkResourceLoader::abort):
+        (WebKit::NetworkResourceLoader::didReceiveResponse):
+        (WebKit::NetworkResourceLoader::willSendRedirectedRequest):
+        (WebKit::NetworkResourceLoader::tryStoreAsCacheEntry):
+        (WebKit::NetworkResourceLoader::didRetrieveCacheEntry):
+        * NetworkProcess/NetworkResourceLoader.h:
+        * NetworkProcess/cache/NetworkCache.cpp:
+        (WebKit::NetworkCache::Cache::open):
+
+            Open now returns null if it fails.
+            Add RegisterNotify option to set up notify trigger for the shared instance.
+
+        (WebKit::NetworkCache::Cache::Cache):
+        (WebKit::NetworkCache::Cache::~Cache):
+
+            Add destructor.
+
+        (WebKit::NetworkCache::dumpFileChanged):
+        (WebKit::NetworkCache::Cache::setCapacity):
+        (WebKit::NetworkCache::Cache::retrieve):
+
+            Protect the cache instance during asynchronous operations.
+
+        (WebKit::NetworkCache::Cache::store):
+        (WebKit::NetworkCache::Cache::storeRedirect):
+        (WebKit::NetworkCache::Cache::remove):
+        (WebKit::NetworkCache::Cache::traverse):
+        (WebKit::NetworkCache::Cache::dumpContentsToFile):
+        (WebKit::NetworkCache::Cache::clear):
+        (WebKit::NetworkCache::Cache::recordsPath const):
+        (WebKit::NetworkCache::Cache::retrieveData):
+        (WebKit::NetworkCache::Cache::storeData):
+        (WebKit::NetworkCache::singleton): Deleted.
+        (WebKit::NetworkCache::Cache::initialize): Deleted.
+        * NetworkProcess/cache/NetworkCache.h:
+        (WebKit::NetworkCache::Cache::canUseSharedMemoryForBodyData const):
+        (WebKit::NetworkCache::Cache::isEnabled const): Deleted.
+
+            Remove isEnabled() state as a cache object now always represents an enabled cache.
+
+        * NetworkProcess/cache/NetworkCacheEntry.cpp:
+        (WebKit::NetworkCache::Entry::initializeShareableResourceHandleFromStorageRecord const):
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
+        (WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):
+        (WebKit::NetworkCache::SpeculativeLoad::didReceiveResponse):
+        (WebKit::NetworkCache::SpeculativeLoad::didFinishLoading):
+        * NetworkProcess/cache/NetworkCacheStatistics.cpp:
+        (WebKit::NetworkCache::Statistics::initialize):
+        (WebKit::NetworkCache::Statistics::shrinkIfNeeded):
+        * NetworkProcess/cache/NetworkCacheStorage.cpp:
+        (WebKit::NetworkCache::Storage::ReadOperation::ReadOperation):
+        (WebKit::NetworkCache::Storage::WriteOperation::WriteOperation):
+        (WebKit::NetworkCache::Storage::TraverseOperation::TraverseOperation):
+
+            Operations now ref the storage. They are already deleted in the main thread so
+            proper destruction is taken care of.
+
+        (WebKit::NetworkCache::Storage::open):
+        (WebKit::NetworkCache::Storage::~Storage):
+        (WebKit::NetworkCache::Storage::synchronize):
+
+            This and other asynchronous methods now protect the Storage instance.
+
+        (WebKit::NetworkCache::Storage::remove):
+        (WebKit::NetworkCache::Storage::retrieve):
+        (WebKit::NetworkCache::Storage::store):
+        (WebKit::NetworkCache::Storage::traverse):
+        (WebKit::NetworkCache::Storage::clear):
+        (WebKit::NetworkCache::Storage::shrink):
+        (WebKit::NetworkCache::Storage::deleteOldVersions):
+        * NetworkProcess/cache/NetworkCacheStorage.h:
+        * NetworkProcess/cocoa/NetworkProcessCocoa.mm:
+        (WebKit::NetworkProcess::platformInitializeNetworkProcessCocoa):
+        (WebKit::NetworkProcess::clearDiskCache):
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
+        * NetworkProcess/soup/NetworkProcessSoup.cpp:
+        (WebKit::NetworkProcess::platformInitializeNetworkProcess):
+        (WebKit::NetworkProcess::clearDiskCache):
+
 2017-08-04  Frederic Wang  <[email protected]>
 
         ScrollingTreeOverflowScrollingNodeIOS uses the wrong fixed position rectangle

Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -409,7 +409,8 @@
 
 void NetworkConnectionToWebProcess::storeDerivedDataToCache(const WebKit::NetworkCache::DataKey& dataKey, const IPC::DataReference& data)
 {
-    NetworkCache::singleton().storeData(dataKey, data.data(), data.size());
+    if (auto* cache = NetworkProcess::singleton().cache())
+        cache->storeData(dataKey, data.data(), data.size());
 }
 
 void NetworkConnectionToWebProcess::setCaptureExtraNetworkLoadMetricsEnabled(bool enabled)

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -328,9 +328,9 @@
 static void fetchDiskCacheEntries(SessionID sessionID, OptionSet<WebsiteDataFetchOption> fetchOptions, Function<void (Vector<WebsiteData::Entry>)>&& completionHandler)
 {
 #if ENABLE(NETWORK_CACHE)
-    if (NetworkCache::singleton().isEnabled()) {
+    if (auto* cache = NetworkProcess::singleton().cache()) {
         HashMap<SecurityOriginData, uint64_t> originsAndSizes;
-        NetworkCache::singleton().traverse([fetchOptions, completionHandler = WTFMove(completionHandler), originsAndSizes = WTFMove(originsAndSizes)](auto* traversalEntry) mutable {
+        cache->traverse([fetchOptions, completionHandler = WTFMove(completionHandler), originsAndSizes = WTFMove(originsAndSizes)](auto* traversalEntry) mutable {
             if (!traversalEntry) {
                 Vector<WebsiteData::Entry> entries;
 
@@ -436,13 +436,13 @@
 static void clearDiskCacheEntries(const Vector<SecurityOriginData>& origins, Function<void ()>&& completionHandler)
 {
 #if ENABLE(NETWORK_CACHE)
-    if (NetworkCache::singleton().isEnabled()) {
+    if (auto* cache = NetworkProcess::singleton().cache()) {
         HashSet<RefPtr<SecurityOrigin>> originsToDelete;
         for (auto& origin : origins)
             originsToDelete.add(origin.securityOrigin());
 
         Vector<NetworkCache::Key> cacheKeysToDelete;
-        NetworkCache::singleton().traverse([completionHandler = WTFMove(completionHandler), originsToDelete = WTFMove(originsToDelete), cacheKeysToDelete = WTFMove(cacheKeysToDelete)](auto* traversalEntry) mutable {
+        cache->traverse([cache, completionHandler = WTFMove(completionHandler), originsToDelete = WTFMove(originsToDelete), cacheKeysToDelete = WTFMove(cacheKeysToDelete)](auto* traversalEntry) mutable {
             if (traversalEntry) {
                 if (originsToDelete.contains(SecurityOrigin::create(traversalEntry->entry.response().url())))
                     cacheKeysToDelete.append(traversalEntry->entry.key());
@@ -449,7 +449,7 @@
                 return;
             }
 
-            NetworkCache::singleton().remove(cacheKeysToDelete, WTFMove(completionHandler));
+            cache->remove(cacheKeysToDelete, WTFMove(completionHandler));
             return;
         });
 
@@ -575,9 +575,8 @@
         urlCacheDiskCapacity = m_diskCacheSizeOverride;
 
 #if ENABLE(NETWORK_CACHE)
-    auto& networkCache = NetworkCache::singleton();
-    if (networkCache.isEnabled()) {
-        networkCache.setCapacity(urlCacheDiskCapacity);
+    if (m_cache) {
+        m_cache->setCapacity(urlCacheDiskCapacity);
         return;
     }
 #endif

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2017-08-04 13:25:02 UTC (rev 220267)
@@ -63,6 +63,10 @@
 struct NetworkProcessCreationParameters;
 struct WebsiteDataStoreParameters;
 
+namespace NetworkCache {
+class Cache;
+}
+
 class NetworkProcess : public ChildProcess, private DownloadManager::Client {
     WTF_MAKE_NONCOPYABLE(NetworkProcess);
     friend class NeverDestroyed<NetworkProcess>;
@@ -86,6 +90,9 @@
 
     AuthenticationManager& authenticationManager();
     DownloadManager& downloadManager();
+
+    NetworkCache::Cache* cache() { return m_cache.get(); }
+
     bool canHandleHTTPSServerTrustEvaluation() const { return m_canHandleHTTPSServerTrustEvaluation; }
 
     void processWillSuspendImminently(bool& handled);
@@ -220,6 +227,8 @@
     bool m_canHandleHTTPSServerTrustEvaluation;
     Seconds m_loadThrottleLatency;
 
+    RefPtr<NetworkCache::Cache> m_cache;
+
     typedef HashMap<const char*, std::unique_ptr<NetworkProcessSupplement>, PtrHash<const char*>> NetworkProcessSupplementMap;
     NetworkProcessSupplementMap m_supplements;
 

Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -86,6 +86,7 @@
     , m_connection(connection)
     , m_defersLoading(parameters.defersLoading)
     , m_bufferingTimer(*this, &NetworkResourceLoader::bufferingTimerFired)
+    , m_cache(sessionID().isEphemeral() ? nullptr : NetworkProcess::singleton().cache())
 {
     ASSERT(RunLoop::isMain());
     // FIXME: This is necessary because of the existence of EmptyFrameLoaderClient in WebCore.
@@ -121,10 +122,10 @@
 #if ENABLE(NETWORK_CACHE)
 bool NetworkResourceLoader::canUseCache(const ResourceRequest& request) const
 {
-    if (!NetworkCache::singleton().isEnabled())
+    if (!m_cache)
         return false;
-    if (sessionID().isEphemeral())
-        return false;
+    ASSERT(!sessionID().isEphemeral());
+
     if (!request.url().protocolIsInHTTPFamily())
         return false;
     if (originalRequest().cachePolicy() == WebCore::DoNotUseAnyCache)
@@ -181,7 +182,7 @@
     ASSERT(canUseCache(request));
 
     RefPtr<NetworkResourceLoader> loader(this);
-    NetworkCache::singleton().retrieve(request, { m_parameters.webPageID, m_parameters.webFrameID }, [this, loader = WTFMove(loader), request](auto entry) {
+    m_cache->retrieve(request, { m_parameters.webPageID, m_parameters.webFrameID }, [this, loader = WTFMove(loader), request](auto entry) {
         if (loader->hasOneRef()) {
             // The loader has been aborted and is only held alive by this lambda.
             return;
@@ -307,7 +308,7 @@
         if (canUseCache(m_networkLoad->currentRequest())) {
             // We might already have used data from this incomplete load. Ensure older versions don't remain in the cache after cancel.
             if (!m_response.isNull())
-                NetworkCache::singleton().remove(m_networkLoad->currentRequest());
+                m_cache->remove(m_networkLoad->currentRequest());
         }
 #endif
         m_networkLoad->cancel();
@@ -334,7 +335,7 @@
     if (m_cacheEntryForValidation) {
         bool validationSucceeded = m_response.httpStatusCode() == 304; // 304 Not Modified
         if (validationSucceeded) {
-            m_cacheEntryForValidation = NetworkCache::singleton().update(originalRequest(), { m_parameters.webPageID, m_parameters.webFrameID }, *m_cacheEntryForValidation, m_response);
+            m_cacheEntryForValidation = m_cache->update(originalRequest(), { m_parameters.webPageID, m_parameters.webFrameID }, *m_cacheEntryForValidation, m_response);
             // If the request was conditional then this revalidation was not triggered by the network cache and we pass the 304 response to WebCore.
             if (originalRequest().isConditional())
                 m_cacheEntryForValidation = nullptr;
@@ -470,7 +471,7 @@
 
 #if ENABLE(NETWORK_CACHE)
     if (canUseCachedRedirect(request))
-        NetworkCache::singleton().storeRedirect(request, redirectResponse, redirectRequest);
+        m_cache->storeRedirect(request, redirectResponse, redirectRequest);
 #else
     UNUSED_PARAM(request);
 #endif
@@ -559,7 +560,7 @@
     if (!m_bufferedDataForCache)
         return;
 
-    NetworkCache::singleton().store(m_networkLoad->currentRequest(), m_response, WTFMove(m_bufferedDataForCache), [loader = makeRef(*this)](auto& mappedBody) mutable {
+    m_cache->store(m_networkLoad->currentRequest(), m_response, WTFMove(m_bufferedDataForCache), [loader = makeRef(*this)](auto& mappedBody) mutable {
 #if ENABLE(SHAREABLE_RESOURCE)
         if (mappedBody.shareableResourceHandle.isNull())
             return;
@@ -588,7 +589,7 @@
 
         for (auto& type : m_parameters.derivedCachedDataTypesToRetrieve) {
             NetworkCache::DataKey key { originalRequest().cachePartition(), type, bodyHash };
-            NetworkCache::singleton().retrieveData(key, [loader = makeRef(*this), entryPtr, type, retrieveCount] (const uint8_t* data, size_t size) mutable {
+            m_cache->retrieveData(key, [loader = makeRef(*this), entryPtr, type, retrieveCount] (const uint8_t* data, size_t size) mutable {
                 loader->m_retrievedDerivedDataCount++;
                 bool retrievedAll = loader->m_retrievedDerivedDataCount == retrieveCount;
                 std::unique_ptr<NetworkCache::Entry> entry(retrievedAll ? entryPtr : nullptr);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h	2017-08-04 13:25:02 UTC (rev 220267)
@@ -160,6 +160,7 @@
 
     WebCore::Timer m_bufferingTimer;
 #if ENABLE(NETWORK_CACHE)
+    RefPtr<NetworkCache::Cache> m_cache;
     RefPtr<WebCore::SharedBuffer> m_bufferedDataForCache;
     std::unique_ptr<NetworkCache::Entry> m_cacheEntryForValidation;
     bool m_isWaitingContinueWillSendRequestForCachedRedirect { false };

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-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
@@ -62,10 +62,16 @@
     return resource;
 }
 
-Cache& singleton()
+RefPtr<Cache> Cache::open(const String& cachePath, OptionSet<Option> options)
 {
-    static NeverDestroyed<Cache> instance;
-    return instance;
+    auto storage = Storage::open(cachePath, options.contains(Option::TestingMode) ? Storage::Mode::Testing : Storage::Mode::Normal);
+
+    LOG(NetworkCache, "(NetworkProcess) opened cache storage, success %d", !!storage);
+
+    if (!storage)
+        return nullptr;
+
+    return adoptRef(*new Cache(storage.releaseNonNull(), options));
 }
 
 #if PLATFORM(GTK)
@@ -75,10 +81,9 @@
 }
 #endif
 
-bool Cache::initialize(const String& cachePath, OptionSet<Option> options)
+Cache::Cache(Ref<Storage>&& storage, OptionSet<Option> options)
+    : m_storage(WTFMove(storage))
 {
-    m_storage = Storage::open(cachePath, options.contains(Option::TestingMode) ? Storage::Mode::Testing : Storage::Mode::Normal);
-
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
     if (options.contains(Option::SpeculativeRevalidation)) {
         m_lowPowerModeNotifier = std::make_unique<WebCore::LowPowerModeNotifier>([this](bool isLowPowerModeEnabled) {
@@ -87,44 +92,41 @@
                 m_speculativeLoadManager = nullptr;
             else {
                 ASSERT(!m_speculativeLoadManager);
-                m_speculativeLoadManager = std::make_unique<SpeculativeLoadManager>(*m_storage);
+                m_speculativeLoadManager = std::make_unique<SpeculativeLoadManager>(*this, m_storage.get());
             }
         });
         if (!m_lowPowerModeNotifier->isLowPowerModeEnabled())
-            m_speculativeLoadManager = std::make_unique<SpeculativeLoadManager>(*m_storage);
+            m_speculativeLoadManager = std::make_unique<SpeculativeLoadManager>(*this, m_storage.get());
     }
 #endif
 
     if (options.contains(Option::EfficacyLogging))
-        m_statistics = Statistics::open(cachePath);
+        m_statistics = Statistics::open(*this, m_storage->basePath());
 
+    if (options.contains(Option::RegisterNotify)) {
 #if PLATFORM(COCOA)
-    // Triggers with "notifyutil -p com.apple.WebKit.Cache.dump".
-    if (m_storage) {
+        // Triggers with "notifyutil -p com.apple.WebKit.Cache.dump".
         int token;
         notify_register_dispatch("com.apple.WebKit.Cache.dump", &token, dispatch_get_main_queue(), ^(int) {
             dumpContentsToFile();
         });
-    }
 #endif
 #if PLATFORM(GTK)
-    // Triggers with "touch $cachePath/dump".
-    if (m_storage) {
+        // Triggers with "touch $cachePath/dump".
         CString dumpFilePath = WebCore::fileSystemRepresentation(WebCore::pathByAppendingComponent(m_storage->basePath(), "dump"));
         GRefPtr<GFile> dumpFile = adoptGRef(g_file_new_for_path(dumpFilePath.data()));
         GFileMonitor* monitor = g_file_monitor_file(dumpFile.get(), G_FILE_MONITOR_NONE, nullptr, nullptr);
         g_signal_connect_swapped(monitor, "changed", G_CALLBACK(dumpFileChanged), this);
+#endif
     }
-#endif
+}
 
-    LOG(NetworkCache, "(NetworkProcess) opened cache storage, success %d", !!m_storage);
-    return !!m_storage;
+Cache::~Cache()
+{
 }
 
 void Cache::setCapacity(size_t maximumSize)
 {
-    if (!m_storage)
-        return;
     m_storage->setCapacity(maximumSize);
 }
 
@@ -315,7 +317,6 @@
 
 void Cache::retrieve(const WebCore::ResourceRequest& request, const GlobalFrameID& frameID, Function<void (std::unique_ptr<Entry>)>&& completionHandler)
 {
-    ASSERT(isEnabled());
     ASSERT(request.url().protocolIsInHTTPFamily());
 
     LOG(NetworkCache, "(NetworkProcess) retrieving %s priority %d", request.url().string().ascii().data(), static_cast<int>(request.priority()));
@@ -355,7 +356,7 @@
     auto startTime = std::chrono::system_clock::now();
     auto priority = static_cast<unsigned>(request.priority());
 
-    m_storage->retrieve(storageKey, priority, [this, request, completionHandler = WTFMove(completionHandler), startTime, storageKey, frameID](auto record) {
+    m_storage->retrieve(storageKey, priority, [this, protectedThis = makeRef(*this), request, completionHandler = WTFMove(completionHandler), startTime, storageKey, frameID](auto record) {
         if (!record) {
             LOG(NetworkCache, "(NetworkProcess) not found in storage");
 
@@ -408,7 +409,6 @@
 
 std::unique_ptr<Entry> Cache::store(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, Function<void (MappedBody&)>&& completionHandler)
 {
-    ASSERT(isEnabled());
     ASSERT(responseData);
 
     LOG(NetworkCache, "(NetworkProcess) storing %s, partition %s", request.url().string().latin1().data(), makeCacheKey(request).partition().latin1().data());
@@ -433,7 +433,7 @@
     auto cacheEntry = makeEntry(request, response, WTFMove(responseData));
     auto record = cacheEntry->encodeAsStorageRecord();
 
-    m_storage->store(record, [this, completionHandler = WTFMove(completionHandler)](const Data& bodyData) {
+    m_storage->store(record, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](const Data& bodyData) {
         MappedBody mappedBody;
 #if ENABLE(SHAREABLE_RESOURCE)
         if (canUseSharedMemoryForBodyData()) {
@@ -453,8 +453,6 @@
 
 std::unique_ptr<Entry> Cache::storeRedirect(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest)
 {
-    ASSERT(isEnabled());
-
     LOG(NetworkCache, "(NetworkProcess) storing redirect %s -> %s", request.url().string().latin1().data(), redirectRequest.url().string().latin1().data());
 
     StoreDecision storeDecision = makeStoreDecision(request, response, 0);
@@ -495,8 +493,6 @@
 
 void Cache::remove(const Key& key)
 {
-    ASSERT(isEnabled());
-
     m_storage->remove(key);
 }
 
@@ -507,15 +503,11 @@
 
 void Cache::remove(const Vector<Key>& keys, Function<void ()>&& completionHandler)
 {
-    ASSERT(isEnabled());
-
     m_storage->remove(keys, WTFMove(completionHandler));
 }
 
 void Cache::traverse(Function<void (const TraversalEntry*)>&& traverseHandler)
 {
-    ASSERT(isEnabled());
-
     // Protect against clients making excessive traversal requests.
     const unsigned maximumTraverseCount = 3;
     if (m_traverseCount >= maximumTraverseCount) {
@@ -529,7 +521,7 @@
 
     ++m_traverseCount;
 
-    m_storage->traverse(resourceType(), 0, [this, traverseHandler = WTFMove(traverseHandler)](const Storage::Record* record, const Storage::RecordInfo& recordInfo) {
+    m_storage->traverse(resourceType(), 0, [this, protectedThis = makeRef(*this), traverseHandler = WTFMove(traverseHandler)](const Storage::Record* record, const Storage::RecordInfo& recordInfo) {
         if (!record) {
             --m_traverseCount;
             traverseHandler(nullptr);
@@ -552,8 +544,6 @@
 
 void Cache::dumpContentsToFile()
 {
-    if (!m_storage)
-        return;
     auto fd = WebCore::openFile(dumpFilePath(), WebCore::OpenForWrite);
     if (!WebCore::isHandleValid(fd))
         return;
@@ -620,10 +610,6 @@
     if (m_statistics)
         m_statistics->clear();
 
-    if (!m_storage) {
-        RunLoop::main().dispatch(WTFMove(completionHandler));
-        return;
-    }
     String anyType;
     m_storage->clear(anyType, modifiedSince, WTFMove(completionHandler));
 
@@ -637,13 +623,11 @@
 
 String Cache::recordsPath() const
 {
-    return m_storage ? m_storage->recordsPath() : String();
+    return m_storage->recordsPath();
 }
 
 void Cache::retrieveData(const DataKey& dataKey, Function<void (const uint8_t* data, size_t size)> completionHandler)
 {
-    ASSERT(isEnabled());
-
     Key key { dataKey, m_storage->salt() };
     m_storage->retrieve(key, 4, [completionHandler = WTFMove(completionHandler)] (auto record) {
         if (!record || !record->body.size()) {
@@ -657,8 +641,6 @@
 
 void Cache::storeData(const DataKey& dataKey, const uint8_t* data, size_t size)
 {
-    if (!m_storage)
-        return;
     Key key { dataKey, m_storage->salt() };
     Storage::Record record { key, std::chrono::system_clock::now(), { }, Data { data, size }, { } };
     m_storage->store(record, { });

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h	2017-08-04 13:25:02 UTC (rev 220267)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-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
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef NetworkCache_h
-#define NetworkCache_h
+#pragma once
 
 #if ENABLE(NETWORK_CACHE)
 
@@ -50,8 +49,6 @@
 class SpeculativeLoadManager;
 class Statistics;
 
-Cache& singleton();
-
 struct MappedBody {
 #if ENABLE(SHAREABLE_RESOURCE)
     RefPtr<ShareableResource> shareableResource;
@@ -91,23 +88,21 @@
 
 using GlobalFrameID = std::pair<uint64_t /*webPageID*/, uint64_t /*webFrameID*/>;
 
-class Cache {
-    WTF_MAKE_NONCOPYABLE(Cache);
-    friend class WTF::NeverDestroyed<Cache>;
+class Cache : public RefCounted<Cache> {
 public:
     enum class Option {
         EfficacyLogging = 1 << 0,
         // In testing mode we try to eliminate sources of randomness. Cache does not shrink and there are no read timeouts.
         TestingMode = 1 << 1,
+        RegisterNotify = 1 << 2,
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
-        SpeculativeRevalidation = 1 << 2,
+        SpeculativeRevalidation = 1 << 3,
 #endif
     };
-    bool initialize(const String& cachePath, OptionSet<Option>);
+    static RefPtr<Cache> open(const String& cachePath, OptionSet<Option>);
+
     void setCapacity(size_t);
 
-    bool isEnabled() const { return !!m_storage; }
-
     // Completion handler may get called back synchronously on failure.
     void retrieve(const WebCore::ResourceRequest&, const GlobalFrameID&, Function<void (std::unique_ptr<Entry>)>&&);
     std::unique_ptr<Entry> store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, Function<void (MappedBody&)>&&);
@@ -135,15 +130,16 @@
     void dumpContentsToFile();
 
     String recordsPath() const;
-    bool canUseSharedMemoryForBodyData() const { return m_storage && m_storage->canUseSharedMemoryForBodyData(); }
+    bool canUseSharedMemoryForBodyData() const { return m_storage->canUseSharedMemoryForBodyData(); }
 
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
     SpeculativeLoadManager* speculativeLoadManager() { return m_speculativeLoadManager.get(); }
 #endif
 
+    ~Cache();
+
 private:
-    Cache() = default;
-    ~Cache() = delete;
+    Cache(Ref<Storage>&&, OptionSet<Option> options);
 
     Key makeCacheKey(const WebCore::ResourceRequest&);
 
@@ -150,7 +146,8 @@
     String dumpFilePath() const;
     void deleteDumpFile();
 
-    std::unique_ptr<Storage> m_storage;
+    Ref<Storage> m_storage;
+
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
     std::unique_ptr<WebCore::LowPowerModeNotifier> m_lowPowerModeNotifier;
     std::unique_ptr<SpeculativeLoadManager> m_speculativeLoadManager;
@@ -163,4 +160,3 @@
 }
 }
 #endif
-#endif

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -28,6 +28,7 @@
 
 #include "Logging.h"
 #include "NetworkCacheCoders.h"
+#include "NetworkProcess.h"
 #include <WebCore/ResourceRequest.h>
 #include <WebCore/SharedBuffer.h>
 #include <wtf/text/StringBuilder.h>
@@ -146,7 +147,8 @@
 #if ENABLE(SHAREABLE_RESOURCE)
 void Entry::initializeShareableResourceHandleFromStorageRecord() const
 {
-    if (!NetworkCache::singleton().canUseSharedMemoryForBodyData())
+    auto* cache = NetworkProcess::singleton().cache();
+    if (!cache || !cache->canUseSharedMemoryForBodyData())
         return;
 
     auto sharedMemory = m_sourceStorageRecord.body.tryCreateSharedMemory();

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -41,8 +41,9 @@
 
 using namespace WebCore;
 
-SpeculativeLoad::SpeculativeLoad(const GlobalFrameID& frameID, const ResourceRequest& request, std::unique_ptr<NetworkCache::Entry> cacheEntryForValidation, RevalidationCompletionHandler&& completionHandler)
-    : m_frameID(frameID)
+SpeculativeLoad::SpeculativeLoad(Cache& cache, const GlobalFrameID& frameID, const ResourceRequest& request, std::unique_ptr<NetworkCache::Entry> cacheEntryForValidation, RevalidationCompletionHandler&& completionHandler)
+    : m_cache(cache)
+    , m_frameID(frameID)
     , m_completionHandler(WTFMove(completionHandler))
     , m_originalRequest(request)
     , m_bufferedDataForCache(SharedBuffer::create())
@@ -71,10 +72,10 @@
 {
     LOG(NetworkCacheSpeculativePreloading, "Speculative redirect %s -> %s", request.url().string().utf8().data(), redirectRequest.url().string().utf8().data());
 
-    m_cacheEntry = NetworkCache::singleton().storeRedirect(request, redirectResponse, redirectRequest);
+    m_cacheEntry = m_cache->storeRedirect(request, redirectResponse, redirectRequest);
     // Create a synthetic cache entry if we can't store.
     if (!m_cacheEntry)
-        m_cacheEntry = NetworkCache::singleton().makeRedirectEntry(request, redirectResponse, redirectRequest);
+        m_cacheEntry = m_cache->makeRedirectEntry(request, redirectResponse, redirectRequest);
 
     // Don't follow the redirect. The redirect target will be registered for speculative load when it is loaded.
     didComplete();
@@ -89,7 +90,7 @@
 
     bool validationSucceeded = m_response.httpStatusCode() == 304; // 304 Not Modified
     if (validationSucceeded && m_cacheEntry)
-        m_cacheEntry = NetworkCache::singleton().update(m_originalRequest, m_frameID, *m_cacheEntry, m_response);
+        m_cacheEntry = m_cache->update(m_originalRequest, m_frameID, *m_cacheEntry, m_response);
     else
         m_cacheEntry = nullptr;
 
@@ -115,10 +116,10 @@
     if (m_didComplete)
         return;
     if (!m_cacheEntry && m_bufferedDataForCache) {
-        m_cacheEntry = NetworkCache::singleton().store(m_originalRequest, m_response, m_bufferedDataForCache.copyRef(), [](auto& mappedBody) { });
+        m_cacheEntry = m_cache->store(m_originalRequest, m_response, m_bufferedDataForCache.copyRef(), [](auto& mappedBody) { });
         // Create a synthetic cache entry if we can't store.
         if (!m_cacheEntry && isStatusCodeCacheableByDefault(m_response.httpStatusCode()))
-            m_cacheEntry = NetworkCache::singleton().makeEntry(m_originalRequest, m_response, WTFMove(m_bufferedDataForCache));
+            m_cacheEntry = m_cache->makeEntry(m_originalRequest, m_response, WTFMove(m_bufferedDataForCache));
     }
 
     didComplete();

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h	2017-08-04 13:25:02 UTC (rev 220267)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef NetworkCacheSpeculativeLoad_h
-#define NetworkCacheSpeculativeLoad_h
+#pragma once
 
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
 
@@ -45,7 +44,7 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     typedef Function<void (std::unique_ptr<NetworkCache::Entry>)> RevalidationCompletionHandler;
-    SpeculativeLoad(const GlobalFrameID&, const WebCore::ResourceRequest&, std::unique_ptr<NetworkCache::Entry>, RevalidationCompletionHandler&&);
+    SpeculativeLoad(Cache&, const GlobalFrameID&, const WebCore::ResourceRequest&, std::unique_ptr<NetworkCache::Entry>, RevalidationCompletionHandler&&);
 
     virtual ~SpeculativeLoad();
 
@@ -66,6 +65,7 @@
 
     void didComplete();
 
+    Ref<Cache> m_cache;
     GlobalFrameID m_frameID;
     RevalidationCompletionHandler m_completionHandler;
     WebCore::ResourceRequest m_originalRequest;
@@ -83,5 +83,3 @@
 } // namespace WebKit
 
 #endif // ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
-
-#endif // NetworkCacheSpeculativeLoad_h

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -245,8 +245,9 @@
     bool m_didRetrieveExistingEntry { false };
 };
 
-SpeculativeLoadManager::SpeculativeLoadManager(Storage& storage)
-    : m_storage(storage)
+SpeculativeLoadManager::SpeculativeLoadManager(Cache& cache, Storage& storage)
+    : m_cache(cache)
+    , m_storage(storage)
 {
 }
 
@@ -466,7 +467,7 @@
 
     LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Speculatively revalidating '%s':", key.identifier().utf8().data());
 
-    auto revalidator = std::make_unique<SpeculativeLoad>(frameID, revalidationRequest, WTFMove(entry), [this, key, revalidationRequest, frameID](std::unique_ptr<Entry> revalidatedEntry) {
+    auto revalidator = std::make_unique<SpeculativeLoad>(m_cache, frameID, revalidationRequest, WTFMove(entry), [this, key, revalidationRequest, frameID](std::unique_ptr<Entry> revalidatedEntry) {
         ASSERT(!revalidatedEntry || !revalidatedEntry->needsValidation());
         ASSERT(!revalidatedEntry || revalidatedEntry->key() == key);
 

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h	2017-08-04 13:25:02 UTC (rev 220267)
@@ -46,7 +46,7 @@
 class SpeculativeLoadManager {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit SpeculativeLoadManager(Storage&);
+    explicit SpeculativeLoadManager(Cache&, Storage&);
     ~SpeculativeLoadManager();
 
     void registerLoad(const GlobalFrameID&, const WebCore::ResourceRequest&, const Key& resourceKey);
@@ -70,6 +70,7 @@
     static bool canUsePreloadedEntry(const PreloadedEntry&, const WebCore::ResourceRequest& actualRequest);
     static bool canUsePendingPreload(const SpeculativeLoad&, const WebCore::ResourceRequest& actualRequest);
 
+    Cache& m_cache;
     Storage& m_storage;
 
     class PendingFrameLoad;

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -74,16 +74,17 @@
     return true;
 }
 
-std::unique_ptr<Statistics> Statistics::open(const String& cachePath)
+std::unique_ptr<Statistics> Statistics::open(Cache& cache, const String& cachePath)
 {
     ASSERT(RunLoop::isMain());
 
     String databasePath = WebCore::pathByAppendingComponent(cachePath, StatisticsDatabaseName);
-    return std::make_unique<Statistics>(databasePath);
+    return std::make_unique<Statistics>(cache, databasePath);
 }
 
-Statistics::Statistics(const String& databasePath)
-    : m_serialBackgroundIOQueue(WorkQueue::create("com.apple.WebKit.Cache.Statistics.Background", WorkQueue::Type::Serial, WorkQueue::QOS::Background))
+Statistics::Statistics(Cache& cache, const String& databasePath)
+    : m_cache(cache)
+    , m_serialBackgroundIOQueue(WorkQueue::create("com.apple.WebKit.Cache.Statistics.Background", WorkQueue::Type::Serial, WorkQueue::QOS::Background))
     , m_writeTimer(*this, &Statistics::writeTimerFired)
 {
     initialize(databasePath);
@@ -95,7 +96,7 @@
 
     auto startTime = std::chrono::system_clock::now();
 
-    serialBackgroundIOQueue().dispatch([this, databasePath = databasePath.isolatedCopy(), networkCachePath = singleton().recordsPath().isolatedCopy(), startTime] {
+    serialBackgroundIOQueue().dispatch([this, databasePath = databasePath.isolatedCopy(), networkCachePath = m_cache.recordsPath(), startTime] {
         WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
 
         if (!WebCore::makeAllDirectories(WebCore::directoryName(databasePath)))
@@ -178,7 +179,7 @@
 
     clear();
 
-    serialBackgroundIOQueue().dispatch([this, networkCachePath = singleton().recordsPath().isolatedCopy()] {
+    serialBackgroundIOQueue().dispatch([this, networkCachePath = m_cache.recordsPath()] {
         bootstrapFromNetworkCache(networkCachePath);
         LOG(NetworkCache, "(NetworkProcess) statistics cache shrink completed m_approximateEntryCount=%lu", static_cast<size_t>(m_approximateEntryCount));
     });

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.h (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.h	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.h	2017-08-04 13:25:02 UTC (rev 220267)
@@ -43,8 +43,8 @@
 
 class Statistics {
 public:
-    static std::unique_ptr<Statistics> open(const String& cachePath);
-    explicit Statistics(const String& databasePath);
+    static std::unique_ptr<Statistics> open(Cache&, const String& cachePath);
+    explicit Statistics(Cache&, const String& databasePath);
 
     void clear();
 
@@ -77,6 +77,8 @@
         RequestedCompletionHandler completionHandler;
     };
 
+    Cache& m_cache;
+
     std::atomic<size_t> m_approximateEntryCount { 0 };
 
     mutable Ref<WorkQueue> m_serialBackgroundIOQueue;

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-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
@@ -53,8 +53,9 @@
 struct Storage::ReadOperation {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ReadOperation(const Key& key, RetrieveCompletionHandler&& completionHandler)
-        : key(key)
+    ReadOperation(Storage& storage, const Key& key, RetrieveCompletionHandler&& completionHandler)
+        : storage(storage)
+        , key(key)
         , completionHandler(WTFMove(completionHandler))
     { }
 
@@ -61,6 +62,8 @@
     void cancel();
     bool finish();
 
+    Ref<Storage> storage;
+
     const Key key;
     const RetrieveCompletionHandler completionHandler;
     
@@ -99,11 +102,13 @@
 struct Storage::WriteOperation {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    WriteOperation(const Record& record, MappedBodyHandler&& mappedBodyHandler)
-        : record(record)
+    WriteOperation(Storage& storage, const Record& record, MappedBodyHandler&& mappedBodyHandler)
+        : storage(storage)
+        , record(record)
         , mappedBodyHandler(WTFMove(mappedBodyHandler))
     { }
-    
+    Ref<Storage> storage;
+
     const Record record;
     const MappedBodyHandler mappedBodyHandler;
 
@@ -113,11 +118,13 @@
 struct Storage::TraverseOperation {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    TraverseOperation(const String& type, TraverseFlags flags, TraverseHandler&& handler)
-        : type(type)
+    TraverseOperation(Storage& storage, const String& type, TraverseFlags flags, TraverseHandler&& handler)
+        : storage(storage)
+        , type(type)
         , flags(flags)
         , handler(WTFMove(handler))
     { }
+    Ref<Storage> storage;
 
     const String type;
     const TraverseFlags flags;
@@ -149,7 +156,7 @@
     return WebCore::pathByAppendingComponent(makeVersionedDirectoryPath(baseDirectoryPath), saltFileName);
 }
 
-std::unique_ptr<Storage> Storage::open(const String& cachePath, Mode mode)
+RefPtr<Storage> Storage::open(const String& cachePath, Mode mode)
 {
     ASSERT(RunLoop::isMain());
 
@@ -158,7 +165,7 @@
     auto salt = readOrMakeSalt(makeSaltFilePath(cachePath));
     if (!salt)
         return nullptr;
-    return std::unique_ptr<Storage>(new Storage(cachePath, mode, *salt));
+    return adoptRef(new Storage(cachePath, mode, *salt));
 }
 
 void traverseRecordsFiles(const String& recordsPath, const String& expectedType, const RecordFileTraverseFunction& function)
@@ -226,6 +233,12 @@
 
 Storage::~Storage()
 {
+    ASSERT(RunLoop::isMain());
+    ASSERT(m_activeReadOperations.isEmpty());
+    ASSERT(m_activeWriteOperations.isEmpty());
+    ASSERT(m_activeTraverseOperations.isEmpty());
+    ASSERT(!m_synchronizationInProgress);
+    ASSERT(!m_shrinkInProgress);
 }
 
 String Storage::basePath() const
@@ -258,7 +271,7 @@
 
     LOG(NetworkCacheStorage, "(NetworkProcess) synchronizing cache");
 
-    backgroundIOQueue().dispatch([this] {
+    backgroundIOQueue().dispatch([this, protectedThis = makeRef(*this)] () mutable {
         auto recordFilter = std::make_unique<ContentsFilter>();
         auto blobFilter = std::make_unique<ContentsFilter>();
         size_t recordsSize = 0;
@@ -309,6 +322,8 @@
         deleteEmptyRecordsDirectories(recordsPath());
 
         LOG(NetworkCacheStorage, "(NetworkProcess) cache synchronization completed size=%zu count=%u", recordsSize, count);
+
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis)] { });
     });
 }
 
@@ -554,8 +569,9 @@
 
     removeFromPendingWriteOperations(key);
 
-    serialBackgroundIOQueue().dispatch([this, key] {
+    serialBackgroundIOQueue().dispatch([this, protectedThis = makeRef(*this), key] () mutable {
         deleteFiles(key);
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis)] { });
     });
 }
 
@@ -573,12 +589,14 @@
         keysToRemove.uncheckedAppend(key);
     }
 
-    serialBackgroundIOQueue().dispatch([this, keysToRemove = WTFMove(keysToRemove), completionHandler = WTFMove(completionHandler)] () mutable {
+    serialBackgroundIOQueue().dispatch([this, protectedThis = makeRef(*this), keysToRemove = WTFMove(keysToRemove), completionHandler = WTFMove(completionHandler)] () mutable {
         for (auto& key : keysToRemove)
             deleteFiles(key);
 
-        if (completionHandler)
-            RunLoop::main().dispatch(WTFMove(completionHandler));
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] {
+            if (completionHandler)
+                completionHandler();
+        });
     });
 }
 
@@ -805,7 +823,7 @@
     if (retrieveFromMemory(m_activeWriteOperations, key, completionHandler))
         return;
 
-    auto readOperation = std::make_unique<ReadOperation>(key, WTFMove(completionHandler));
+    auto readOperation = std::make_unique<ReadOperation>(*this, key, WTFMove(completionHandler));
     m_pendingReadOperationsByPriority[priority].prepend(WTFMove(readOperation));
     dispatchPendingReadOperations();
 }
@@ -818,7 +836,7 @@
     if (!m_capacity)
         return;
 
-    auto writeOperation = std::make_unique<WriteOperation>(record, WTFMove(mappedBodyHandler));
+    auto writeOperation = std::make_unique<WriteOperation>(*this, record, WTFMove(mappedBodyHandler));
     m_pendingWriteOperations.prepend(WTFMove(writeOperation));
 
     // Add key to the filter already here as we do lookups from the pending operations too.
@@ -840,7 +858,7 @@
     ASSERT(traverseHandler);
     // Avoid non-thread safe Function copies.
 
-    auto traverseOperationPtr = std::make_unique<TraverseOperation>(type, flags, WTFMove(traverseHandler));
+    auto traverseOperationPtr = std::make_unique<TraverseOperation>(*this, type, flags, WTFMove(traverseHandler));
     auto& traverseOperation = *traverseOperationPtr;
     m_activeTraverseOperations.add(WTFMove(traverseOperationPtr));
 
@@ -936,7 +954,7 @@
         m_blobFilter->clear();
     m_approximateRecordsSize = 0;
 
-    ioQueue().dispatch([this, modifiedSinceTime, completionHandler = WTFMove(completionHandler), type = type.isolatedCopy()] () mutable {
+    ioQueue().dispatch([this, protectedThis = makeRef(*this), modifiedSinceTime, completionHandler = WTFMove(completionHandler), type = type.isolatedCopy()] () mutable {
         auto recordsPath = this->recordsPath();
         traverseRecordsFiles(recordsPath, type, [modifiedSinceTime](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
             auto filePath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
@@ -953,11 +971,10 @@
         // This cleans unreferenced blobs.
         m_blobStorage.synchronize();
 
-        if (completionHandler) {
-            RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)] {
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] {
+            if (completionHandler)
                 completionHandler();
-            });
-        }
+        });
     });
 }
 
@@ -1019,7 +1036,7 @@
 
     LOG(NetworkCacheStorage, "(NetworkProcess) shrinking cache approximateSize=%zu capacity=%zu", approximateSize(), m_capacity);
 
-    backgroundIOQueue().dispatch([this] {
+    backgroundIOQueue().dispatch([this, protectedThis = makeRef(*this)] () mutable {
         auto recordsPath = this->recordsPath();
         String anyType;
         traverseRecordsFiles(recordsPath, anyType, [this](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
@@ -1043,7 +1060,7 @@
             }
         });
 
-        RunLoop::main().dispatch([this] {
+        RunLoop::main().dispatch([this, protectedThis = WTFMove(protectedThis)] {
             m_shrinkInProgress = false;
             // We could synchronize during the shrink traversal. However this is fast and it is better to have just one code path.
             synchronize();
@@ -1055,7 +1072,7 @@
 
 void Storage::deleteOldVersions()
 {
-    backgroundIOQueue().dispatch([this] {
+    backgroundIOQueue().dispatch([this, protectedThis = makeRef(*this)] () mutable {
         auto cachePath = basePath();
         traverseDirectory(cachePath, [&cachePath](const String& subdirName, DirectoryEntryType type) {
             if (type != DirectoryEntryType::Directory)
@@ -1079,6 +1096,8 @@
 
             deleteDirectoryRecursively(oldVersionPath);
         });
+
+        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis)] { });
     });
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h	2017-08-04 13:25:02 UTC (rev 220267)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-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
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef NetworkCacheStorage_h
-#define NetworkCacheStorage_h
+#pragma once
 
 #if ENABLE(NETWORK_CACHE)
 
@@ -45,11 +44,10 @@
 
 class IOChannel;
 
-class Storage {
-    WTF_MAKE_NONCOPYABLE(Storage);
+class Storage : public ThreadSafeRefCounted<Storage> {
 public:
     enum class Mode { Normal, Testing };
-    static std::unique_ptr<Storage> open(const String& cachePath, Mode);
+    static RefPtr<Storage> open(const String& cachePath, Mode);
 
     struct Record {
         WTF_MAKE_FAST_ALLOCATED;
@@ -193,4 +191,3 @@
 }
 }
 #endif
-#endif

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm	2017-08-04 13:25:02 UTC (rev 220267)
@@ -84,6 +84,7 @@
     NetworkSessionCocoa::setSourceApplicationBundleIdentifier(parameters.sourceApplicationBundleIdentifier);
     NetworkSessionCocoa::setSourceApplicationSecondaryIdentifier(parameters.sourceApplicationSecondaryIdentifier);
     NetworkSessionCocoa::setAllowsCellularAccess(parameters.allowsCellularAccess);
+    NetworkSessionCocoa::setUsesNetworkCache(parameters.shouldEnableNetworkCache);
 #if PLATFORM(IOS)
     NetworkSessionCocoa::setCTDataConnectionServiceType(parameters.ctDataConnectionServiceType);
 #endif
@@ -108,7 +109,7 @@
         SandboxExtension::consumePermanently(parameters.diskCacheDirectoryExtensionHandle);
 #if ENABLE(NETWORK_CACHE)
         if (parameters.shouldEnableNetworkCache) {
-            OptionSet<NetworkCache::Cache::Option> cacheOptions;
+            OptionSet<NetworkCache::Cache::Option> cacheOptions { NetworkCache::Cache::Option::RegisterNotify };
             if (parameters.shouldEnableNetworkCacheEfficacyLogging)
                 cacheOptions |= NetworkCache::Cache::Option::EfficacyLogging;
             if (parameters.shouldUseTestingNetworkSession)
@@ -117,7 +118,10 @@
             if (parameters.shouldEnableNetworkCacheSpeculativeRevalidation)
                 cacheOptions |= NetworkCache::Cache::Option::SpeculativeRevalidation;
 #endif
-            if (NetworkCache::singleton().initialize(m_diskCacheDirectory, cacheOptions)) {
+            m_cache = NetworkCache::Cache::open(m_diskCacheDirectory, cacheOptions);
+
+            if (m_cache) {
+                // Disable NSURLCache.
                 auto urlCache(adoptNS([[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]));
                 [NSURLCache setSharedURLCache:urlCache.get()];
                 return;
@@ -187,16 +191,18 @@
         m_clearCacheDispatchGroup = dispatch_group_create();
 
 #if ENABLE(NETWORK_CACHE)
-    auto group = m_clearCacheDispatchGroup;
-    dispatch_group_async(group, dispatch_get_main_queue(), BlockPtr<void()>::fromCallable([group, modifiedSince, completionHandler = WTFMove(completionHandler)] () mutable {
-        NetworkCache::singleton().clear(modifiedSince, [group, modifiedSince, completionHandler = WTFMove(completionHandler)] () mutable {
-            // FIXME: Probably not necessary.
-            clearNSURLCache(group, modifiedSince, WTFMove(completionHandler));
-        });
-    }).get());
-#else
+    if (auto* cache = NetworkProcess::singleton().cache()) {
+        auto group = m_clearCacheDispatchGroup;
+        dispatch_group_async(group, dispatch_get_main_queue(), BlockPtr<void()>::fromCallable([cache, group, modifiedSince, completionHandler = WTFMove(completionHandler)] () mutable {
+            cache->clear(modifiedSince, [group, modifiedSince, completionHandler = WTFMove(completionHandler)] () mutable {
+                // FIXME: Probably not necessary.
+                clearNSURLCache(group, modifiedSince, WTFMove(completionHandler));
+            });
+        }).get());
+        return;
+    }
+#endif
     clearNSURLCache(m_clearCacheDispatchGroup, modifiedSince, WTFMove(completionHandler));
-#endif
 }
 
 void NetworkProcess::setCookieStoragePartitioningEnabled(bool enabled)

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h	2017-08-04 13:25:02 UTC (rev 220267)
@@ -52,6 +52,7 @@
     static void setSourceApplicationBundleIdentifier(const String&);
     static void setSourceApplicationSecondaryIdentifier(const String&);
     static void setAllowsCellularAccess(bool);
+    static void setUsesNetworkCache(bool);
 #if PLATFORM(IOS)
     static void setCTDataConnectionServiceType(const String&);
 #endif

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm	2017-08-04 13:25:02 UTC (rev 220267)
@@ -33,7 +33,6 @@
 #import "Download.h"
 #import "LegacyCustomProtocolManager.h"
 #import "Logging.h"
-#import "NetworkCache.h"
 #import "NetworkLoad.h"
 #import "NetworkProcess.h"
 #import "SessionTracker.h"
@@ -449,6 +448,7 @@
 namespace WebKit {
     
 static bool allowsCellularAccess { true };
+static bool usesNetworkCache { false };
 static LegacyCustomProtocolManager* legacyCustomProtocolManager;
 
 #if !ASSERT_DISABLED
@@ -520,6 +520,11 @@
     allowsCellularAccess = value;
 }
 
+void NetworkSessionCocoa::setUsesNetworkCache(bool value)
+{
+    usesNetworkCache = value;
+}
+
 #if PLATFORM(IOS)
 void NetworkSessionCocoa::setCTDataConnectionServiceType(const String& type)
 {
@@ -553,10 +558,10 @@
 
     if (!allowsCellularAccess)
         configuration.allowsCellularAccess = NO;
-    
-    if (NetworkCache::singleton().isEnabled())
+
+    if (usesNetworkCache)
         configuration.URLCache = nil;
-    
+
     if (auto& data = ""
         configuration._sourceApplicationAuditTokenData = (NSData *)data.get();
 

Modified: trunk/Source/WebKit/NetworkProcess/ios/NetworkProcessIOS.mm (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/ios/NetworkProcessIOS.mm	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/ios/NetworkProcessIOS.mm	2017-08-04 13:25:02 UTC (rev 220267)
@@ -79,7 +79,8 @@
     if (resourceCachesToClear == InMemoryResourceCachesOnly)
         return;
 #if ENABLE(NETWORK_CACHE)
-    NetworkCache::singleton().clear();
+    if (m_cache)
+        m_cache->clear();
 #endif
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp (220266 => 220267)


--- trunk/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp	2017-08-04 10:12:53 UTC (rev 220266)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp	2017-08-04 13:25:02 UTC (rev 220267)
@@ -112,7 +112,7 @@
 
     SoupNetworkSession::clearOldSoupCache(WebCore::directoryName(m_diskCacheDirectory));
 
-    OptionSet<NetworkCache::Cache::Option> cacheOptions;
+    OptionSet<NetworkCache::Cache::Option> cacheOptions { NetworkCache::Cache::Option::RegisterNotify };
     if (parameters.shouldEnableNetworkCacheEfficacyLogging)
         cacheOptions |= NetworkCache::Cache::Option::EfficacyLogging;
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
@@ -120,7 +120,7 @@
         cacheOptions |= NetworkCache::Cache::Option::SpeculativeRevalidation;
 #endif
 
-    NetworkCache::singleton().initialize(m_diskCacheDirectory, cacheOptions);
+    m_cache = NetworkCache::Cache::open(m_diskCacheDirectory, cacheOptions);
 
     if (!parameters.cookiePersistentStoragePath.isEmpty()) {
         supplement<WebCookieManager>()->setCookiePersistentStorage(parameters.cookiePersistentStoragePath,
@@ -158,7 +158,9 @@
 
 void NetworkProcess::clearDiskCache(std::chrono::system_clock::time_point modifiedSince, Function<void ()>&& completionHandler)
 {
-    NetworkCache::singleton().clear(modifiedSince, WTFMove(completionHandler));
+    if (!m_cache)
+        return;
+    m_cache->clear(modifiedSince, WTFMove(completionHandler));
 }
 
 void NetworkProcess::platformTerminate()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to