Changeset 201693 in webkit


Ignore:
Timestamp:
Jun 4, 2016 8:46:42 PM (8 years ago)
Author:
beidson@apple.com
Message:

Modern IDB: Crash seen in IDBConnectionProxy::putOrAdd on GuardMalloc bot
https://bugs.webkit.org/show_bug.cgi?id=158124

Reviewed by Darin Adler.

No new tests (Covered by existing test configurations).

  • Modules/indexeddb/IDBTransaction.cpp:

(WebCore::IDBTransaction::putOrAddOnServer):

  • Modules/indexeddb/client/IDBConnectionProxy.cpp:

(WebCore::IDBClient::IDBConnectionProxy::putOrAdd):

  • Modules/indexeddb/client/IDBConnectionProxy.h:

(WebCore::IDBClient::IDBConnectionProxy::callConnectionOnMainThread):

  • bindings/js/SerializedScriptValue.cpp:

(WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB):

  • bindings/js/SerializedScriptValue.h:
  • platform/network/BlobRegistry.h:
  • platform/network/BlobRegistryImpl.cpp:

(WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):

  • platform/network/BlobRegistryImpl.h:
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r201691 r201693  
     12016-06-04  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Crash seen in IDBConnectionProxy::putOrAdd on GuardMalloc bot
     4        https://bugs.webkit.org/show_bug.cgi?id=158124
     5
     6        Reviewed by Darin Adler.
     7
     8        No new tests (Covered by existing test configurations).
     9
     10        * Modules/indexeddb/IDBTransaction.cpp:
     11        (WebCore::IDBTransaction::putOrAddOnServer):
     12       
     13        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
     14        (WebCore::IDBClient::IDBConnectionProxy::putOrAdd):
     15       
     16        * Modules/indexeddb/client/IDBConnectionProxy.h:
     17        (WebCore::IDBClient::IDBConnectionProxy::callConnectionOnMainThread):
     18       
     19        * bindings/js/SerializedScriptValue.cpp:
     20        (WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB):
     21        * bindings/js/SerializedScriptValue.h:
     22       
     23        * platform/network/BlobRegistry.h:
     24        * platform/network/BlobRegistryImpl.cpp:
     25        (WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):
     26        * platform/network/BlobRegistryImpl.h:
     27
    1282016-06-03  Ada Chan  <adachan@apple.com>
    229
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp

    r201547 r201693  
    967967    }
    968968
    969     RefPtr<IDBTransaction> protectedThis(this);
    970     RefPtr<IDBClient::TransactionOperation> protectedOperation(&operation);
    971     value->writeBlobsToDiskForIndexedDB([protectedThis = WTFMove(protectedThis), this, protectedOperation = WTFMove(protectedOperation), key = WTFMove(key), overwriteMode](const IDBValue& idbValue) mutable {
     969    value->writeBlobsToDiskForIndexedDB([protectedThis = Ref<IDBTransaction>(*this), this, protectedOperation = Ref<IDBClient::TransactionOperation>(operation), keyData = IDBKeyData(key.get()).isolatedCopy(), overwriteMode](const IDBValue& idbValue) mutable {
    972970        ASSERT(currentThread() == originThreadID());
    973971        ASSERT(isMainThread());
    974972        if (idbValue.data().data()) {
    975             m_database->connectionProxy().putOrAdd(*protectedOperation, key.get(), idbValue, overwriteMode);
     973            m_database->connectionProxy().putOrAdd(protectedOperation.get(), WTFMove(keyData), idbValue, overwriteMode);
    976974            return;
    977975        }
     
    980978        // In that case, we cannot successfully store this record, so we callback with an error.
    981979        auto result = IDBResultData::error(protectedOperation->identifier(), { IDBDatabaseException::UnknownError, ASCIILiteral("Error preparing Blob/File data to be stored in object store") });
    982         callOnMainThread([protectedThis = WTFMove(protectedThis), protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)]() {
     980        callOnMainThread([protectedThis = WTFMove(protectedThis), protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)]() mutable {
    983981            protectedOperation->completed(result);
    984982        });
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp

    r201402 r201693  
    157157}
    158158
    159 void IDBConnectionProxy::putOrAdd(TransactionOperation& operation, IDBKey* key, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode mode)
    160 {
    161     const IDBRequestData requestData(operation);
    162     saveOperation(operation);
    163 
    164     callConnectionOnMainThread(&IDBConnectionToServer::putOrAdd, requestData, IDBKeyData(key), value, mode);
     159void IDBConnectionProxy::putOrAdd(TransactionOperation& operation, IDBKeyData&& keyData, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode mode)
     160{
     161    const IDBRequestData requestData(operation);
     162    saveOperation(operation);
     163
     164    callConnectionOnMainThread(&IDBConnectionToServer::putOrAdd, requestData, keyData, value, mode);
    165165}
    166166
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h

    r201518 r201693  
    7171    void createIndex(TransactionOperation&, const IDBIndexInfo&);
    7272    void deleteIndex(TransactionOperation&, uint64_t objectStoreIdentifier, const String& indexName);
    73     void putOrAdd(TransactionOperation&, IDBKey*, const IDBValue&, const IndexedDB::ObjectStoreOverwriteMode);
     73    void putOrAdd(TransactionOperation&, IDBKeyData&&, const IDBValue&, const IndexedDB::ObjectStoreOverwriteMode);
    7474    void getRecord(TransactionOperation&, const IDBKeyRangeData&);
    7575    void getCount(TransactionOperation&, const IDBKeyRangeData&);
     
    125125    {
    126126        if (isMainThread())
    127             (m_connectionToServer.*method)(arguments...);
     127            (m_connectionToServer.*method)(std::forward<Arguments>(arguments)...);
    128128        else
    129129            postMainThreadTask(m_connectionToServer, method, arguments...);
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp

    r201575 r201693  
    27972797}
    27982798
    2799 void SerializedScriptValue::writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler)
     2799void SerializedScriptValue::writeBlobsToDiskForIndexedDB(NoncopyableFunction<void (const IDBValue&)>&& completionHandler)
    28002800{
    28012801    ASSERT(isMainThread());
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.h

    r201232 r201693  
    3232#include <runtime/JSCJSValue.h>
    3333#include <wtf/Forward.h>
     34#include <wtf/NoncopyableFunction.h>
    3435#include <wtf/RefCounted.h>
    3536#include <wtf/text/WTFString.h>
     
    8788#if ENABLE(INDEXED_DATABASE)
    8889    Vector<String> blobURLsIsolatedCopy() const;
    89     void writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler);
     90    void writeBlobsToDiskForIndexedDB(NoncopyableFunction<void (const IDBValue&)>&& completionHandler);
    9091    IDBValue writeBlobsToDiskForIndexedDBSynchronously();
    9192#endif // ENABLE(INDEXED_DATABASE)
  • trunk/Source/WebCore/platform/network/BlobRegistry.h

    r199708 r201693  
    3434#include <functional>
    3535#include <wtf/Forward.h>
     36#include <wtf/NoncopyableFunction.h>
    3637#include <wtf/Vector.h>
    3738
     
    6869    virtual unsigned long long blobSize(const URL&) = 0;
    6970
    70     virtual void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) = 0;
     71    virtual void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, NoncopyableFunction<void (const Vector<String>& filePaths)>&& completionHandler) = 0;
    7172
    7273    virtual bool isBlobRegistryImpl() const { return false; }
  • trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp

    r201302 r201693  
    257257};
    258258
    259 void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler)
     259void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, NoncopyableFunction<void (const Vector<String>& filePaths)>&& completionHandler)
    260260{
    261261    Vector<BlobForFileWriting> blobsForWriting;
     
    288288        Vector<String> filePaths;
    289289
    290         ScopeGuard completionCaller([completionHandler]() mutable {
    291             callOnMainThread([completionHandler = WTFMove(completionHandler)]() {
    292                 Vector<String> filePaths;
    293                 completionHandler(filePaths);
    294             });
    295         });
    296 
    297         for (auto& blob : blobsForWriting) {
    298             PlatformFileHandle file;
    299             String tempFilePath = openTemporaryFile(ASCIILiteral("Blob"), file);
    300 
    301             ScopeGuard fileCloser([file]() {
    302                 PlatformFileHandle handle = file;
    303                 closeFile(handle);
    304             });
    305            
    306             if (tempFilePath.isEmpty() || !isHandleValid(file)) {
    307                 LOG_ERROR("Failed to open temporary file for writing a Blob to IndexedDB");
    308                 return;
    309             }
    310 
    311             for (auto& part : blob.filePathsOrDataBuffers) {
    312                 if (part.second.data()) {
    313                     int length = part.second.data()->size();
    314                     if (writeToFile(file, reinterpret_cast<const char*>(part.second.data()->data()), length) != length) {
    315                         LOG_ERROR("Failed writing a Blob to temporary file for storage in IndexedDB");
    316                         return;
    317                     }
    318                 } else {
    319                     ASSERT(!part.first.isEmpty());
    320                     if (!appendFileContentsToFileHandle(part.first, file)) {
    321                         LOG_ERROR("Failed copying File contents to a Blob temporary file for storage in IndexedDB (%s to %s)", part.first.utf8().data(), tempFilePath.utf8().data());
    322                         return;
     290        auto performWriting = [blobsForWriting = WTFMove(blobsForWriting), &filePaths]() {
     291            for (auto& blob : blobsForWriting) {
     292                PlatformFileHandle file;
     293                String tempFilePath = openTemporaryFile(ASCIILiteral("Blob"), file);
     294
     295                ScopeGuard fileCloser([file]() mutable {
     296                    closeFile(file);
     297                });
     298               
     299                if (tempFilePath.isEmpty() || !isHandleValid(file)) {
     300                    LOG_ERROR("Failed to open temporary file for writing a Blob to IndexedDB");
     301                    return false;
     302                }
     303
     304                for (auto& part : blob.filePathsOrDataBuffers) {
     305                    if (part.second.data()) {
     306                        int length = part.second.data()->size();
     307                        if (writeToFile(file, reinterpret_cast<const char*>(part.second.data()->data()), length) != length) {
     308                            LOG_ERROR("Failed writing a Blob to temporary file for storage in IndexedDB");
     309                            return false;
     310                        }
     311                    } else {
     312                        ASSERT(!part.first.isEmpty());
     313                        if (!appendFileContentsToFileHandle(part.first, file)) {
     314                            LOG_ERROR("Failed copying File contents to a Blob temporary file for storage in IndexedDB (%s to %s)", part.first.utf8().data(), tempFilePath.utf8().data());
     315                            return false;
     316                        }
    323317                    }
    324318                }
     319
     320                filePaths.append(tempFilePath.isolatedCopy());
    325321            }
    326322
    327             filePaths.append(tempFilePath.isolatedCopy());
    328         }
    329 
    330         completionCaller.disable();
     323            return true;
     324        };
     325
     326        if (!performWriting())
     327            filePaths.clear();
     328
    331329        callOnMainThread([completionHandler = WTFMove(completionHandler), filePaths = WTFMove(filePaths)]() {
    332330            completionHandler(filePaths);
  • trunk/Source/WebCore/platform/network/BlobRegistryImpl.h

    r199708 r201693  
    6969    unsigned long long blobSize(const URL&) override;
    7070
    71     void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) override;
     71    void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, NoncopyableFunction<void (const Vector<String>& filePaths)>&& completionHandler) override;
    7272
    7373    HashMap<String, RefPtr<BlobData>> m_blobs;
Note: See TracChangeset for help on using the changeset viewer.