Changeset 179708 in webkit
- Timestamp:
- Feb 5, 2015 2:17:22 PM (9 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r179707 r179708 1 2015-02-05 Antti Koivisto <antti@apple.com> 2 3 Switch to file backed buffer when resource is cached to disk 4 https://bugs.webkit.org/show_bug.cgi?id=141295 5 6 Reviewed by Chris Dumez. 7 8 Wire the DidCacheResource mechanism to the new disk cache. 9 10 * NetworkProcess/NetworkResourceLoader.cpp: 11 (WebKit::NetworkResourceLoader::didFinishLoading): 12 13 Send DidCacheResource message to the web process so it can switch the resource to file backing. 14 15 * NetworkProcess/cache/NetworkCache.cpp: 16 (WebKit::NetworkCache::store): 17 (WebKit::NetworkCache::update): 18 * NetworkProcess/cache/NetworkCache.h: 19 * NetworkProcess/cache/NetworkCacheStorage.h: 20 (WebKit::DispatchPtr::DispatchPtr): 21 * NetworkProcess/cache/NetworkCacheStorageCocoa.mm: 22 (WebKit::NetworkCacheStorage::Data::Data): 23 (WebKit::mapFile): 24 (WebKit::decodeEntry): 25 (WebKit::retrieveActive): 26 (WebKit::NetworkCacheStorage::retrieve): 27 (WebKit::NetworkCacheStorage::store): 28 29 Map files larger than a memory page after a successful store. 30 31 (WebKit::NetworkCacheStorage::update): 32 (WebKit::encodeEntry): Deleted. 33 1 34 2015-02-05 Chris Dumez <cdumez@apple.com> 2 35 -
trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp
r179409 r179708 337 337 338 338 bool isPrivate = sessionID().isEphemeral(); 339 if (hasCacheableRedirect && !isPrivate) 340 NetworkCache::singleton().store(originalRequest(), m_response, m_bufferedDataForCache.release()); 339 if (hasCacheableRedirect && !isPrivate) { 340 // Keep the connection alive. 341 RefPtr<NetworkConnectionToWebProcess> connection(connectionToWebProcess()); 342 RefPtr<NetworkResourceLoader> loader(this); 343 NetworkCache::singleton().store(originalRequest(), m_response, WTF::move(m_bufferedDataForCache), [loader, connection](NetworkCache::MappedBody& mappedBody) { 344 #if ENABLE(SHAREABLE_RESOURCE) 345 if (mappedBody.shareableResourceHandle.isNull()) 346 return; 347 LOG(NetworkCache, "(NetworkProcess) sending DidCacheResource"); 348 loader->send(Messages::NetworkProcessConnection::DidCacheResource(loader->originalRequest(), mappedBody.shareableResourceHandle, loader->sessionID())); 349 #endif 350 }); 351 } 341 352 } 342 353 #endif -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp
r179690 r179708 282 282 } 283 283 284 void NetworkCache::store(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response, PassRefPtr<WebCore::SharedBuffer> responseData)284 void NetworkCache::store(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, std::function<void (MappedBody&)> completionHandler) 285 285 { 286 286 ASSERT(isEnabled()); … … 295 295 296 296 auto key = makeCacheKey(originalRequest); 297 auto storageEntry = encodeStorageEntry(originalRequest, response, responseData); 298 299 m_storage->store(key, storageEntry, [](bool success) { 297 auto storageEntry = encodeStorageEntry(originalRequest, response, WTF::move(responseData)); 298 299 m_storage->store(key, storageEntry, [completionHandler](bool success, const NetworkCacheStorage::Data& bodyData) { 300 MappedBody mappedBody; 301 #if ENABLE(SHAREABLE_RESOURCE) 302 if (bodyData.isMap()) { 303 RefPtr<SharedMemory> sharedMemory = SharedMemory::createFromVMBuffer(const_cast<uint8_t*>(bodyData.data()), bodyData.size()); 304 mappedBody.shareableResource = sharedMemory ? ShareableResource::create(WTF::move(sharedMemory), 0, bodyData.size()) : nullptr; 305 if (mappedBody.shareableResource) 306 mappedBody.shareableResource->createHandle(mappedBody.shareableResourceHandle); 307 } 308 #endif 309 completionHandler(mappedBody); 300 310 LOG(NetworkCache, "(NetworkProcess) store success=%d", success); 301 311 }); … … 312 322 auto updateEntry = encodeStorageEntry(originalRequest, response, entry.buffer); 313 323 314 m_storage->update(key, updateEntry, entry.storageEntry, [](bool success ) {324 m_storage->update(key, updateEntry, entry.storageEntry, [](bool success, const NetworkCacheStorage::Data&) { 315 325 LOG(NetworkCache, "(NetworkProcess) updated, success=%d", success); 316 326 }); -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h
r179546 r179708 64 64 // Completion handler may get called back synchronously on failure. 65 65 void retrieve(const WebCore::ResourceRequest&, std::function<void (std::unique_ptr<Entry>)>); 66 void store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, PassRefPtr<WebCore::SharedBuffer>); 66 67 struct MappedBody { 68 #if ENABLE(SHAREABLE_RESOURCE) 69 RefPtr<ShareableResource> shareableResource; 70 ShareableResource::Handle shareableResourceHandle; 71 #endif 72 }; 73 void store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, std::function<void (MappedBody&)>); 67 74 void update(const WebCore::ResourceRequest&, const Entry&, const WebCore::ResourceResponse& validatingResponse); 68 75 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h
r179690 r179708 60 60 { 61 61 } 62 DispatchPtr(T ptr) 63 : m_ptr(ptr) 64 { 65 if (m_ptr) 66 dispatch_retain(m_ptr); 67 } 62 68 DispatchPtr(const DispatchPtr& other) 63 69 : m_ptr(other.m_ptr) … … 138 144 }; 139 145 // This may call completion handler synchronously on failure. 140 void retrieve(const NetworkCacheKey&, unsigned priority, std::function<bool (std::unique_ptr<Entry>)>); 141 void store(const NetworkCacheKey&, const Entry&, std::function<void (bool success)>); 142 void update(const NetworkCacheKey&, const Entry& updateEntry, const Entry& existingEntry, std::function<void (bool success)>); 146 typedef std::function<bool (std::unique_ptr<Entry>)> RetrieveCompletionHandler; 147 void retrieve(const NetworkCacheKey&, unsigned priority, RetrieveCompletionHandler&&); 148 149 typedef std::function<void (bool success, const Data& mappedBody)> StoreCompletionHandler; 150 void store(const NetworkCacheKey&, const Entry&, StoreCompletionHandler&&); 151 void update(const NetworkCacheKey&, const Entry& updateEntry, const Entry& existingEntry, StoreCompletionHandler&&); 143 152 144 153 void setMaximumSize(size_t); … … 157 166 struct RetrieveOperation { 158 167 NetworkCacheKey key; 159 std::function<bool (std::unique_ptr<Entry>)>completionHandler;168 RetrieveCompletionHandler completionHandler; 160 169 }; 161 170 void dispatchRetrieveOperation(std::unique_ptr<const RetrieveOperation>); … … 165 174 NetworkCacheKey key; 166 175 Entry entry; 167 std::function<void (bool success)>completionHandler;176 StoreCompletionHandler completionHandler; 168 177 }; 169 178 … … 172 181 Entry entry; 173 182 Entry existingEntry; 174 std::function<void (bool success)>completionHandler;183 StoreCompletionHandler completionHandler; 175 184 }; 176 185 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorageCocoa.mm
r179704 r179708 82 82 NetworkCacheStorage::Data::Data(DispatchPtr<dispatch_data_t> dispatchData, Backing backing) 83 83 { 84 if (!dispatchData) 85 return; 84 86 const void* data; 85 87 m_dispatchData = adoptDispatch(dispatch_data_create_map(dispatchData.get(), &data, &m_size)); … … 165 167 switch (type) { 166 168 case FileOpenType::Create: 167 oflag = O_ WRONLY| O_CREAT | O_TRUNC | O_NONBLOCK;169 oflag = O_RDWR | O_CREAT | O_TRUNC | O_NONBLOCK; 168 170 mode = S_IRUSR | S_IWUSR; 169 171 WebCore::makeAllDirectories(directoryPathForKey(key, cachePath)); … … 251 253 } 252 254 255 static DispatchPtr<dispatch_data_t> mapFile(int fd, size_t offset, size_t size) 256 { 257 void* map = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, offset); 258 if (map == MAP_FAILED) 259 return nullptr; 260 auto bodyMap = adoptDispatch(dispatch_data_create(map, size, dispatch_get_main_queue(), [map, size] { 261 munmap(map, size); 262 })); 263 return bodyMap; 264 } 265 253 266 static std::unique_ptr<NetworkCacheStorage::Entry> decodeEntry(dispatch_data_t fileData, int fd, const NetworkCacheKey& key) 254 267 { … … 271 284 return nullptr; 272 285 } 273 size_t mapSize = metaData.bodySize; 274 void* map = mmap(nullptr, mapSize, PROT_READ, MAP_PRIVATE, fd, metaData.bodyOffset);275 if (! map) {286 287 auto bodyData = mapFile(fd, metaData.bodyOffset, metaData.bodySize); 288 if (!bodyData) { 276 289 LOG(NetworkCacheStorage, "(NetworkProcess) map failed"); 277 290 return nullptr; 278 291 } 279 280 auto bodyData = adoptDispatch(dispatch_data_create(map, metaData.bodySize, dispatch_get_main_queue(), [map, mapSize] {281 munmap(map, mapSize);282 }));283 292 284 293 if (metaData.bodyChecksum != hashData(bodyData.get())) { … … 330 339 auto alignmentData = adoptDispatch(dispatch_data_create(filler.data(), filler.size(), nullptr, DISPATCH_DATA_DESTRUCTOR_DEFAULT)); 331 340 return adoptDispatch(dispatch_data_create_concat(headerData.get(), alignmentData.get())); 332 }333 334 static DispatchPtr<dispatch_data_t> encodeEntry(const NetworkCacheKey& key, const NetworkCacheStorage::Entry& entry)335 {336 auto encodedHeader = encodeEntryHeader(key, entry);337 return adoptDispatch(dispatch_data_create_concat(encodedHeader.get(), entry.body.dispatchData()));338 341 } 339 342 … … 408 411 } 409 412 410 template <class T> bool retrieveActive(const T& operations, const NetworkCacheKey& key, std::function<bool (std::unique_ptr<NetworkCacheStorage::Entry>)>& completionHandler)413 template <class T> bool retrieveActive(const T& operations, const NetworkCacheKey& key, NetworkCacheStorage::RetrieveCompletionHandler& completionHandler) 411 414 { 412 415 for (auto& operation : operations) { … … 423 426 } 424 427 425 void NetworkCacheStorage::retrieve(const NetworkCacheKey& key, unsigned priority, std::function<bool (std::unique_ptr<Entry>)>completionHandler)428 void NetworkCacheStorage::retrieve(const NetworkCacheKey& key, unsigned priority, RetrieveCompletionHandler&& completionHandler) 426 429 { 427 430 ASSERT(RunLoop::isMain()); … … 439 442 440 443 // Fetch from disk. 441 m_pendingRetrieveOperationsByPriority[priority].append(std::make_unique<RetrieveOperation>(RetrieveOperation { key, completionHandler}));444 m_pendingRetrieveOperationsByPriority[priority].append(std::make_unique<RetrieveOperation>(RetrieveOperation { key, WTF::move(completionHandler) })); 442 445 dispatchPendingRetrieveOperations(); 443 446 } 444 447 445 void NetworkCacheStorage::store(const NetworkCacheKey& key, const Entry& entry, std::function<void (bool success)>completionHandler)448 void NetworkCacheStorage::store(const NetworkCacheKey& key, const Entry& entry, StoreCompletionHandler&& completionHandler) 446 449 { 447 450 ASSERT(RunLoop::isMain()); … … 450 453 ++m_approximateEntryCount; 451 454 452 auto storeOperation = std::make_unique<StoreOperation>(StoreOperation { key, entry, completionHandler});455 auto storeOperation = std::make_unique<StoreOperation>(StoreOperation { key, entry, WTF::move(completionHandler) }); 453 456 auto& store = *storeOperation; 454 457 m_activeStoreOperations.add(WTF::move(storeOperation)); … … 456 459 StringCapture cachePathCapture(m_directoryPath); 457 460 dispatch_async(m_backgroundIOQueue.get(), [this, &store, cachePathCapture] { 458 auto data = encodeEntry(store.key, store.entry); 461 auto encodedHeader = encodeEntryHeader(store.key, store.entry); 462 auto writeData = adoptDispatch(dispatch_data_create_concat(encodedHeader.get(), store.entry.body.dispatchData())); 463 464 size_t bodyOffset = dispatch_data_get_size(encodedHeader.get()); 465 size_t bodySize = store.entry.body.size(); 459 466 460 467 int fd; 461 468 auto channel = openFileForKey(store.key, FileOpenType::Create, cachePathCapture.string(), fd); 462 dispatch_io_write(channel.get(), 0, data.get(), dispatch_get_main_queue(), [this, &store](bool done, dispatch_data_t, int error) {469 dispatch_io_write(channel.get(), 0, writeData.get(), dispatch_get_main_queue(), [this, &store, fd, bodyOffset, bodySize](bool done, dispatch_data_t, int error) { 463 470 ASSERT_UNUSED(done, done); 464 471 LOG(NetworkCacheStorage, "(NetworkProcess) write complete error=%d", error); … … 470 477 } 471 478 472 store.completionHandler(!error); 479 bool shouldMapBody = !error && bodySize >= vm_page_size; 480 auto bodyMap = shouldMapBody ? mapFile(fd, bodyOffset, bodySize) : nullptr; 481 482 Data bodyData(bodyMap, Data::Backing::Map); 483 store.completionHandler(!error, bodyData); 473 484 474 485 m_activeStoreOperations.remove(&store); … … 479 490 } 480 491 481 void NetworkCacheStorage::update(const NetworkCacheKey& key, const Entry& updateEntry, const Entry& existingEntry, std::function<void (bool success)>completionHandler)492 void NetworkCacheStorage::update(const NetworkCacheKey& key, const Entry& updateEntry, const Entry& existingEntry, StoreCompletionHandler&& completionHandler) 482 493 { 483 494 ASSERT(RunLoop::isMain()); … … 485 496 if (!m_contentsFilter.mayContain(key.hash())) { 486 497 LOG(NetworkCacheStorage, "(NetworkProcess) existing entry not found, storing full entry"); 487 store(key, updateEntry, completionHandler);488 return; 489 } 490 491 auto updateOperation = std::make_unique<UpdateOperation>(UpdateOperation { key, updateEntry, existingEntry, completionHandler});498 store(key, updateEntry, WTF::move(completionHandler)); 499 return; 500 } 501 502 auto updateOperation = std::make_unique<UpdateOperation>(UpdateOperation { key, updateEntry, existingEntry, WTF::move(completionHandler) }); 492 503 auto& update = *updateOperation; 493 504 m_activeUpdateOperations.add(WTF::move(updateOperation)); … … 503 514 LOG(NetworkCacheStorage, "(NetworkProcess) page-rounded header size changed, storing full entry"); 504 515 dispatch_async(dispatch_get_main_queue(), [this, &update] { 505 store(update.key, update.entry, update.completionHandler);516 store(update.key, update.entry, WTF::move(update.completionHandler)); 506 517 507 518 ASSERT(m_activeUpdateOperations.contains(&update)); … … 520 531 removeEntry(update.key); 521 532 522 update.completionHandler(!error );533 update.completionHandler(!error, Data()); 523 534 524 535 ASSERT(m_activeUpdateOperations.contains(&update));
Note: See TracChangeset
for help on using the changeset viewer.