Title: [229904] trunk/Source/WebKit
Revision
229904
Author
[email protected]
Date
2018-03-23 11:02:30 -0700 (Fri, 23 Mar 2018)

Log Message

CacheStorage::Engine should not ref itself when hopping to a background thread
https://bugs.webkit.org/show_bug.cgi?id=183925
<rdar://problem/38580483>

Reviewed by Chris Dumez.

Add support for weak pointers to CacheStorage Engine.
Use weak pointer when hopping to background threads.
Store callbacks in CacheStorage::Engine maps to keep them being destroyed in the main thread only.
Made some callbacks CompletionHandler as a bonus.

Made sure to use just one Engine for all private sessions.

* NetworkProcess/cache/CacheStorageEngine.cpp:
(WebKit::CacheStorage::Engine::~Engine):
(WebKit::CacheStorage::Engine::from):
(WebKit::CacheStorage::Engine::initialize):
(WebKit::CacheStorage::Engine::writeFile):
(WebKit::CacheStorage::Engine::readFile):
* NetworkProcess/cache/CacheStorageEngine.h:
(WebKit::CacheStorage::Engine::weakPtrFactory):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (229903 => 229904)


--- trunk/Source/WebKit/ChangeLog	2018-03-23 17:48:46 UTC (rev 229903)
+++ trunk/Source/WebKit/ChangeLog	2018-03-23 18:02:30 UTC (rev 229904)
@@ -1,3 +1,27 @@
+2018-03-23  Youenn Fablet  <[email protected]>
+
+        CacheStorage::Engine should not ref itself when hopping to a background thread
+        https://bugs.webkit.org/show_bug.cgi?id=183925
+        <rdar://problem/38580483>
+
+        Reviewed by Chris Dumez.
+
+        Add support for weak pointers to CacheStorage Engine.
+        Use weak pointer when hopping to background threads.
+        Store callbacks in CacheStorage::Engine maps to keep them being destroyed in the main thread only.
+        Made some callbacks CompletionHandler as a bonus.
+
+        Made sure to use just one Engine for all private sessions.
+
+        * NetworkProcess/cache/CacheStorageEngine.cpp:
+        (WebKit::CacheStorage::Engine::~Engine):
+        (WebKit::CacheStorage::Engine::from):
+        (WebKit::CacheStorage::Engine::initialize):
+        (WebKit::CacheStorage::Engine::writeFile):
+        (WebKit::CacheStorage::Engine::readFile):
+        * NetworkProcess/cache/CacheStorageEngine.h:
+        (WebKit::CacheStorage::Engine::weakPtrFactory):
+
 2018-03-23  Ryan Haddad  <[email protected]>
 
         Unreviewed build fix.

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp (229903 => 229904)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2018-03-23 17:48:46 UTC (rev 229903)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2018-03-23 18:02:30 UTC (rev 229904)
@@ -66,10 +66,24 @@
 {
     for (auto& caches : m_caches.values())
         caches->detach();
+
+    if (m_initializationCallback)
+        m_initializationCallback(Error::Internal);
+
+    auto writeCallbacks = WTFMove(m_pendingWriteCallbacks);
+    for (auto& callback : writeCallbacks.values())
+        callback(Error::Internal);
+
+    auto readCallbacks = WTFMove(m_pendingReadCallbacks);
+    for (auto& callback : readCallbacks.values())
+        callback(Data { }, 1);
 }
 
 Engine& Engine::from(PAL::SessionID sessionID)
 {
+    if (sessionID.isEphemeral())
+        sessionID = PAL::SessionID::legacyPrivateSessionID();
+
     auto addResult = globalEngineMap().add(sessionID, nullptr);
     if (addResult.isNewEntry)
         addResult.iterator->value = Engine::create(NetworkProcess::singleton().cacheStorageDirectory(sessionID));
@@ -178,7 +192,7 @@
     });
 }
 
-void Engine::initialize(Function<void(std::optional<Error>&&)>&& callback)
+void Engine::initialize(CompletionCallback&& callback)
 {
     if (m_salt) {
         callback(std::nullopt);
@@ -190,16 +204,21 @@
         return;
     }
 
+    m_initializationCallback = WTFMove(callback);
+
     String saltPath = WebCore::FileSystem::pathByAppendingComponent(m_rootPath, ASCIILiteral("salt"));
-    m_ioQueue->dispatch([protectedThis = makeRef(*this), this, callback = WTFMove(callback), saltPath = WTFMove(saltPath)] () mutable {
+    m_ioQueue->dispatch([this, weakThis = makeWeakPtr(this), saltPath = WTFMove(saltPath)] () mutable {
         WebCore::FileSystem::makeAllDirectories(m_rootPath);
-        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), this, salt = readOrMakeSalt(saltPath), callback = WTFMove(callback)]() mutable {
+        RunLoop::main().dispatch([this, weakThis = WTFMove(weakThis), salt = readOrMakeSalt(saltPath)]() mutable {
+            if (!weakThis)
+                return;
+
             if (!salt) {
-                callback(Error::WriteDisk);
+                m_initializationCallback(Error::WriteDisk);
                 return;
             }
             m_salt = WTFMove(salt);
-            callback(std::nullopt);
+            m_initializationCallback(std::nullopt);
         });
     });
 }
@@ -277,10 +296,15 @@
         return;
     }
 
-    m_ioQueue->dispatch([callback = WTFMove(callback), data = "" filename = filename.isolatedCopy()] () mutable {
+    m_pendingWriteCallbacks.add(++m_pendingCallbacksCounter, WTFMove(callback));
+    m_ioQueue->dispatch([this, weakThis = makeWeakPtr(this), identifier = m_pendingCallbacksCounter, data = "" filename = filename.isolatedCopy()] () mutable {
         auto channel = IOChannel::open(filename, IOChannel::Type::Create);
-        channel->write(0, data, nullptr, [callback = WTFMove(callback)](int error) mutable {
+        channel->write(0, data, nullptr, [this, weakThis = WTFMove(weakThis), identifier](int error) mutable {
             ASSERT(RunLoop::isMain());
+            if (!weakThis)
+                return;
+
+            auto callback = m_pendingWriteCallbacks.take(identifier);
             if (error) {
                 RELEASE_LOG_ERROR(CacheStorage, "CacheStorage::Engine::writeFile failed with error %d", error);
 
@@ -292,7 +316,7 @@
     });
 }
 
-void Engine::readFile(const String& filename, WTF::Function<void(const NetworkCache::Data&, int error)>&& callback)
+void Engine::readFile(const String& filename, CompletionHandler<void(const NetworkCache::Data&, int error)>&& callback)
 {
     if (!shouldPersist()) {
         callback(Data { }, 0);
@@ -299,21 +323,29 @@
         return;
     }
 
-    m_ioQueue->dispatch([callback = WTFMove(callback), filename = filename.isolatedCopy()]() mutable {
+    m_pendingReadCallbacks.add(++m_pendingCallbacksCounter, WTFMove(callback));
+    m_ioQueue->dispatch([this, weakThis = makeWeakPtr(this), identifier = m_pendingCallbacksCounter, filename = filename.isolatedCopy()]() mutable {
         auto channel = IOChannel::open(filename, IOChannel::Type::Read);
         if (channel->fileDescriptor() < 0) {
-            RunLoop::main().dispatch([callback = WTFMove(callback)]() mutable {
-                callback(Data { }, 0);
+            RunLoop::main().dispatch([this, weakThis = WTFMove(weakThis), identifier]() mutable {
+                if (!weakThis)
+                    return;
+
+                m_pendingReadCallbacks.take(identifier)(Data { }, 0);
             });
             return;
         }
 
-        channel->read(0, std::numeric_limits<size_t>::max(), nullptr, [callback = WTFMove(callback)](const Data& data, int error) mutable {
+        channel->read(0, std::numeric_limits<size_t>::max(), nullptr, [this, weakThis = WTFMove(weakThis), identifier](const Data& data, int error) mutable {
             RELEASE_LOG_ERROR_IF(error, CacheStorage, "CacheStorage::Engine::readFile failed with error %d", error);
 
             // FIXME: We should do the decoding in the background thread.
             ASSERT(RunLoop::isMain());
-            callback(data, error);
+
+            if (!weakThis)
+                return;
+
+            m_pendingReadCallbacks.take(identifier)(data, error);
         });
     });
 }

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h (229903 => 229904)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h	2018-03-23 17:48:46 UTC (rev 229903)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h	2018-03-23 18:02:30 UTC (rev 229904)
@@ -30,7 +30,8 @@
 #include "WebsiteData.h"
 #include <WebCore/ClientOrigin.h>
 #include <wtf/HashMap.h>
-#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/RefCounted.h>
+#include <wtf/WeakPtr.h>
 #include <wtf/WorkQueue.h>
 
 namespace IPC {
@@ -52,7 +53,7 @@
 using CacheIdentifier = uint64_t;
 using LockCount = uint64_t;
 
-class Engine : public ThreadSafeRefCounted<Engine> {
+class Engine : public RefCounted<Engine> {
 public:
     ~Engine();
 
@@ -76,7 +77,7 @@
     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 readFile(const String& filename, CompletionHandler<void(const NetworkCache::Data&, int error)>&&);
     void removeFile(const String& filename);
 
     const String& rootPath() const { return m_rootPath; }
@@ -89,6 +90,8 @@
     void clearAllCaches(WTF::CallbackAggregator&);
     void clearCachesForOrigin(const WebCore::SecurityOriginData&, WTF::CallbackAggregator&);
 
+    WeakPtrFactory<Engine>& weakPtrFactory() { return m_weakFactory; }
+
 private:
     static Engine& defaultEngine();
     explicit Engine(String&& rootPath);
@@ -97,7 +100,7 @@
 
     void fetchEntries(bool /* shouldComputeSize */, WTF::CompletionHandler<void(Vector<WebsiteData::Entry>)>&&);
 
-    void initialize(WTF::Function<void(std::optional<WebCore::DOMCacheEngine::Error>&&)>&&);
+    void initialize(WebCore::DOMCacheEngine::CompletionCallback&&);
 
     using CachesOrError = Expected<std::reference_wrapper<Caches>, WebCore::DOMCacheEngine::Error>;
     using CachesCallback = WTF::Function<void(CachesOrError&&)>;
@@ -115,6 +118,11 @@
     RefPtr<WorkQueue> m_ioQueue;
     std::optional<NetworkCache::Salt> m_salt;
     HashMap<CacheIdentifier, LockCount> m_cacheLocks;
+    WebCore::DOMCacheEngine::CompletionCallback m_initializationCallback;
+    WeakPtrFactory<Engine> m_weakFactory;
+    HashMap<uint64_t, WebCore::DOMCacheEngine::CompletionCallback> m_pendingWriteCallbacks;
+    HashMap<uint64_t, CompletionHandler<void(const NetworkCache::Data&, int error)>> m_pendingReadCallbacks;
+    uint64_t m_pendingCallbacksCounter { 0 };
 };
 
 } // namespace CacheStorage
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to