Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (199042 => 199043)
--- trunk/Source/WebCore/CMakeLists.txt 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/CMakeLists.txt 2016-04-05 05:47:32 UTC (rev 199043)
@@ -850,6 +850,7 @@
Modules/indexeddb/IDBRequest.cpp
Modules/indexeddb/IDBRequestCompletionEvent.cpp
Modules/indexeddb/IDBTransaction.cpp
+ Modules/indexeddb/IDBValue.cpp
Modules/indexeddb/IDBVersionChangeEvent.cpp
Modules/indexeddb/WorkerGlobalScopeIndexedDatabase.cpp
Modified: trunk/Source/WebCore/ChangeLog (199042 => 199043)
--- trunk/Source/WebCore/ChangeLog 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/ChangeLog 2016-04-05 05:47:32 UTC (rev 199043)
@@ -1,3 +1,46 @@
+2016-04-04 Brady Eidson <[email protected]>
+
+ Modern IDB: Dump blobs to disk before storing them in an object store.
+ https://bugs.webkit.org/show_bug.cgi?id=156068
+
+ 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:
+
2016-04-04 Jer Noble <[email protected]>
[iOS] Crash when playing <video> after playing Web Audio
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (199042 => 199043)
--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -867,8 +867,14 @@
LOG(IndexedDB, "IDBTransaction::putOrAddOnServer");
ASSERT(!isReadOnly());
+ ASSERT(value);
- serverConnection().putOrAdd(operation, key, value, overwriteMode);
+ RefPtr<IDBTransaction> protector(this);
+ RefPtr<IDBClient::TransactionOperation> operationRef(&operation);
+ value->writeBlobsToDiskForIndexedDB([protector, this, operationRef, key, value, overwriteMode](const IDBValue&) {
+ // FIXME: Send the passed in IDBValue to the IDB server instead of the SerializedScriptValue.
+ serverConnection().putOrAdd(*operationRef, key.get(), *value, overwriteMode);
+ });
}
void IDBTransaction::didPutOrAddOnServer(IDBRequest& request, const IDBResultData& resultData)
Copied: trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp (from rev 199042, trunk/Source/WebCore/platform/ScopeGuard.h) (0 => 199043)
--- trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IDBValue.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+IDBValue::IDBValue()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
Copied: trunk/Source/WebCore/Modules/indexeddb/IDBValue.h (from rev 199042, trunk/Source/WebCore/platform/ScopeGuard.h) (0 => 199043)
--- trunk/Source/WebCore/Modules/indexeddb/IDBValue.h (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBValue.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+class IDBValue {
+public:
+ IDBValue();
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp (199042 => 199043)
--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -171,12 +171,12 @@
completeOperation(resultData);
}
-void IDBConnectionToServer::putOrAdd(TransactionOperation& operation, RefPtr<IDBKey>& key, RefPtr<SerializedScriptValue>& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
+void IDBConnectionToServer::putOrAdd(TransactionOperation& operation, IDBKey* key, SerializedScriptValue& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
{
LOG(IndexedDB, "IDBConnectionToServer::putOrAdd");
saveOperation(operation);
- m_delegate->putOrAdd(IDBRequestData(operation), key.get(), *value, overwriteMode);
+ m_delegate->putOrAdd(IDBRequestData(operation), key, value, overwriteMode);
}
void IDBConnectionToServer::didPutOrAdd(const IDBResultData& resultData)
Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h (199042 => 199043)
--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -77,7 +77,7 @@
void deleteIndex(TransactionOperation&, uint64_t objectStoreIdentifier, const String& indexName);
WEBCORE_EXPORT void didDeleteIndex(const IDBResultData&);
- void putOrAdd(TransactionOperation&, RefPtr<IDBKey>&, RefPtr<SerializedScriptValue>&, const IndexedDB::ObjectStoreOverwriteMode);
+ void putOrAdd(TransactionOperation&, IDBKey*, SerializedScriptValue&, const IndexedDB::ObjectStoreOverwriteMode);
WEBCORE_EXPORT void didPutOrAdd(const IDBResultData&);
void getRecord(TransactionOperation&, const IDBKeyRangeData&);
Modified: trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h (199042 => 199043)
--- trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -42,7 +42,7 @@
namespace IDBClient {
-class TransactionOperation : public RefCounted<TransactionOperation> {
+class TransactionOperation : public ThreadSafeRefCounted<TransactionOperation> {
public:
void perform()
{
@@ -92,7 +92,6 @@
TransactionOperationImpl(IDBTransaction& transaction, void (IDBTransaction::*completeMethod)(const IDBResultData&), void (IDBTransaction::*performMethod)(TransactionOperation&, Arguments...), Arguments&&... arguments)
: TransactionOperation(transaction)
{
- relaxAdoptionRequirement();
RefPtr<TransactionOperation> self(this);
ASSERT(performMethod);
@@ -111,7 +110,6 @@
TransactionOperationImpl(IDBTransaction& transaction, IDBRequest& request, void (IDBTransaction::*completeMethod)(IDBRequest&, const IDBResultData&), void (IDBTransaction::*performMethod)(TransactionOperation&, Arguments...), Arguments&&... arguments)
: TransactionOperation(transaction, request)
{
- relaxAdoptionRequirement();
RefPtr<TransactionOperation> self(this);
ASSERT(performMethod);
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (199042 => 199043)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-04-05 05:47:32 UTC (rev 199043)
@@ -2045,6 +2045,8 @@
5160712F1BD8307800DBC4F2 /* IDBObjectStoreInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160712D1BD8307200DBC4F2 /* IDBObjectStoreInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
516071321BD8308B00DBC4F2 /* TransactionOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160712B1BD8305300DBC4F2 /* TransactionOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
5160F4980B0AA75F00C1D2AF /* HistoryItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */; };
+ 516103AF1CADBA770016B4C7 /* IDBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 516103AE1CADB9A30016B4C7 /* IDBValue.h */; };
+ 516103B01CADBA7A0016B4C7 /* IDBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 516103AD1CADB9A30016B4C7 /* IDBValue.cpp */; };
5162C7F411F77EFB00612EFE /* SchemeRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */; };
5162C7F511F77EFB00612EFE /* SchemeRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 5162C7F311F77EFB00612EFE /* SchemeRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
516953971329A3C800B92D04 /* IconDatabaseBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 516953951329A3C800B92D04 /* IconDatabaseBase.cpp */; };
@@ -9595,6 +9597,8 @@
5160712C1BD8307200DBC4F2 /* IDBObjectStoreInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBObjectStoreInfo.cpp; sourceTree = "<group>"; };
5160712D1BD8307200DBC4F2 /* IDBObjectStoreInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBObjectStoreInfo.h; sourceTree = "<group>"; };
5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HistoryItemMac.mm; sourceTree = "<group>"; };
+ 516103AD1CADB9A30016B4C7 /* IDBValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBValue.cpp; sourceTree = "<group>"; };
+ 516103AE1CADB9A30016B4C7 /* IDBValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBValue.h; sourceTree = "<group>"; };
5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SchemeRegistry.cpp; sourceTree = "<group>"; };
5162C7F311F77EFB00612EFE /* SchemeRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchemeRegistry.h; sourceTree = "<group>"; };
51645B411B9F889B00F789CE /* IDBCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBCursor.h; sourceTree = "<group>"; };
@@ -19586,6 +19590,8 @@
51645B501B9F889B00F789CE /* IDBTransaction.cpp */,
51645B511B9F889B00F789CE /* IDBTransaction.h */,
51D719A6181106E00016DC51 /* IDBTransaction.idl */,
+ 516103AD1CADB9A30016B4C7 /* IDBValue.cpp */,
+ 516103AE1CADB9A30016B4C7 /* IDBValue.h */,
51645B521B9F889B00F789CE /* IDBVersionChangeEvent.cpp */,
51645B531B9F889B00F789CE /* IDBVersionChangeEvent.h */,
51D719AD181106E00016DC51 /* IDBVersionChangeEvent.idl */,
@@ -25992,6 +25998,7 @@
976D6C89122B8A3D001FD1F7 /* FileReader.h in Headers */,
2E75841E12779ADA0062628B /* FileReaderLoader.h in Headers */,
2E75841F12779ADA0062628B /* FileReaderLoaderClient.h in Headers */,
+ 516103AF1CADBA770016B4C7 /* IDBValue.h in Headers */,
2EDF369D122C94B4002F7D4E /* FileReaderSync.h in Headers */,
2EF1BFEB121C9F4200C27627 /* FileStream.h in Headers */,
2EF1BFF9121CB0CE00C27627 /* FileStreamClient.h in Headers */,
@@ -31786,6 +31793,7 @@
376DCCE113B4F966002EBEFC /* TextRun.cpp in Sources */,
B2C3DA4A0D006C1D00EF6F26 /* TextStream.cpp in Sources */,
9759E93F14EF1CF80026A2DD /* TextTrack.cpp in Sources */,
+ 516103B01CADBA7A0016B4C7 /* IDBValue.cpp in Sources */,
9759E94214EF1CF80026A2DD /* TextTrackCue.cpp in Sources */,
071A9EC2168FBC43002629F9 /* TextTrackCueGeneric.cpp in Sources */,
9759E94514EF1CF80026A2DD /* TextTrackCueList.cpp in Sources */,
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (199042 => 199043)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2013, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
#include "SerializedScriptValue.h"
#include "Blob.h"
+#include "BlobRegistry.h"
#include "CryptoKeyAES.h"
#include "CryptoKeyDataOctetSequence.h"
#include "CryptoKeyDataRSAComponents.h"
@@ -36,6 +37,7 @@
#include "ExceptionCode.h"
#include "File.h"
#include "FileList.h"
+#include "IDBValue.h"
#include "ImageData.h"
#include "JSBlob.h"
#include "JSCryptoKey.h"
@@ -75,6 +77,7 @@
#include <runtime/TypedArrayInlines.h>
#include <runtime/TypedArrays.h>
#include <wtf/HashTraits.h>
+#include <wtf/MainThread.h>
#include <wtf/Vector.h>
using namespace JSC;
@@ -2582,15 +2585,6 @@
return std::make_pair(JSValue(), ValidationError);
}
-void SerializedScriptValue::addBlobURL(const String& string)
-{
- m_blobURLs.append(Vector<uint16_t>());
- m_blobURLs.last().reserveCapacity(string.length());
- for (size_t i = 0; i < string.length(); i++)
- m_blobURLs.last().append(string.characterAt(i));
- m_blobURLs.last().resize(m_blobURLs.last().size());
-}
-
SerializedScriptValue::~SerializedScriptValue()
{
}
@@ -2600,19 +2594,15 @@
{
}
-SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector<String>& blobURLs)
- : m_data(WTFMove(buffer))
-{
- for (auto& string : blobURLs)
- addBlobURL(string);
-}
-
SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector<String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray>&& arrayBufferContentsArray)
: m_data(WTFMove(buffer))
, m_arrayBufferContentsArray(WTFMove(arrayBufferContentsArray))
{
- for (auto& string : blobURLs)
- addBlobURL(string);
+ // Since this SerializedScriptValue is meant to be passed between threads, its String data members
+ // need to be isolatedCopies so we don't run into thread safety issues for the StringImpls.
+ m_blobURLs.reserveInitialCapacity(blobURLs.size());
+ for (auto& url : blobURLs)
+ m_blobURLs.append(url.isolatedCopy());
}
std::unique_ptr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(
@@ -2757,4 +2747,20 @@
return CurrentVersion;
}
+void SerializedScriptValue::writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler)
+{
+ ASSERT(isMainThread());
+
+ if (m_blobURLs.isEmpty()) {
+ completionHandler({ });
+ return;
+ }
+
+ RefPtr<SerializedScriptValue> protector(this);
+ blobRegistry().writeBlobsToTemporaryFiles(m_blobURLs, [completionHandler, this, protector](const Vector<String>&) {
+ // FIXME: Return an IDBValue that contains both the SerializedScriptValue data and all blob file data.
+ completionHandler({ });
+ });
}
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (199042 => 199043)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2013, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,6 +41,7 @@
namespace WebCore {
+class IDBValue;
class MessagePort;
typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
typedef Vector<RefPtr<JSC::ArrayBuffer>, 1> ArrayBufferArray;
@@ -83,7 +84,7 @@
const Vector<uint8_t>& data() const { return m_data; }
bool hasBlobURLs() const { return !m_blobURLs.isEmpty(); }
- void blobURLs(Vector<String>&) const;
+ void writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler);
static Ref<SerializedScriptValue> createFromWireBytes(Vector<uint8_t>&& data)
{
@@ -98,15 +99,14 @@
static void maybeThrowExceptionIfSerializationFailed(JSC::ExecState*, SerializationReturnCode);
static bool serializationDidCompleteSuccessfully(SerializationReturnCode);
static std::unique_ptr<ArrayBufferContentsArray> transferArrayBuffers(JSC::ExecState*, ArrayBufferArray&, SerializationReturnCode&);
- void addBlobURL(const String&);
WEBCORE_EXPORT SerializedScriptValue(Vector<unsigned char>&&);
- SerializedScriptValue(Vector<unsigned char>&&, const Vector<String>& blobURLs);
SerializedScriptValue(Vector<unsigned char>&&, const Vector<String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray>&&);
Vector<unsigned char> m_data;
std::unique_ptr<ArrayBufferContentsArray> m_arrayBufferContentsArray;
- Vector<Vector<uint16_t>> m_blobURLs;
+
+ Vector<String> m_blobURLs;
};
}
Modified: trunk/Source/WebCore/platform/FileSystem.cpp (199042 => 199043)
--- trunk/Source/WebCore/platform/FileSystem.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/platform/FileSystem.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -27,6 +27,7 @@
#include "config.h"
#include "FileSystem.h"
+#include "ScopeGuard.h"
#include <wtf/HexNumber.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
@@ -129,6 +130,37 @@
return result.toString();
}
+bool appendFileContentsToFileHandle(const String& path, PlatformFileHandle& target)
+{
+ auto source = openFile(path, OpenForRead);
+
+ if (!isHandleValid(source))
+ return false;
+
+ static int bufferSize = 1 << 19;
+ Vector<char> buffer(bufferSize);
+
+ ScopeGuard fileCloser([source]() {
+ PlatformFileHandle handle = source;
+ closeFile(handle);
+ });
+
+ do {
+ int readBytes = readFromFile(source, buffer.data(), bufferSize);
+
+ if (readBytes < 0)
+ return false;
+
+ if (writeToFile(target, buffer.data(), readBytes) != readBytes)
+ return false;
+
+ if (readBytes < bufferSize)
+ return true;
+ } while (true);
+
+ ASSERT_NOT_REACHED();
+}
+
#if !PLATFORM(MAC)
void setMetadataURL(String&, const String&, const String&)
Modified: trunk/Source/WebCore/platform/FileSystem.h (199042 => 199043)
--- trunk/Source/WebCore/platform/FileSystem.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/platform/FileSystem.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -176,6 +176,11 @@
WEBCORE_EXPORT int writeToFile(PlatformFileHandle, const char* data, int length);
// Returns number of bytes actually written if successful, -1 otherwise.
int readFromFile(PlatformFileHandle, char* data, int length);
+
+// Appends the contents of the file found at 'path' to the open PlatformFileHandle.
+// Returns true if the write was successful, false if it was not.
+bool appendFileContentsToFileHandle(const String& path, PlatformFileHandle&);
+
#if USE(FILE_LOCK)
bool lockFile(PlatformFileHandle, FileLockMode);
bool unlockFile(PlatformFileHandle);
Modified: trunk/Source/WebCore/platform/ScopeGuard.h (199042 => 199043)
--- trunk/Source/WebCore/platform/ScopeGuard.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/platform/ScopeGuard.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -25,6 +25,8 @@
#ifndef ScopeGuard_h
#define ScopeGuard_h
+#include <functional>
+
namespace WebCore {
class ScopeGuard {
Modified: trunk/Source/WebCore/platform/network/BlobRegistry.h (199042 => 199043)
--- trunk/Source/WebCore/platform/network/BlobRegistry.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/platform/network/BlobRegistry.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -31,6 +31,7 @@
#ifndef BlobRegistry_h
#define BlobRegistry_h
+#include <functional>
#include <wtf/Forward.h>
#include <wtf/Vector.h>
@@ -63,6 +64,8 @@
virtual unsigned long long blobSize(const URL&) = 0;
+ virtual void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) = 0;
+
virtual bool isBlobRegistryImpl() const { return false; }
protected:
Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp (199042 => 199043)
--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -41,8 +41,11 @@
#include "ResourceHandle.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
+#include "ScopeGuard.h"
#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
+#include <wtf/WorkQueue.h>
namespace WebCore {
@@ -228,4 +231,90 @@
return result;
}
+static WorkQueue& blobUtilityQueue()
+{
+ static NeverDestroyed<Ref<WorkQueue>> queue(WorkQueue::create("org.webkit.BlobUtility", WorkQueue::Type::Serial, WorkQueue::QOS::Background));
+ return queue.get();
+}
+
+struct BlobForFileWriting {
+ String blobURL;
+ Vector<std::pair<String, ThreadSafeDataBuffer>> filePathsOrDataBuffers;
+};
+
+void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler)
+{
+ Vector<BlobForFileWriting> blobsForWriting;
+ for (auto& url : blobURLs) {
+ blobsForWriting.append({ });
+ blobsForWriting.last().blobURL = url.isolatedCopy();
+
+ auto* blobData = getBlobDataFromURL({ ParsedURLString, url });
+ if (!blobData) {
+ Vector<String> filePaths;
+ completionHandler(filePaths);
+ }
+
+ for (auto& item : blobData->items()) {
+ switch (item.type()) {
+ case BlobDataItem::Type::Data:
+ blobsForWriting.last().filePathsOrDataBuffers.append({ { }, item.data() });
+ break;
+ case BlobDataItem::Type::File:
+ blobsForWriting.last().filePathsOrDataBuffers.append({ item.file()->path().isolatedCopy(), { } });
+
+ }
+ }
+ }
+
+ blobUtilityQueue().dispatch([blobsForWriting, completionHandler]() {
+ Vector<String> filePaths;
+
+ ScopeGuard completionCaller([completionHandler]() {
+ callOnMainThread([completionHandler]() {
+ Vector<String> filePaths;
+ completionHandler(filePaths);
+ });
+ });
+
+ for (auto& blob : blobsForWriting) {
+ PlatformFileHandle file;
+ String tempFilePath = openTemporaryFile(ASCIILiteral("Blob"), file);
+
+ ScopeGuard fileCloser([file, completionHandler]() {
+ PlatformFileHandle handle = file;
+ closeFile(handle);
+ });
+
+ if (tempFilePath.isEmpty() || !isHandleValid(file)) {
+ LOG_ERROR("Failed to open temporary file for writing a Blob to IndexedDB");
+ return;
+ }
+
+ for (auto& part : blob.filePathsOrDataBuffers) {
+ if (part.second.data()) {
+ int length = part.second.data()->size();
+ if (writeToFile(file, reinterpret_cast<const char*>(part.second.data()->data()), length) != length) {
+ LOG_ERROR("Failed writing a Blob to temporary file for storage in IndexedDB");
+ return;
+ }
+ } else {
+ ASSERT(!part.first.isEmpty());
+ if (!appendFileContentsToFileHandle(part.first, file)) {
+ LOG_ERROR("Failed copying File contents to a Blob temporary file for storage in IndexedDB");
+ return;
+ }
+ }
+ }
+
+ filePaths.append(tempFilePath.isolatedCopy());
+ }
+
+ completionCaller.disable();
+ callOnMainThread([completionHandler, filePaths]() {
+ completionHandler(filePaths);
+ });
+ });
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.h (199042 => 199043)
--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -67,6 +67,8 @@
unsigned long long blobSize(const URL&) override;
+ void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) override;
+
HashMap<String, RefPtr<BlobData>> m_blobs;
};
Modified: trunk/Source/WebKit2/ChangeLog (199042 => 199043)
--- trunk/Source/WebKit2/ChangeLog 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/ChangeLog 2016-04-05 05:47:32 UTC (rev 199043)
@@ -1,3 +1,30 @@
+2016-04-04 Brady Eidson <[email protected]>
+
+ Modern IDB: Dump blobs to disk before storing them in an object store.
+ https://bugs.webkit.org/show_bug.cgi?id=156068
+
+ 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:
+
2016-04-04 Chelsea Pugh <[email protected]>
[iOS] Allow clients in the bundle to know whether a field was focused by user interaction
Modified: trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp (199042 => 199043)
--- trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -117,6 +117,11 @@
return blobRegistry().blobSize(url);
}
+void NetworkBlobRegistry::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void(const Vector<String>&)> completionHandler)
+{
+ blobRegistry().writeBlobsToTemporaryFiles(blobURLs, completionHandler);
+}
+
void NetworkBlobRegistry::connectionToWebProcessDidClose(NetworkConnectionToWebProcess* connection)
{
if (!m_blobsForConnection.contains(connection))
Modified: trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h (199042 => 199043)
--- trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -27,6 +27,7 @@
#define NetworkBlobRegistry_h
#include <WebCore/URLHash.h>
+#include <functional>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -52,6 +53,7 @@
void registerBlobURLForSlice(NetworkConnectionToWebProcess*, const WebCore::URL&, const WebCore::URL& srcURL, int64_t start, int64_t end);
void unregisterBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&);
uint64_t blobSize(NetworkConnectionToWebProcess*, const WebCore::URL&);
+ void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void(const Vector<String>&)> completionHandler);
void connectionToWebProcessDidClose(NetworkConnectionToWebProcess*);
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp (199042 => 199043)
--- trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -30,11 +30,13 @@
#include "NetworkConnectionToWebProcessMessages.h"
#include "NetworkLoad.h"
#include "NetworkProcess.h"
+#include "NetworkProcessConnectionMessages.h"
#include "NetworkResourceLoadParameters.h"
#include "NetworkResourceLoader.h"
#include "NetworkResourceLoaderMessages.h"
#include "RemoteNetworkingContext.h"
#include "SessionTracker.h"
+#include "WebCoreArgumentCoders.h"
#include <WebCore/NotImplemented.h>
#include <WebCore/PingHandle.h>
#include <WebCore/PlatformCookieJar.h>
@@ -279,6 +281,28 @@
resultSize = NetworkBlobRegistry::singleton().blobSize(this, url);
}
+void NetworkConnectionToWebProcess::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, uint64_t requestIdentifier)
+{
+ RefPtr<NetworkConnectionToWebProcess> protector(this);
+
+ Vector<RefPtr<WebCore::BlobDataFileReference>> fileReferences;
+ for (auto& url : blobURLs)
+ fileReferences.appendVector(NetworkBlobRegistry::singleton().filesInBlob(*this, { ParsedURLString, url }));
+
+ for (auto& file : fileReferences)
+ file->prepareForFileAccess();
+
+ NetworkBlobRegistry::singleton().writeBlobsToTemporaryFiles(blobURLs, [this, protector, requestIdentifier, fileReferences](const Vector<String>& fileNames) {
+ for (auto& file : fileReferences)
+ file->revokeFileAccess();
+
+ if (!m_connection || !m_connection->isValid())
+ return;
+
+ m_connection->send(Messages::NetworkProcessConnection::DidWriteBlobsToTemporaryFiles(requestIdentifier, fileNames), 0);
+ });
+}
+
void NetworkConnectionToWebProcess::ensureLegacyPrivateBrowsingSession()
{
NetworkProcess::singleton().ensurePrivateBrowsingSession(SessionID::legacyPrivateSessionID());
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h (199042 => 199043)
--- trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -93,6 +93,8 @@
void registerBlobURLForSlice(const WebCore::URL&, const WebCore::URL& srcURL, int64_t start, int64_t end);
void blobSize(const WebCore::URL&, uint64_t& resultSize);
void unregisterBlobURL(const WebCore::URL&);
+ void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, uint64_t requestIdentifier);
+
void ensureLegacyPrivateBrowsingSession();
RefPtr<IPC::Connection> m_connection;
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in (199042 => 199043)
--- trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in 2016-04-05 05:47:32 UTC (rev 199043)
@@ -45,5 +45,7 @@
RegisterBlobURLForSlice(WebCore::URL url, WebCore::URL srcURL, int64_t start, int64_t end)
UnregisterBlobURL(WebCore::URL url)
BlobSize(WebCore::URL url) -> (uint64_t resultSize)
+ WriteBlobsToTemporaryFiles(Vector<String> blobURLs, uint64_t requestIdentifier)
+
EnsureLegacyPrivateBrowsingSession()
}
Modified: trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp (199042 => 199043)
--- trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -75,4 +75,9 @@
return resultSize;
}
+void BlobRegistryProxy::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler)
+{
+ WebProcess::singleton().networkConnection()->writeBlobsToTemporaryFiles(blobURLs, completionHandler);
}
+
+}
Modified: trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h (199042 => 199043)
--- trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -38,6 +38,7 @@
void unregisterBlobURL(const WebCore::URL&) override;
void registerBlobURLForSlice(const WebCore::URL&, const WebCore::URL& srcURL, long long start, long long end) override;
unsigned long long blobSize(const WebCore::URL&) override;
+ void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) override;
};
}
Modified: trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp (199042 => 199043)
--- trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp 2016-04-05 05:47:32 UTC (rev 199043)
@@ -72,12 +72,35 @@
{
// The NetworkProcess probably crashed.
WebProcess::singleton().networkProcessConnectionClosed(this);
+
+ Vector<String> dummyFilenames;
+ for (auto handler : m_writeBlobToFileCompletionHandlers.values())
+ handler(dummyFilenames);
+
+ m_writeBlobToFileCompletionHandlers.clear();
}
void NetworkProcessConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
{
}
+void NetworkProcessConnection::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler)
+{
+ static uint64_t writeBlobToFileIdentifier;
+ uint64_t requestIdentifier = ++writeBlobToFileIdentifier;
+
+ m_writeBlobToFileCompletionHandlers.set(requestIdentifier, completionHandler);
+
+ WebProcess::singleton().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::WriteBlobsToTemporaryFiles(blobURLs, requestIdentifier), 0);
+}
+
+void NetworkProcessConnection::didWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, const Vector<String>& filenames)
+{
+ auto handler = m_writeBlobToFileCompletionHandlers.take(requestIdentifier);
+ if (handler)
+ handler(filenames);
+}
+
#if ENABLE(SHAREABLE_RESOURCE)
void NetworkProcessConnection::didCacheResource(const ResourceRequest& request, const ShareableResource::Handle& handle, SessionID sessionID)
{
Modified: trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h (199042 => 199043)
--- trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h 2016-04-05 05:47:32 UTC (rev 199043)
@@ -58,6 +58,8 @@
void didReceiveNetworkProcessConnectionMessage(IPC::Connection&, IPC::MessageDecoder&);
+ void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler);
+
private:
NetworkProcessConnection(IPC::Connection::Identifier);
@@ -69,6 +71,8 @@
IPC::ProcessType localProcessType() override { return IPC::ProcessType::Web; }
IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Network; }
+ void didWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, const Vector<String>& filenames);
+
#if ENABLE(SHAREABLE_RESOURCE)
// Message handlers.
void didCacheResource(const WebCore::ResourceRequest&, const ShareableResource::Handle&, WebCore::SessionID);
@@ -76,6 +80,8 @@
// The connection from the web process to the network process.
RefPtr<IPC::Connection> m_connection;
+
+ HashMap<uint64_t, std::function<void (const Vector<String>&)>> m_writeBlobToFileCompletionHandlers;
};
} // namespace WebKit
Modified: trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in (199042 => 199043)
--- trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in 2016-04-05 05:39:18 UTC (rev 199042)
+++ trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in 2016-04-05 05:47:32 UTC (rev 199043)
@@ -26,4 +26,5 @@
DidCacheResource(WebCore::ResourceRequest request, WebKit::ShareableResource::Handle resource, WebCore::SessionID sessionID)
#endif
+ DidWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, Vector<String> filenames)
}