Changeset 179708 in webkit


Ignore:
Timestamp:
Feb 5, 2015 2:17:22 PM (9 years ago)
Author:
Antti Koivisto
Message:

Switch to file backed buffer when resource is cached to disk
https://bugs.webkit.org/show_bug.cgi?id=141295

Reviewed by Chris Dumez.

Wire the DidCacheResource mechanism to the new disk cache.

  • NetworkProcess/NetworkResourceLoader.cpp:

(WebKit::NetworkResourceLoader::didFinishLoading):

Send DidCacheResource message to the web process so it can switch the resource to file backing.

  • NetworkProcess/cache/NetworkCache.cpp:

(WebKit::NetworkCache::store):
(WebKit::NetworkCache::update):

  • NetworkProcess/cache/NetworkCache.h:
  • NetworkProcess/cache/NetworkCacheStorage.h:

(WebKit::DispatchPtr::DispatchPtr):

  • NetworkProcess/cache/NetworkCacheStorageCocoa.mm:

(WebKit::NetworkCacheStorage::Data::Data):
(WebKit::mapFile):
(WebKit::decodeEntry):
(WebKit::retrieveActive):
(WebKit::NetworkCacheStorage::retrieve):
(WebKit::NetworkCacheStorage::store):

Map files larger than a memory page after a successful store.

(WebKit::NetworkCacheStorage::update):
(WebKit::encodeEntry): Deleted.

Location:
trunk/Source/WebKit2
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r179707 r179708  
     12015-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
    1342015-02-05  Chris Dumez  <cdumez@apple.com>
    235
  • trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp

    r179409 r179708  
    337337
    338338        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        }
    341352    }
    342353#endif
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp

    r179690 r179708  
    282282}
    283283
    284 void NetworkCache::store(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response, PassRefPtr<WebCore::SharedBuffer> responseData)
     284void NetworkCache::store(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, std::function<void (MappedBody&)> completionHandler)
    285285{
    286286    ASSERT(isEnabled());
     
    295295
    296296    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);
    300310        LOG(NetworkCache, "(NetworkProcess) store success=%d", success);
    301311    });
     
    312322    auto updateEntry = encodeStorageEntry(originalRequest, response, entry.buffer);
    313323
    314     m_storage->update(key, updateEntry, entry.storageEntry, [](bool success) {
     324    m_storage->update(key, updateEntry, entry.storageEntry, [](bool success, const NetworkCacheStorage::Data&) {
    315325        LOG(NetworkCache, "(NetworkProcess) updated, success=%d", success);
    316326    });
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h

    r179546 r179708  
    6464    // Completion handler may get called back synchronously on failure.
    6565    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&)>);
    6774    void update(const WebCore::ResourceRequest&, const Entry&, const WebCore::ResourceResponse& validatingResponse);
    6875
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h

    r179690 r179708  
    6060    {
    6161    }
     62    DispatchPtr(T ptr)
     63        : m_ptr(ptr)
     64    {
     65        if (m_ptr)
     66            dispatch_retain(m_ptr);
     67    }
    6268    DispatchPtr(const DispatchPtr& other)
    6369        : m_ptr(other.m_ptr)
     
    138144    };
    139145    // 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&&);
    143152
    144153    void setMaximumSize(size_t);
     
    157166    struct RetrieveOperation {
    158167        NetworkCacheKey key;
    159         std::function<bool (std::unique_ptr<Entry>)> completionHandler;
     168        RetrieveCompletionHandler completionHandler;
    160169    };
    161170    void dispatchRetrieveOperation(std::unique_ptr<const RetrieveOperation>);
     
    165174        NetworkCacheKey key;
    166175        Entry entry;
    167         std::function<void (bool success)> completionHandler;
     176        StoreCompletionHandler completionHandler;
    168177    };
    169178
     
    172181        Entry entry;
    173182        Entry existingEntry;
    174         std::function<void (bool success)> completionHandler;
     183        StoreCompletionHandler completionHandler;
    175184    };
    176185
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorageCocoa.mm

    r179704 r179708  
    8282NetworkCacheStorage::Data::Data(DispatchPtr<dispatch_data_t> dispatchData, Backing backing)
    8383{
     84    if (!dispatchData)
     85        return;
    8486    const void* data;
    8587    m_dispatchData = adoptDispatch(dispatch_data_create_map(dispatchData.get(), &data, &m_size));
     
    165167    switch (type) {
    166168    case FileOpenType::Create:
    167         oflag = O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK;
     169        oflag = O_RDWR | O_CREAT | O_TRUNC | O_NONBLOCK;
    168170        mode = S_IRUSR | S_IWUSR;
    169171        WebCore::makeAllDirectories(directoryPathForKey(key, cachePath));
     
    251253}
    252254
     255static 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
    253266static std::unique_ptr<NetworkCacheStorage::Entry> decodeEntry(dispatch_data_t fileData, int fd, const NetworkCacheKey& key)
    254267{
     
    271284        return nullptr;
    272285    }
    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) {
    276289        LOG(NetworkCacheStorage, "(NetworkProcess) map failed");
    277290        return nullptr;
    278291    }
    279 
    280     auto bodyData = adoptDispatch(dispatch_data_create(map, metaData.bodySize, dispatch_get_main_queue(), [map, mapSize] {
    281         munmap(map, mapSize);
    282     }));
    283292
    284293    if (metaData.bodyChecksum != hashData(bodyData.get())) {
     
    330339    auto alignmentData = adoptDispatch(dispatch_data_create(filler.data(), filler.size(), nullptr, DISPATCH_DATA_DESTRUCTOR_DEFAULT));
    331340    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()));
    338341}
    339342
     
    408411}
    409412
    410 template <class T> bool retrieveActive(const T& operations, const NetworkCacheKey& key, std::function<bool (std::unique_ptr<NetworkCacheStorage::Entry>)>& completionHandler)
     413template <class T> bool retrieveActive(const T& operations, const NetworkCacheKey& key, NetworkCacheStorage::RetrieveCompletionHandler& completionHandler)
    411414{
    412415    for (auto& operation : operations) {
     
    423426}
    424427
    425 void NetworkCacheStorage::retrieve(const NetworkCacheKey& key, unsigned priority, std::function<bool (std::unique_ptr<Entry>)> completionHandler)
     428void NetworkCacheStorage::retrieve(const NetworkCacheKey& key, unsigned priority, RetrieveCompletionHandler&& completionHandler)
    426429{
    427430    ASSERT(RunLoop::isMain());
     
    439442
    440443    // 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) }));
    442445    dispatchPendingRetrieveOperations();
    443446}
    444447
    445 void NetworkCacheStorage::store(const NetworkCacheKey& key, const Entry& entry, std::function<void (bool success)> completionHandler)
     448void NetworkCacheStorage::store(const NetworkCacheKey& key, const Entry& entry, StoreCompletionHandler&& completionHandler)
    446449{
    447450    ASSERT(RunLoop::isMain());
     
    450453    ++m_approximateEntryCount;
    451454
    452     auto storeOperation = std::make_unique<StoreOperation>(StoreOperation { key, entry, completionHandler });
     455    auto storeOperation = std::make_unique<StoreOperation>(StoreOperation { key, entry, WTF::move(completionHandler) });
    453456    auto& store = *storeOperation;
    454457    m_activeStoreOperations.add(WTF::move(storeOperation));
     
    456459    StringCapture cachePathCapture(m_directoryPath);
    457460    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();
    459466
    460467        int fd;
    461468        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) {
    463470            ASSERT_UNUSED(done, done);
    464471            LOG(NetworkCacheStorage, "(NetworkProcess) write complete error=%d", error);
     
    470477            }
    471478
    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);
    473484
    474485            m_activeStoreOperations.remove(&store);
     
    479490}
    480491
    481 void NetworkCacheStorage::update(const NetworkCacheKey& key, const Entry& updateEntry, const Entry& existingEntry, std::function<void (bool success)> completionHandler)
     492void NetworkCacheStorage::update(const NetworkCacheKey& key, const Entry& updateEntry, const Entry& existingEntry, StoreCompletionHandler&& completionHandler)
    482493{
    483494    ASSERT(RunLoop::isMain());
     
    485496    if (!m_contentsFilter.mayContain(key.hash())) {
    486497        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) });
    492503    auto& update = *updateOperation;
    493504    m_activeUpdateOperations.add(WTF::move(updateOperation));
     
    503514            LOG(NetworkCacheStorage, "(NetworkProcess) page-rounded header size changed, storing full entry");
    504515            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));
    506517
    507518                ASSERT(m_activeUpdateOperations.contains(&update));
     
    520531                removeEntry(update.key);
    521532
    522             update.completionHandler(!error);
     533            update.completionHandler(!error, Data());
    523534
    524535            ASSERT(m_activeUpdateOperations.contains(&update));
Note: See TracChangeset for help on using the changeset viewer.