⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 199043 in webkit


Ignore:
Timestamp:
Apr 4, 2016, 10:47:32 PM (11 years ago)
Author:
beidson@apple.com
Message:

Modern IDB: Dump blobs to disk before storing them in an object store.
​https://bugs.webkit.org/show_bug.cgi?id=156068
Source/WebCore:

Reviewed by Alex Christensen.

No new tests (Under development, no observable change in behavior yet).

  • WebCore.xcodeproj/project.pbxproj:
  • CMakeLists.txt:
  • Modules/indexeddb/IDBTransaction.cpp:

(WebCore::IDBTransaction::putOrAddOnServer):

  • Modules/indexeddb/IDBValue.cpp: Copied from Source/WebCore/platform/ScopeGuard.h.

(WebCore::IDBValue::IDBValue):

  • Modules/indexeddb/IDBValue.h: Copied from Source/WebCore/platform/ScopeGuard.h.
  • Modules/indexeddb/client/IDBConnectionToServer.cpp:

(WebCore::IDBClient::IDBConnectionToServer::putOrAdd):

  • Modules/indexeddb/client/IDBConnectionToServer.h:
  • Modules/indexeddb/client/TransactionOperation.h:
  • bindings/js/SerializedScriptValue.cpp:

(WebCore::SerializedScriptValue::SerializedScriptValue):
(WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB):
(WebCore::SerializedScriptValue::addBlobURL): Deleted.

  • bindings/js/SerializedScriptValue.h:
  • platform/FileSystem.cpp:

(WebCore::appendFileContentsToFileHandle):

  • platform/FileSystem.h:
  • platform/ScopeGuard.h:
  • platform/network/BlobRegistry.h:
  • platform/network/BlobRegistryImpl.cpp:

(WebCore::blobUtilityQueue):
(WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):

  • platform/network/BlobRegistryImpl.h:

Source/WebKit2:

Reviewed by Alex Christensen.

  • NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:

(WebKit::NetworkBlobRegistry::writeBlobsToTemporaryFiles):

  • NetworkProcess/FileAPI/NetworkBlobRegistry.h:
  • NetworkProcess/NetworkConnectionToWebProcess.cpp:

(WebKit::NetworkConnectionToWebProcess::writeBlobsToTemporaryFiles):

  • NetworkProcess/NetworkConnectionToWebProcess.h:
  • NetworkProcess/NetworkConnectionToWebProcess.messages.in:
  • WebProcess/FileAPI/BlobRegistryProxy.cpp:

(WebKit::BlobRegistryProxy::writeBlobsToTemporaryFiles):

  • WebProcess/FileAPI/BlobRegistryProxy.h:
  • WebProcess/Network/NetworkProcessConnection.cpp:

(WebKit::NetworkProcessConnection::didClose):
(WebKit::NetworkProcessConnection::writeBlobsToTemporaryFiles):
(WebKit::NetworkProcessConnection::didWriteBlobsToTemporaryFiles):

  • WebProcess/Network/NetworkProcessConnection.h:
  • WebProcess/Network/NetworkProcessConnection.messages.in:
Location:
trunk/Source
Files:
26 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r199030 r199043  
    851851    Modules/indexeddb/IDBRequestCompletionEvent.cpp
    852852    Modules/indexeddb/IDBTransaction.cpp
     853    Modules/indexeddb/IDBValue.cpp
    853854    Modules/indexeddb/IDBVersionChangeEvent.cpp
    854855    Modules/indexeddb/WorkerGlobalScopeIndexedDatabase.cpp
  • trunk/Source/WebCore/ChangeLog

    r199042 r199043  
     12016-04-04  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Dump blobs to disk before storing them in an object store.
     4        https://bugs.webkit.org/show_bug.cgi?id=156068
     5       
     6        Reviewed by Alex Christensen.
     7
     8        No new tests (Under development, no observable change in behavior yet).
     9
     10        * WebCore.xcodeproj/project.pbxproj:
     11        * CMakeLists.txt:
     12
     13        * Modules/indexeddb/IDBTransaction.cpp:
     14        (WebCore::IDBTransaction::putOrAddOnServer):
     15       
     16        * Modules/indexeddb/IDBValue.cpp: Copied from Source/WebCore/platform/ScopeGuard.h.
     17        (WebCore::IDBValue::IDBValue):
     18        * Modules/indexeddb/IDBValue.h: Copied from Source/WebCore/platform/ScopeGuard.h.
     19       
     20        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
     21        (WebCore::IDBClient::IDBConnectionToServer::putOrAdd):
     22        * Modules/indexeddb/client/IDBConnectionToServer.h:
     23       
     24        * Modules/indexeddb/client/TransactionOperation.h:
     25       
     26        * bindings/js/SerializedScriptValue.cpp:
     27        (WebCore::SerializedScriptValue::SerializedScriptValue):
     28        (WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB):
     29        (WebCore::SerializedScriptValue::addBlobURL): Deleted.
     30        * bindings/js/SerializedScriptValue.h:
     31       
     32        * platform/FileSystem.cpp:
     33        (WebCore::appendFileContentsToFileHandle):
     34        * platform/FileSystem.h:
     35       
     36        * platform/ScopeGuard.h:
     37       
     38        * platform/network/BlobRegistry.h:
     39        * platform/network/BlobRegistryImpl.cpp:
     40        (WebCore::blobUtilityQueue):
     41        (WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):
     42        * platform/network/BlobRegistryImpl.h:
     43
    1442016-04-04  Jer Noble  <jer.noble@apple.com>
    245
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp

    r198762 r199043  
    868868
    869869    ASSERT(!isReadOnly());
    870 
    871     serverConnection().putOrAdd(operation, key, value, overwriteMode);
     870    ASSERT(value);
     871
     872    RefPtr<IDBTransaction> protector(this);
     873    RefPtr<IDBClient::TransactionOperation> operationRef(&operation);
     874    value->writeBlobsToDiskForIndexedDB([protector, this, operationRef, key, value, overwriteMode](const IDBValue&) {
     875        // FIXME: Send the passed in IDBValue to the IDB server instead of the SerializedScriptValue.
     876        serverConnection().putOrAdd(*operationRef, key.get(), *value, overwriteMode);
     877    });
    872878}
    873879
  • trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp

    r199042 r199043  
    2323 * THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    25 #ifndef ScopeGuard_h
    26 #define ScopeGuard_h
     25
     26#include "config.h"
     27#include "IDBValue.h"
     28
     29#if ENABLE(INDEXED_DATABASE)
    2730
    2831namespace WebCore {
    2932
    30 class ScopeGuard {
    31 public:
    32     ScopeGuard()
    33     {
    34     }
    35 
    36     ScopeGuard(std::function<void()> function)
    37         : m_function(WTFMove(function))
    38     {
    39     }
    40 
    41     ~ScopeGuard()
    42     {
    43         if (m_function)
    44             m_function();
    45     }
    46 
    47     void enable(std::function<void()> function)
    48     {
    49         m_function = WTFMove(function);
    50     }
    51 
    52     void disable()
    53     {
    54         m_function = nullptr;
    55     }
    56 
    57 private:
    58     std::function<void()> m_function { nullptr };
    59 };
     33IDBValue::IDBValue()
     34{
     35}
    6036
    6137} // namespace WebCore
    6238
    63 #endif // ScopeGuard_h
     39#endif // ENABLE(INDEXED_DATABASE)
  • trunk/Source/WebCore/Modules/indexeddb/IDBValue.h

    r199042 r199043  
    2323 * THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    25 #ifndef ScopeGuard_h
    26 #define ScopeGuard_h
     25
     26#pragma once
     27#if ENABLE(INDEXED_DATABASE)
    2728
    2829namespace WebCore {
    2930
    30 class ScopeGuard {
     31class IDBValue {
    3132public:
    32     ScopeGuard()
    33     {
    34     }
    35 
    36     ScopeGuard(std::function<void()> function)
    37         : m_function(WTFMove(function))
    38     {
    39     }
    40 
    41     ~ScopeGuard()
    42     {
    43         if (m_function)
    44             m_function();
    45     }
    46 
    47     void enable(std::function<void()> function)
    48     {
    49         m_function = WTFMove(function);
    50     }
    51 
    52     void disable()
    53     {
    54         m_function = nullptr;
    55     }
    56 
    57 private:
    58     std::function<void()> m_function { nullptr };
     33    IDBValue();
    5934};
    6035
    6136} // namespace WebCore
    6237
    63 #endif // ScopeGuard_h
     38#endif // ENABLE(INDEXED_DATABASE)
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp

    r198762 r199043  
    172172}
    173173
    174 void IDBConnectionToServer::putOrAdd(TransactionOperation& operation, RefPtr<IDBKey>& key, RefPtr<SerializedScriptValue>& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
     174void IDBConnectionToServer::putOrAdd(TransactionOperation& operation, IDBKey* key, SerializedScriptValue& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
    175175{
    176176    LOG(IndexedDB, "IDBConnectionToServer::putOrAdd");
    177177
    178178    saveOperation(operation);
    179     m_delegate->putOrAdd(IDBRequestData(operation), key.get(), *value, overwriteMode);
     179    m_delegate->putOrAdd(IDBRequestData(operation), key, value, overwriteMode);
    180180}
    181181
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h

    r198762 r199043  
    7878    WEBCORE_EXPORT void didDeleteIndex(const IDBResultData&);
    7979
    80     void putOrAdd(TransactionOperation&, RefPtr<IDBKey>&, RefPtr<SerializedScriptValue>&, const IndexedDB::ObjectStoreOverwriteMode);
     80    void putOrAdd(TransactionOperation&, IDBKey*, SerializedScriptValue&, const IndexedDB::ObjectStoreOverwriteMode);
    8181    WEBCORE_EXPORT void didPutOrAdd(const IDBResultData&);
    8282
  • trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h

    r198762 r199043  
    4343namespace IDBClient {
    4444
    45 class TransactionOperation : public RefCounted<TransactionOperation> {
     45class TransactionOperation : public ThreadSafeRefCounted<TransactionOperation> {
    4646public:
    4747    void perform()
    … …  
    9393        : TransactionOperation(transaction)
    9494    {
    95         relaxAdoptionRequirement();
    9695        RefPtr<TransactionOperation> self(this);
    9796
    … …  
    112111        : TransactionOperation(transaction, request)
    113112    {
    114         relaxAdoptionRequirement();
    115113        RefPtr<TransactionOperation> self(this);
    116114
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r199030 r199043  
    20462046                516071321BD8308B00DBC4F2 /* TransactionOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160712B1BD8305300DBC4F2 /* TransactionOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
    20472047                5160F4980B0AA75F00C1D2AF /* HistoryItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */; };
     2048                516103AF1CADBA770016B4C7 /* IDBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 516103AE1CADB9A30016B4C7 /* IDBValue.h */; };
     2049                516103B01CADBA7A0016B4C7 /* IDBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 516103AD1CADB9A30016B4C7 /* IDBValue.cpp */; };
    20482050                5162C7F411F77EFB00612EFE /* SchemeRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */; };
    20492051                5162C7F511F77EFB00612EFE /* SchemeRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 5162C7F311F77EFB00612EFE /* SchemeRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
    … …  
    95969598                5160712D1BD8307200DBC4F2 /* IDBObjectStoreInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBObjectStoreInfo.h; sourceTree = "<group>"; };
    95979599                5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HistoryItemMac.mm; sourceTree = "<group>"; };
     9600                516103AD1CADB9A30016B4C7 /* IDBValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBValue.cpp; sourceTree = "<group>"; };
     9601                516103AE1CADB9A30016B4C7 /* IDBValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBValue.h; sourceTree = "<group>"; };
    95989602                5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SchemeRegistry.cpp; sourceTree = "<group>"; };
    95999603                5162C7F311F77EFB00612EFE /* SchemeRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchemeRegistry.h; sourceTree = "<group>"; };
    … …  
    1958719591                                51645B511B9F889B00F789CE /* IDBTransaction.h */,
    1958819592                                51D719A6181106E00016DC51 /* IDBTransaction.idl */,
     19593                                516103AD1CADB9A30016B4C7 /* IDBValue.cpp */,
     19594                                516103AE1CADB9A30016B4C7 /* IDBValue.h */,
    1958919595                                51645B521B9F889B00F789CE /* IDBVersionChangeEvent.cpp */,
    1959019596                                51645B531B9F889B00F789CE /* IDBVersionChangeEvent.h */,
    … …  
    2599325999                                2E75841E12779ADA0062628B /* FileReaderLoader.h in Headers */,
    2599426000                                2E75841F12779ADA0062628B /* FileReaderLoaderClient.h in Headers */,
     26001                                516103AF1CADBA770016B4C7 /* IDBValue.h in Headers */,
    2599526002                                2EDF369D122C94B4002F7D4E /* FileReaderSync.h in Headers */,
    2599626003                                2EF1BFEB121C9F4200C27627 /* FileStream.h in Headers */,
    … …  
    3178731794                                B2C3DA4A0D006C1D00EF6F26 /* TextStream.cpp in Sources */,
    3178831795                                9759E93F14EF1CF80026A2DD /* TextTrack.cpp in Sources */,
     31796                                516103B01CADBA7A0016B4C7 /* IDBValue.cpp in Sources */,
    3178931797                                9759E94214EF1CF80026A2DD /* TextTrackCue.cpp in Sources */,
    3179031798                                071A9EC2168FBC43002629F9 /* TextTrackCueGeneric.cpp in Sources */,
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp

    r198852 r199043  
    11/*
    2  * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009, 2013, 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
    … …  
    2929
    3030#include "Blob.h"
     31#include "BlobRegistry.h"
    3132#include "CryptoKeyAES.h"
    3233#include "CryptoKeyDataOctetSequence.h"
    … …  
    3738#include "File.h"
    3839#include "FileList.h"
     40#include "IDBValue.h"
    3941#include "ImageData.h"
    4042#include "JSBlob.h"
    … …  
    7678#include <runtime/TypedArrays.h>
    7779#include <wtf/HashTraits.h>
     80#include <wtf/MainThread.h>
    7881#include <wtf/Vector.h>
    7982
    … …  
    25832586}
    25842587
    2585 void SerializedScriptValue::addBlobURL(const String& string)
    2586 {
    2587     m_blobURLs.append(Vector<uint16_t>());
    2588     m_blobURLs.last().reserveCapacity(string.length());
    2589     for (size_t i = 0; i < string.length(); i++)
    2590         m_blobURLs.last().append(string.characterAt(i));
    2591     m_blobURLs.last().resize(m_blobURLs.last().size());
    2592 }
    2593 
    25942588SerializedScriptValue::~SerializedScriptValue()
    25952589{
    … …  
    26012595}
    26022596
    2603 SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector<String>& blobURLs)
    2604     : m_data(WTFMove(buffer))
    2605 {
    2606     for (auto& string : blobURLs)
    2607         addBlobURL(string);
    2608 }
    2609 
    26102597SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector<String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray>&& arrayBufferContentsArray)
    26112598    : m_data(WTFMove(buffer))
    26122599    , m_arrayBufferContentsArray(WTFMove(arrayBufferContentsArray))
    26132600{
    2614     for (auto& string : blobURLs)
    2615         addBlobURL(string);
     2601    // Since this SerializedScriptValue is meant to be passed between threads, its String data members
     2602    // need to be isolatedCopies so we don't run into thread safety issues for the StringImpls.
     2603    m_blobURLs.reserveInitialCapacity(blobURLs.size());
     2604    for (auto& url : blobURLs)
     2605        m_blobURLs.append(url.isolatedCopy());
    26162606}
    26172607
    … …  
    27582748}
    27592749
     2750void SerializedScriptValue::writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler)
     2751{
     2752    ASSERT(isMainThread());
     2753
     2754    if (m_blobURLs.isEmpty()) {
     2755        completionHandler({ });
     2756        return;
     2757    }
     2758
     2759    RefPtr<SerializedScriptValue> protector(this);
     2760    blobRegistry().writeBlobsToTemporaryFiles(m_blobURLs, [completionHandler, this, protector](const Vector<String>&) {
     2761        // FIXME: Return an IDBValue that contains both the SerializedScriptValue data and all blob file data.
     2762        completionHandler({ });
     2763    });
    27602764}
     2765
     2766} // namespace WebCore
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.h

    r198852 r199043  
    11/*
    2  * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009, 2013, 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
    … …  
    4242namespace WebCore {
    4343
     44class IDBValue;
    4445class MessagePort;
    4546typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
    … …  
    8485    const Vector<uint8_t>& data() const { return m_data; }
    8586    bool hasBlobURLs() const { return !m_blobURLs.isEmpty(); }
    86     void blobURLs(Vector<String>&) const;
     87    void writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler);
    8788
    8889    static Ref<SerializedScriptValue> createFromWireBytes(Vector<uint8_t>&& data)
    … …  
    99100    static bool serializationDidCompleteSuccessfully(SerializationReturnCode);
    100101    static std::unique_ptr<ArrayBufferContentsArray> transferArrayBuffers(JSC::ExecState*, ArrayBufferArray&, SerializationReturnCode&);
    101     void addBlobURL(const String&);
    102102
    103103    WEBCORE_EXPORT SerializedScriptValue(Vector<unsigned char>&&);
    104     SerializedScriptValue(Vector<unsigned char>&&, const Vector<String>& blobURLs);
    105104    SerializedScriptValue(Vector<unsigned char>&&, const Vector<String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray>&&);
    106105
    107106    Vector<unsigned char> m_data;
    108107    std::unique_ptr<ArrayBufferContentsArray> m_arrayBufferContentsArray;
    109     Vector<Vector<uint16_t>> m_blobURLs;
     108
     109    Vector<String> m_blobURLs;
    110110};
    111111
  • trunk/Source/WebCore/platform/FileSystem.cpp

    r195913 r199043  
    2828#include "FileSystem.h"
    2929
     30#include "ScopeGuard.h"
    3031#include <wtf/HexNumber.h>
    3132#include <wtf/text/CString.h>
    … …  
    130131}
    131132
     133bool appendFileContentsToFileHandle(const String& path, PlatformFileHandle& target)
     134{
     135    auto source = openFile(path, OpenForRead);
     136
     137    if (!isHandleValid(source))
     138        return false;
     139
     140    static int bufferSize = 1 << 19;
     141    Vector<char> buffer(bufferSize);
     142
     143    ScopeGuard fileCloser([source]() {
     144        PlatformFileHandle handle = source;
     145        closeFile(handle);
     146    });
     147
     148    do {
     149        int readBytes = readFromFile(source, buffer.data(), bufferSize);
     150       
     151        if (readBytes < 0)
     152            return false;
     153
     154        if (writeToFile(target, buffer.data(), readBytes) != readBytes)
     155            return false;
     156
     157        if (readBytes < bufferSize)
     158            return true;
     159    } while (true);
     160
     161    ASSERT_NOT_REACHED();
     162}
     163
    132164#if !PLATFORM(MAC)
    133165
  • trunk/Source/WebCore/platform/FileSystem.h

    r189749 r199043  
    177177// Returns number of bytes actually written if successful, -1 otherwise.
    178178int readFromFile(PlatformFileHandle, char* data, int length);
     179
     180// Appends the contents of the file found at 'path' to the open PlatformFileHandle.
     181// Returns true if the write was successful, false if it was not.
     182bool appendFileContentsToFileHandle(const String& path, PlatformFileHandle&);
     183
    179184#if USE(FILE_LOCK)
    180185bool lockFile(PlatformFileHandle, FileLockMode);
  • trunk/Source/WebCore/platform/ScopeGuard.h

    r195997 r199043  
    2525#ifndef ScopeGuard_h
    2626#define ScopeGuard_h
     27
     28#include <functional>
    2729
    2830namespace WebCore {
  • trunk/Source/WebCore/platform/network/BlobRegistry.h

    r196174 r199043  
    3232#define BlobRegistry_h
    3333
     34#include <functional>
    3435#include <wtf/Forward.h>
    3536#include <wtf/Vector.h>
    … …  
    6465    virtual unsigned long long blobSize(const URL&) = 0;
    6566
     67    virtual void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) = 0;
     68
    6669    virtual bool isBlobRegistryImpl() const { return false; }
    6770
  • trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp

    r198869 r199043  
    4242#include "ResourceRequest.h"
    4343#include "ResourceResponse.h"
     44#include "ScopeGuard.h"
    4445#include <wtf/MainThread.h>
     46#include <wtf/NeverDestroyed.h>
    4547#include <wtf/StdLibExtras.h>
     48#include <wtf/WorkQueue.h>
    4649
    4750namespace WebCore {
    … …  
    229232}
    230233
     234static WorkQueue& blobUtilityQueue()
     235{
     236    static NeverDestroyed<Ref<WorkQueue>> queue(WorkQueue::create("org.webkit.BlobUtility", WorkQueue::Type::Serial, WorkQueue::QOS::Background));
     237    return queue.get();
     238}
     239
     240struct BlobForFileWriting {
     241    String blobURL;
     242    Vector<std::pair<String, ThreadSafeDataBuffer>> filePathsOrDataBuffers;
     243};
     244
     245void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler)
     246{
     247    Vector<BlobForFileWriting> blobsForWriting;
     248    for (auto& url : blobURLs) {
     249        blobsForWriting.append({ });
     250        blobsForWriting.last().blobURL = url.isolatedCopy();
     251
     252        auto* blobData = getBlobDataFromURL({ ParsedURLString, url });
     253        if (!blobData) {
     254            Vector<String> filePaths;
     255            completionHandler(filePaths);
     256        }
     257
     258        for (auto& item : blobData->items()) {
     259            switch (item.type()) {
     260            case BlobDataItem::Type::Data:
     261                blobsForWriting.last().filePathsOrDataBuffers.append({ { }, item.data() });
     262                break;
     263            case BlobDataItem::Type::File:
     264                blobsForWriting.last().filePathsOrDataBuffers.append({ item.file()->path().isolatedCopy(), { } });
     265
     266            }
     267        }
     268    }
     269
     270    blobUtilityQueue().dispatch([blobsForWriting, completionHandler]() {
     271        Vector<String> filePaths;
     272
     273        ScopeGuard completionCaller([completionHandler]() {
     274            callOnMainThread([completionHandler]() {
     275                Vector<String> filePaths;
     276                completionHandler(filePaths);
     277            });
     278        });
     279
     280        for (auto& blob : blobsForWriting) {
     281            PlatformFileHandle file;
     282            String tempFilePath = openTemporaryFile(ASCIILiteral("Blob"), file);
     283
     284            ScopeGuard fileCloser([file, completionHandler]() {
     285                PlatformFileHandle handle = file;
     286                closeFile(handle);
     287            });
     288           
     289            if (tempFilePath.isEmpty() || !isHandleValid(file)) {
     290                LOG_ERROR("Failed to open temporary file for writing a Blob to IndexedDB");
     291                return;
     292            }
     293
     294            for (auto& part : blob.filePathsOrDataBuffers) {
     295                if (part.second.data()) {
     296                    int length = part.second.data()->size();
     297                    if (writeToFile(file, reinterpret_cast<const char*>(part.second.data()->data()), length) != length) {
     298                        LOG_ERROR("Failed writing a Blob to temporary file for storage in IndexedDB");
     299                        return;
     300                    }
     301                } else {
     302                    ASSERT(!part.first.isEmpty());
     303                    if (!appendFileContentsToFileHandle(part.first, file)) {
     304                        LOG_ERROR("Failed copying File contents to a Blob temporary file for storage in IndexedDB");
     305                        return;
     306                    }
     307                }
     308            }
     309
     310            filePaths.append(tempFilePath.isolatedCopy());
     311        }
     312
     313        completionCaller.disable();
     314        callOnMainThread([completionHandler, filePaths]() {
     315            completionHandler(filePaths);
     316        });
     317    });
     318}
     319
    231320} // namespace WebCore
  • trunk/Source/WebCore/platform/network/BlobRegistryImpl.h

    r197563 r199043  
    6868    unsigned long long blobSize(const URL&) override;
    6969
     70    void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) override;
     71
    7072    HashMap<String, RefPtr<BlobData>> m_blobs;
    7173};
  • trunk/Source/WebKit2/ChangeLog

    r199040 r199043  
     12016-04-04  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Dump blobs to disk before storing them in an object store.
     4        https://bugs.webkit.org/show_bug.cgi?id=156068
     5
     6        Reviewed by Alex Christensen.
     7
     8        * NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:
     9        (WebKit::NetworkBlobRegistry::writeBlobsToTemporaryFiles):
     10        * NetworkProcess/FileAPI/NetworkBlobRegistry.h:
     11
     12        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     13        (WebKit::NetworkConnectionToWebProcess::writeBlobsToTemporaryFiles):
     14        * NetworkProcess/NetworkConnectionToWebProcess.h:
     15        * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     16
     17        * WebProcess/FileAPI/BlobRegistryProxy.cpp:
     18        (WebKit::BlobRegistryProxy::writeBlobsToTemporaryFiles):
     19        * WebProcess/FileAPI/BlobRegistryProxy.h:
     20
     21        * WebProcess/Network/NetworkProcessConnection.cpp:
     22        (WebKit::NetworkProcessConnection::didClose):
     23        (WebKit::NetworkProcessConnection::writeBlobsToTemporaryFiles):
     24        (WebKit::NetworkProcessConnection::didWriteBlobsToTemporaryFiles):
     25        * WebProcess/Network/NetworkProcessConnection.h:
     26        * WebProcess/Network/NetworkProcessConnection.messages.in:
     27
    1282016-04-04  Chelsea Pugh  <cpugh@apple.com>
    229
  • trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp

    r198869 r199043  
    118118}
    119119
     120void NetworkBlobRegistry::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void(const Vector<String>&)> completionHandler)
     121{
     122    blobRegistry().writeBlobsToTemporaryFiles(blobURLs, completionHandler);
     123}
     124
    120125void NetworkBlobRegistry::connectionToWebProcessDidClose(NetworkConnectionToWebProcess* connection)
    121126{
  • trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h

    r196174 r199043  
    2828
    2929#include <WebCore/URLHash.h>
     30#include <functional>
    3031#include <wtf/HashMap.h>
    3132#include <wtf/HashSet.h>
    … …  
    5354    void unregisterBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&);
    5455    uint64_t blobSize(NetworkConnectionToWebProcess*, const WebCore::URL&);
     56    void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void(const Vector<String>&)> completionHandler);
    5557
    5658    void connectionToWebProcessDidClose(NetworkConnectionToWebProcess*);
  • trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp

    r198911 r199043  
    3131#include "NetworkLoad.h"
    3232#include "NetworkProcess.h"
     33#include "NetworkProcessConnectionMessages.h"
    3334#include "NetworkResourceLoadParameters.h"
    3435#include "NetworkResourceLoader.h"
    … …  
    3637#include "RemoteNetworkingContext.h"
    3738#include "SessionTracker.h"
     39#include "WebCoreArgumentCoders.h"
    3840#include <WebCore/NotImplemented.h>
    3941#include <WebCore/PingHandle.h>
    … …  
    280282}
    281283
     284void NetworkConnectionToWebProcess::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, uint64_t requestIdentifier)
     285{
     286    RefPtr<NetworkConnectionToWebProcess> protector(this);
     287
     288    Vector<RefPtr<WebCore::BlobDataFileReference>> fileReferences;
     289    for (auto& url : blobURLs)
     290        fileReferences.appendVector(NetworkBlobRegistry::singleton().filesInBlob(*this, { ParsedURLString, url }));
     291
     292    for (auto& file : fileReferences)
     293        file->prepareForFileAccess();
     294
     295    NetworkBlobRegistry::singleton().writeBlobsToTemporaryFiles(blobURLs, [this, protector, requestIdentifier, fileReferences](const Vector<String>& fileNames) {
     296        for (auto& file : fileReferences)
     297            file->revokeFileAccess();
     298
     299        if (!m_connection || !m_connection->isValid())
     300            return;
     301
     302        m_connection->send(Messages::NetworkProcessConnection::DidWriteBlobsToTemporaryFiles(requestIdentifier, fileNames), 0);
     303    });
     304}
     305
    282306void NetworkConnectionToWebProcess::ensureLegacyPrivateBrowsingSession()
    283307{
  • trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h

    r198893 r199043  
    9494    void blobSize(const WebCore::URL&, uint64_t& resultSize);
    9595    void unregisterBlobURL(const WebCore::URL&);
     96    void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, uint64_t requestIdentifier);
     97
    9698    void ensureLegacyPrivateBrowsingSession();
    9799
  • trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in

    r198893 r199043  
    4646    UnregisterBlobURL(WebCore::URL url)
    4747    BlobSize(WebCore::URL url) -> (uint64_t resultSize)
     48    WriteBlobsToTemporaryFiles(Vector<String> blobURLs, uint64_t requestIdentifier)
     49
    4850    EnsureLegacyPrivateBrowsingSession()
    4951}
  • trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp

    r196174 r199043  
    7676}
    7777
     78void BlobRegistryProxy::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler)
     79{
     80    WebProcess::singleton().networkConnection()->writeBlobsToTemporaryFiles(blobURLs, completionHandler);
    7881}
     82
     83}
  • trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h

    r197563 r199043  
    3939    void registerBlobURLForSlice(const WebCore::URL&, const WebCore::URL& srcURL, long long start, long long end) override;
    4040    unsigned long long blobSize(const WebCore::URL&) override;
     41    void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) override;
    4142};
    4243
  • trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp

    r193468 r199043  
    7373    // The NetworkProcess probably crashed.
    7474    WebProcess::singleton().networkProcessConnectionClosed(this);
     75
     76    Vector<String> dummyFilenames;
     77    for (auto handler : m_writeBlobToFileCompletionHandlers.values())
     78        handler(dummyFilenames);
     79
     80    m_writeBlobToFileCompletionHandlers.clear();
    7581}
    7682
    7783void NetworkProcessConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
    7884{
     85}
     86
     87void NetworkProcessConnection::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler)
     88{
     89    static uint64_t writeBlobToFileIdentifier;
     90    uint64_t requestIdentifier = ++writeBlobToFileIdentifier;
     91
     92    m_writeBlobToFileCompletionHandlers.set(requestIdentifier, completionHandler);
     93
     94    WebProcess::singleton().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::WriteBlobsToTemporaryFiles(blobURLs, requestIdentifier), 0);
     95}
     96
     97void NetworkProcessConnection::didWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, const Vector<String>& filenames)
     98{
     99    auto handler = m_writeBlobToFileCompletionHandlers.take(requestIdentifier);
     100    if (handler)
     101        handler(filenames);
    79102}
    80103
  • trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h

    r197563 r199043  
    5959    void didReceiveNetworkProcessConnectionMessage(IPC::Connection&, IPC::MessageDecoder&);
    6060
     61    void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler);
     62
    6163private:
    6264    NetworkProcessConnection(IPC::Connection::Identifier);
    … …  
    7072    IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Network; }
    7173
     74    void didWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, const Vector<String>& filenames);
     75
    7276#if ENABLE(SHAREABLE_RESOURCE)
    7377    // Message handlers.
    … …  
    7781    // The connection from the web process to the network process.
    7882    RefPtr<IPC::Connection> m_connection;
     83
     84    HashMap<uint64_t, std::function<void (const Vector<String>&)>> m_writeBlobToFileCompletionHandlers;
    7985};
    8086
  • trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in

    r192697 r199043  
    2727#endif
    2828
     29    DidWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, Vector<String> filenames)
    2930}
Note: See TracChangeset for help on using the changeset viewer.