Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (179707 => 179708)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp 2015-02-05 22:13:10 UTC (rev 179707)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp 2015-02-05 22:17:22 UTC (rev 179708)
@@ -281,7 +281,7 @@
return false;
}
-void NetworkCache::store(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response, PassRefPtr<WebCore::SharedBuffer> responseData)
+void NetworkCache::store(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, std::function<void (MappedBody&)> completionHandler)
{
ASSERT(isEnabled());
ASSERT(responseData);
@@ -294,9 +294,19 @@
}
auto key = makeCacheKey(originalRequest);
- auto storageEntry = encodeStorageEntry(originalRequest, response, responseData);
+ auto storageEntry = encodeStorageEntry(originalRequest, response, WTF::move(responseData));
- m_storage->store(key, storageEntry, [](bool success) {
+ m_storage->store(key, storageEntry, [completionHandler](bool success, const NetworkCacheStorage::Data& bodyData) {
+ MappedBody mappedBody;
+#if ENABLE(SHAREABLE_RESOURCE)
+ if (bodyData.isMap()) {
+ RefPtr<SharedMemory> sharedMemory = SharedMemory::createFromVMBuffer(const_cast<uint8_t*>(bodyData.data()), bodyData.size());
+ mappedBody.shareableResource = sharedMemory ? ShareableResource::create(WTF::move(sharedMemory), 0, bodyData.size()) : nullptr;
+ if (mappedBody.shareableResource)
+ mappedBody.shareableResource->createHandle(mappedBody.shareableResourceHandle);
+ }
+#endif
+ completionHandler(mappedBody);
LOG(NetworkCache, "(NetworkProcess) store success=%d", success);
});
}
@@ -311,7 +321,7 @@
auto key = makeCacheKey(originalRequest);
auto updateEntry = encodeStorageEntry(originalRequest, response, entry.buffer);
- m_storage->update(key, updateEntry, entry.storageEntry, [](bool success) {
+ m_storage->update(key, updateEntry, entry.storageEntry, [](bool success, const NetworkCacheStorage::Data&) {
LOG(NetworkCache, "(NetworkProcess) updated, success=%d", success);
});
}
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h (179707 => 179708)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h 2015-02-05 22:13:10 UTC (rev 179707)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h 2015-02-05 22:17:22 UTC (rev 179708)
@@ -59,6 +59,12 @@
: m_ptr(nullptr)
{
}
+ DispatchPtr(T ptr)
+ : m_ptr(ptr)
+ {
+ if (m_ptr)
+ dispatch_retain(m_ptr);
+ }
DispatchPtr(const DispatchPtr& other)
: m_ptr(other.m_ptr)
{
@@ -137,10 +143,13 @@
Data body;
};
// This may call completion handler synchronously on failure.
- void retrieve(const NetworkCacheKey&, unsigned priority, std::function<bool (std::unique_ptr<Entry>)>);
- void store(const NetworkCacheKey&, const Entry&, std::function<void (bool success)>);
- void update(const NetworkCacheKey&, const Entry& updateEntry, const Entry& existingEntry, std::function<void (bool success)>);
+ typedef std::function<bool (std::unique_ptr<Entry>)> RetrieveCompletionHandler;
+ void retrieve(const NetworkCacheKey&, unsigned priority, RetrieveCompletionHandler&&);
+ typedef std::function<void (bool success, const Data& mappedBody)> StoreCompletionHandler;
+ void store(const NetworkCacheKey&, const Entry&, StoreCompletionHandler&&);
+ void update(const NetworkCacheKey&, const Entry& updateEntry, const Entry& existingEntry, StoreCompletionHandler&&);
+
void setMaximumSize(size_t);
void clear();
@@ -156,7 +165,7 @@
struct RetrieveOperation {
NetworkCacheKey key;
- std::function<bool (std::unique_ptr<Entry>)> completionHandler;
+ RetrieveCompletionHandler completionHandler;
};
void dispatchRetrieveOperation(std::unique_ptr<const RetrieveOperation>);
void dispatchPendingRetrieveOperations();
@@ -164,14 +173,14 @@
struct StoreOperation {
NetworkCacheKey key;
Entry entry;
- std::function<void (bool success)> completionHandler;
+ StoreCompletionHandler completionHandler;
};
struct UpdateOperation {
NetworkCacheKey key;
Entry entry;
Entry existingEntry;
- std::function<void (bool success)> completionHandler;
+ StoreCompletionHandler completionHandler;
};
const String m_directoryPath;
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorageCocoa.mm (179707 => 179708)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorageCocoa.mm 2015-02-05 22:13:10 UTC (rev 179707)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorageCocoa.mm 2015-02-05 22:17:22 UTC (rev 179708)
@@ -81,6 +81,8 @@
NetworkCacheStorage::Data::Data(DispatchPtr<dispatch_data_t> dispatchData, Backing backing)
{
+ if (!dispatchData)
+ return;
const void* data;
m_dispatchData = adoptDispatch(dispatch_data_create_map(dispatchData.get(), &data, &m_size));
m_data = static_cast<const uint8_t*>(data);
@@ -164,7 +166,7 @@
switch (type) {
case FileOpenType::Create:
- oflag = O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK;
+ oflag = O_RDWR | O_CREAT | O_TRUNC | O_NONBLOCK;
mode = S_IRUSR | S_IWUSR;
WebCore::makeAllDirectories(directoryPathForKey(key, cachePath));
break;
@@ -250,6 +252,17 @@
return success;
}
+static DispatchPtr<dispatch_data_t> mapFile(int fd, size_t offset, size_t size)
+{
+ void* map = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, offset);
+ if (map == MAP_FAILED)
+ return nullptr;
+ auto bodyMap = adoptDispatch(dispatch_data_create(map, size, dispatch_get_main_queue(), [map, size] {
+ munmap(map, size);
+ }));
+ return bodyMap;
+}
+
static std::unique_ptr<NetworkCacheStorage::Entry> decodeEntry(dispatch_data_t fileData, int fd, const NetworkCacheKey& key)
{
EntryMetaData metaData;
@@ -270,17 +283,13 @@
LOG(NetworkCacheStorage, "(NetworkProcess) header checksum mismatch");
return nullptr;
}
- size_t mapSize = metaData.bodySize;
- void* map = mmap(nullptr, mapSize, PROT_READ, MAP_PRIVATE, fd, metaData.bodyOffset);
- if (!map) {
+
+ auto bodyData = mapFile(fd, metaData.bodyOffset, metaData.bodySize);
+ if (!bodyData) {
LOG(NetworkCacheStorage, "(NetworkProcess) map failed");
return nullptr;
}
- auto bodyData = adoptDispatch(dispatch_data_create(map, metaData.bodySize, dispatch_get_main_queue(), [map, mapSize] {
- munmap(map, mapSize);
- }));
-
if (metaData.bodyChecksum != hashData(bodyData.get())) {
LOG(NetworkCacheStorage, "(NetworkProcess) data checksum mismatch");
return nullptr;
@@ -331,12 +340,6 @@
return adoptDispatch(dispatch_data_create_concat(headerData.get(), alignmentData.get()));
}
-static DispatchPtr<dispatch_data_t> encodeEntry(const NetworkCacheKey& key, const NetworkCacheStorage::Entry& entry)
-{
- auto encodedHeader = encodeEntryHeader(key, entry);
- return adoptDispatch(dispatch_data_create_concat(encodedHeader.get(), entry.body.dispatchData()));
-}
-
void NetworkCacheStorage::removeEntry(const NetworkCacheKey& key)
{
ASSERT(RunLoop::isMain());
@@ -407,7 +410,7 @@
}
}
-template <class T> bool retrieveActive(const T& operations, const NetworkCacheKey& key, std::function<bool (std::unique_ptr<NetworkCacheStorage::Entry>)>& completionHandler)
+template <class T> bool retrieveActive(const T& operations, const NetworkCacheKey& key, NetworkCacheStorage::RetrieveCompletionHandler& completionHandler)
{
for (auto& operation : operations) {
if (operation->key == key) {
@@ -422,7 +425,7 @@
return false;
}
-void NetworkCacheStorage::retrieve(const NetworkCacheKey& key, unsigned priority, std::function<bool (std::unique_ptr<Entry>)> completionHandler)
+void NetworkCacheStorage::retrieve(const NetworkCacheKey& key, unsigned priority, RetrieveCompletionHandler&& completionHandler)
{
ASSERT(RunLoop::isMain());
ASSERT(priority <= maximumRetrievePriority);
@@ -438,28 +441,32 @@
return;
// Fetch from disk.
- m_pendingRetrieveOperationsByPriority[priority].append(std::make_unique<RetrieveOperation>(RetrieveOperation { key, completionHandler }));
+ m_pendingRetrieveOperationsByPriority[priority].append(std::make_unique<RetrieveOperation>(RetrieveOperation { key, WTF::move(completionHandler) }));
dispatchPendingRetrieveOperations();
}
-void NetworkCacheStorage::store(const NetworkCacheKey& key, const Entry& entry, std::function<void (bool success)> completionHandler)
+void NetworkCacheStorage::store(const NetworkCacheKey& key, const Entry& entry, StoreCompletionHandler&& completionHandler)
{
ASSERT(RunLoop::isMain());
m_contentsFilter.add(key.hash());
++m_approximateEntryCount;
- auto storeOperation = std::make_unique<StoreOperation>(StoreOperation { key, entry, completionHandler });
+ auto storeOperation = std::make_unique<StoreOperation>(StoreOperation { key, entry, WTF::move(completionHandler) });
auto& store = *storeOperation;
m_activeStoreOperations.add(WTF::move(storeOperation));
StringCapture cachePathCapture(m_directoryPath);
dispatch_async(m_backgroundIOQueue.get(), [this, &store, cachePathCapture] {
- auto data = "" store.entry);
+ auto encodedHeader = encodeEntryHeader(store.key, store.entry);
+ auto writeData = adoptDispatch(dispatch_data_create_concat(encodedHeader.get(), store.entry.body.dispatchData()));
+ size_t bodyOffset = dispatch_data_get_size(encodedHeader.get());
+ size_t bodySize = store.entry.body.size();
+
int fd;
auto channel = openFileForKey(store.key, FileOpenType::Create, cachePathCapture.string(), fd);
- dispatch_io_write(channel.get(), 0, data.get(), dispatch_get_main_queue(), [this, &store](bool done, dispatch_data_t, int error) {
+ dispatch_io_write(channel.get(), 0, writeData.get(), dispatch_get_main_queue(), [this, &store, fd, bodyOffset, bodySize](bool done, dispatch_data_t, int error) {
ASSERT_UNUSED(done, done);
LOG(NetworkCacheStorage, "(NetworkProcess) write complete error=%d", error);
if (error) {
@@ -469,8 +476,12 @@
--m_approximateEntryCount;
}
- store.completionHandler(!error);
+ bool shouldMapBody = !error && bodySize >= vm_page_size;
+ auto bodyMap = shouldMapBody ? mapFile(fd, bodyOffset, bodySize) : nullptr;
+ Data bodyData(bodyMap, Data::Backing::Map);
+ store.completionHandler(!error, bodyData);
+
m_activeStoreOperations.remove(&store);
});
});
@@ -478,17 +489,17 @@
shrinkIfNeeded();
}
-void NetworkCacheStorage::update(const NetworkCacheKey& key, const Entry& updateEntry, const Entry& existingEntry, std::function<void (bool success)> completionHandler)
+void NetworkCacheStorage::update(const NetworkCacheKey& key, const Entry& updateEntry, const Entry& existingEntry, StoreCompletionHandler&& completionHandler)
{
ASSERT(RunLoop::isMain());
if (!m_contentsFilter.mayContain(key.hash())) {
LOG(NetworkCacheStorage, "(NetworkProcess) existing entry not found, storing full entry");
- store(key, updateEntry, completionHandler);
+ store(key, updateEntry, WTF::move(completionHandler));
return;
}
- auto updateOperation = std::make_unique<UpdateOperation>(UpdateOperation { key, updateEntry, existingEntry, completionHandler });
+ auto updateOperation = std::make_unique<UpdateOperation>(UpdateOperation { key, updateEntry, existingEntry, WTF::move(completionHandler) });
auto& update = *updateOperation;
m_activeUpdateOperations.add(WTF::move(updateOperation));
@@ -502,7 +513,7 @@
if (pageRoundedHeaderSizeChanged) {
LOG(NetworkCacheStorage, "(NetworkProcess) page-rounded header size changed, storing full entry");
dispatch_async(dispatch_get_main_queue(), [this, &update] {
- store(update.key, update.entry, update.completionHandler);
+ store(update.key, update.entry, WTF::move(update.completionHandler));
ASSERT(m_activeUpdateOperations.contains(&update));
m_activeUpdateOperations.remove(&update);
@@ -519,7 +530,7 @@
if (error)
removeEntry(update.key);
- update.completionHandler(!error);
+ update.completionHandler(!error, Data());
ASSERT(m_activeUpdateOperations.contains(&update));
m_activeUpdateOperations.remove(&update);