Diff
Modified: trunk/Source/WebKit2/ChangeLog (183754 => 183755)
--- trunk/Source/WebKit2/ChangeLog 2015-05-04 18:47:33 UTC (rev 183754)
+++ trunk/Source/WebKit2/ChangeLog 2015-05-04 18:51:36 UTC (rev 183755)
@@ -1,3 +1,34 @@
+2015-05-04 Antti Koivisto <[email protected]>
+
+ Network Cache: Support time based cache clearing
+ https://bugs.webkit.org/show_bug.cgi?id=144568
+ <rdar://problem/19769820>
+
+ Reviewed by Andreas Kling.
+
+ Support clearing cache entries newer than given time only.
+
+ * NetworkProcess/cache/NetworkCache.cpp:
+ (WebKit::NetworkCache::Cache::deleteDumpFile):
+ (WebKit::NetworkCache::Storage::traverse):
+
+ Also fix thread safety of traverse handler function.
+
+ (WebKit::NetworkCache::Cache::clear):
+
+ Also add completion handler to support the API properly.
+
+ * NetworkProcess/cache/NetworkCache.h:
+ * NetworkProcess/cache/NetworkCacheStorage.cpp:
+ (WebKit::NetworkCache::Storage::clear):
+ * NetworkProcess/cache/NetworkCacheStorage.h:
+ * NetworkProcess/cocoa/NetworkProcessCocoa.mm:
+ (WebKit::clearNSURLCache):
+
+ Factor to a function.
+
+ (WebKit::NetworkProcess::clearDiskCache):
+
2015-05-04 Zan Dobersek <[email protected]>
[WTF] Remove Functional.h inclusions
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (183754 => 183755)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp 2015-05-04 18:47:33 UTC (rev 183754)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp 2015-05-04 18:51:36 UTC (rev 183755)
@@ -40,6 +40,7 @@
#include <WebCore/ResourceResponse.h>
#include <WebCore/SharedBuffer.h>
#include <wtf/NeverDestroyed.h>
+#include <wtf/RunLoop.h>
#include <wtf/text/StringBuilder.h>
#if PLATFORM(COCOA)
@@ -524,22 +525,35 @@
});
}
-void Cache::clear()
+void Cache::deleteDumpFile()
{
+ auto queue = WorkQueue::create("com.apple.WebKit.Cache.delete");
+ StringCapture dumpFilePathCapture(dumpFilePath());
+ queue->dispatch([dumpFilePathCapture] {
+ WebCore::deleteFile(dumpFilePathCapture.string());
+ });
+}
+
+void Cache::clear(std::chrono::system_clock::time_point modifiedSince, std::function<void ()>&& completionHandler)
+{
LOG(NetworkCache, "(NetworkProcess) clearing cache");
- if (m_storage) {
- m_storage->clear();
+ deleteDumpFile();
- auto queue = WorkQueue::create("com.apple.WebKit.Cache.delete");
- StringCapture dumpFilePathCapture(dumpFilePath());
- queue->dispatch([dumpFilePathCapture] {
- WebCore::deleteFile(dumpFilePathCapture.string());
- });
- }
if (m_statistics)
m_statistics->clear();
+
+ if (!m_storage) {
+ RunLoop::main().dispatch(completionHandler);
+ return;
+ }
+ m_storage->clear(modifiedSince, WTF::move(completionHandler));
}
+void Cache::clear()
+{
+ clear(std::chrono::system_clock::time_point::min(), nullptr);
+}
+
String Cache::recordsPath() const
{
return m_storage ? m_storage->recordsPath() : String();
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h (183754 => 183755)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h 2015-05-04 18:47:33 UTC (rev 183754)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h 2015-05-04 18:51:36 UTC (rev 183755)
@@ -101,6 +101,7 @@
void remove(const Key&);
void clear();
+ void clear(std::chrono::system_clock::time_point modifiedSince, std::function<void ()>&& completionHandler);
void dumpContentsToFile();
@@ -111,6 +112,7 @@
~Cache() = delete;
String dumpFilePath() const;
+ void deleteDumpFile();
std::unique_ptr<Storage> m_storage;
std::unique_ptr<Statistics> m_statistics;
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp (183754 => 183755)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp 2015-05-04 18:47:33 UTC (rev 183754)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp 2015-05-04 18:51:36 UTC (rev 183755)
@@ -657,9 +657,15 @@
dispatchPendingWriteOperations();
}
-void Storage::traverse(TraverseFlags flags, std::function<void (const Record*, const RecordInfo&)>&& traverseHandler)
+void Storage::traverse(TraverseFlags flags, TraverseHandler&& traverseHandler)
{
- ioQueue().dispatch([this, flags, traverseHandler] {
+ ASSERT(RunLoop::isMain());
+ ASSERT(traverseHandler);
+ // Avoid non-thread safe std::function copies.
+ auto* traverseHandlerPtr = new TraverseHandler(WTF::move(traverseHandler));
+
+ ioQueue().dispatch([this, flags, traverseHandlerPtr] {
+ auto& traverseHandler = *traverseHandlerPtr;
traverseCacheFiles(recordsPath(), [this, flags, &traverseHandler](const String& fileName, const String& partitionPath) {
if (fileName.length() != Key::hashStringLength())
return;
@@ -684,8 +690,9 @@
}
});
});
- RunLoop::main().dispatch([this, traverseHandler] {
- traverseHandler(nullptr, { });
+ RunLoop::main().dispatch([this, traverseHandlerPtr] {
+ (*traverseHandlerPtr)(nullptr, { });
+ delete traverseHandlerPtr;
});
});
}
@@ -708,7 +715,7 @@
shrinkIfNeeded();
}
-void Storage::clear()
+void Storage::clear(std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler)
{
ASSERT(RunLoop::isMain());
LOG(NetworkCacheStorage, "(NetworkProcess) clearing cache");
@@ -719,18 +726,34 @@
m_bodyFilter->clear();
m_approximateRecordsSize = 0;
- ioQueue().dispatch([this] {
+ // Avoid non-thread safe std::function copies.
+ auto* completionHandlerPtr = completionHandler ? new std::function<void ()>(WTF::move(completionHandler)) : nullptr;
+
+ ioQueue().dispatch([this, modifiedSinceTime, completionHandlerPtr] {
auto recordsPath = this->recordsPath();
- traverseDirectory(recordsPath, DT_DIR, [&recordsPath](const String& subdirName) {
+ traverseDirectory(recordsPath, DT_DIR, [&recordsPath, modifiedSinceTime](const String& subdirName) {
String subdirPath = WebCore::pathByAppendingComponent(recordsPath, subdirName);
- traverseDirectory(subdirPath, DT_REG, [&subdirPath](const String& fileName) {
- WebCore::deleteFile(WebCore::pathByAppendingComponent(subdirPath, fileName));
+ traverseDirectory(subdirPath, DT_REG, [&subdirPath, modifiedSinceTime](const String& fileName) {
+ auto filePath = WebCore::pathByAppendingComponent(subdirPath, fileName);
+ if (modifiedSinceTime > std::chrono::system_clock::time_point::min()) {
+ auto times = fileTimes(filePath);
+ if (times.modification < modifiedSinceTime)
+ return;
+ }
+ WebCore::deleteFile(filePath);
});
WebCore::deleteEmptyDirectory(subdirPath);
});
// This cleans unreferences blobs.
m_blobStorage.synchronize();
+
+ if (completionHandlerPtr) {
+ RunLoop::main().dispatch([completionHandlerPtr] {
+ (*completionHandlerPtr)();
+ delete completionHandlerPtr;
+ });
+ }
});
}
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h (183754 => 183755)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h 2015-05-04 18:47:33 UTC (rev 183754)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h 2015-05-04 18:51:36 UTC (rev 183755)
@@ -62,6 +62,7 @@
void store(const Record&, MappedBodyHandler&&);
void remove(const Key&);
+ void clear(std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler);
struct RecordInfo {
size_t bodySize { 0 };
@@ -74,12 +75,12 @@
ShareCount = 1 << 1,
};
typedef unsigned TraverseFlags;
+ typedef std::function<void (const Record*, const RecordInfo&)> TraverseHandler;
// Null record signals end.
- void traverse(TraverseFlags, std::function<void (const Record*, const RecordInfo&)>&&);
+ void traverse(TraverseFlags, TraverseHandler&&);
void setCapacity(size_t);
size_t approximateSize() const;
- void clear();
static const unsigned version = 3;
Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkProcessCocoa.mm (183754 => 183755)
--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkProcessCocoa.mm 2015-05-04 18:47:33 UTC (rev 183754)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkProcessCocoa.mm 2015-05-04 18:51:36 UTC (rev 183755)
@@ -155,16 +155,9 @@
[nsurlCache setDiskCapacity:std::max<unsigned long>(urlCacheDiskCapacity, [nsurlCache diskCapacity])]; // Don't shrink a big disk cache, since that would cause churn.
}
-void NetworkProcess::clearDiskCache(std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler)
+static void clearNSURLCache(dispatch_group_t group, std::chrono::system_clock::time_point modifiedSince, const std::function<void ()>& completionHandler)
{
-#if ENABLE(NETWORK_CACHE)
- NetworkCache::singleton().clear();
-#endif
-
- if (!m_clearCacheDispatchGroup)
- m_clearCacheDispatchGroup = dispatch_group_create();
-
- dispatch_group_async(m_clearCacheDispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [modifiedSince, completionHandler] {
+ dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [modifiedSince, completionHandler] {
NSURLCache *cache = [NSURLCache sharedURLCache];
#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
@@ -180,6 +173,24 @@
});
}
+void NetworkProcess::clearDiskCache(std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler)
+{
+ if (!m_clearCacheDispatchGroup)
+ m_clearCacheDispatchGroup = dispatch_group_create();
+
+#if ENABLE(NETWORK_CACHE)
+ auto group = m_clearCacheDispatchGroup;
+ dispatch_group_async(group, dispatch_get_main_queue(), [group, modifiedSince, completionHandler] {
+ NetworkCache::singleton().clear(modifiedSince, [group, modifiedSince, completionHandler] {
+ // FIXME: Probably not necessary.
+ clearNSURLCache(group, modifiedSince, completionHandler);
+ });
+ });
+#else
+ clearNSURLCache(m_clearCacheDispatchGroup, modifiedSince, completionHandler);
+#endif
}
+}
+
#endif