| Index: third_party/WebKit/Source/modules/indexeddb/IDBRequest.h
|
| diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.h b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.h
|
| index 8d87624bcac2d2d92a7ef8b6ce0b121e7b11925d..200b824d72382437adc9fee51afe584c8046b2a9 100644
|
| --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.h
|
| +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.h
|
| @@ -46,6 +46,7 @@
|
| #include "platform/blob/BlobData.h"
|
| #include "platform/heap/Handle.h"
|
| #include "platform/wtf/HashMap.h"
|
| +#include "platform/wtf/RefPtr.h"
|
| #include "public/platform/WebBlobInfo.h"
|
| #include "public/platform/modules/indexeddb/WebIDBCursor.h"
|
| #include "public/platform/modules/indexeddb/WebIDBTypes.h"
|
| @@ -112,24 +113,54 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
|
| void SetPendingCursor(IDBCursor*);
|
| void Abort();
|
|
|
| - void EnqueueResponse(DOMException*);
|
| - void EnqueueResponse(std::unique_ptr<WebIDBCursor>,
|
| - IDBKey*,
|
| - IDBKey* primary_key,
|
| - PassRefPtr<IDBValue>);
|
| - void EnqueueResponse(IDBKey*);
|
| - void EnqueueResponse(PassRefPtr<IDBValue>);
|
| - void EnqueueResponse(const Vector<RefPtr<IDBValue>>&);
|
| - void EnqueueResponse();
|
| - void EnqueueResponse(IDBKey*, IDBKey* primary_key, PassRefPtr<IDBValue>);
|
| + // Blink's delivery of results from IndexedDB's backing store to script is
|
| + // more complicated than prescribed in the IndexedDB specification.
|
| + //
|
| + // IDBValue, which holds responses from the backing store, is either the
|
| + // serialized V8 value, or a reference to a Blob that holds the serialized
|
| + // value. IDBValueWrapping.h has the motivation and details. This introduces
|
| + // the following complexities.
|
| + //
|
| + // 1) De-serialization is expensive, so it is done lazily in
|
| + // IDBRequest::result(), which is called synchronously from script. On the
|
| + // other hand, Blob data can only be fetched asynchronously. So, IDBValues
|
| + // that reference serialized data stored in Blobs must be processed before
|
| + // IDBRequest event handlers are invoked, because the event handler script may
|
| + // call IDBRequest::result().
|
| + //
|
| + // 2) The IDBRequest events must be dispatched (enqueued in DOMWindow's event
|
| + // queue) in the order in which the requests were issued. If an IDBValue
|
| + // references a Blob, the Blob processing must block event dispatch for all
|
| + // following IDBRequests in the same transaction.
|
| + //
|
| + // The Blob de-referencing and IDBRequest blocking is performed in the
|
| + // HandleResponse() overloads below. Each HandleResponse() overload is paired
|
| + // with a matching EnqueueResponse() overload, which is called when an
|
| + // IDBRequest's result event can be delivered to the application. All the
|
| + // HandleResponse() variants include a fast path that calls directly into
|
| + // EnqueueResponse() if no queueing is required.
|
| + //
|
| + // Some types of requests, such as indexedDB.openDatabase(), cannot be issued
|
| + // after a request that needs Blob processing, so their results are handled by
|
| + // having WebIDBCallbacksImpl call directly into EnqueueResponse(),
|
| + // EnqueueBlocked(), or EnqueueUpgradeNeeded().
|
| +
|
| + void HandleResponse(DOMException*);
|
| + void HandleResponse(IDBKey*);
|
| + void HandleResponse(std::unique_ptr<WebIDBCursor>,
|
| + IDBKey*,
|
| + IDBKey* primary_key,
|
| + RefPtr<IDBValue>&&);
|
| + void HandleResponse(IDBKey*, IDBKey* primary_key, RefPtr<IDBValue>&&);
|
| + void HandleResponse(RefPtr<IDBValue>&&);
|
| + void HandleResponse(const Vector<RefPtr<IDBValue>>&);
|
| + void HandleResponse(int64_t);
|
| + void HandleResponse();
|
|
|
| // Only used in webkitGetDatabaseNames(), which is deprecated and hopefully
|
| // going away soon.
|
| void EnqueueResponse(const Vector<String>&);
|
|
|
| - // Overridden by IDBOpenDBRequest.
|
| - virtual void EnqueueResponse(int64_t);
|
| -
|
| // Only IDBOpenDBRequest instances should receive these:
|
| virtual void EnqueueBlocked(int64_t old_version) { NOTREACHED(); }
|
| virtual void EnqueueUpgradeNeeded(int64_t old_version,
|
| @@ -162,10 +193,30 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
|
|
|
| IDBCursor* GetResultCursor() const;
|
|
|
| - void StorePutOperationBlobs(
|
| - HashMap<String, RefPtr<BlobDataHandle>> blob_handles) {
|
| - transit_blob_handles_ = std::move(blob_handles);
|
| + // Used to hang onto Blobs until the browser process handles the request.
|
| + //
|
| + // Blobs are ref-counted on the browser side, and BlobDataHandles manage
|
| + // references from renderers. When a BlobDataHandle gets destroyed, the
|
| + // browser-side Blob gets derefenced, which might cause it to be destroyed as
|
| + // well.
|
| + //
|
| + // After script uses a Blob in a put() request, the Blink-side Blob object
|
| + // (which hangs onto the BlobDataHandle) may get garbage-collected. IDBRequest
|
| + // needs to hang onto the BlobDataHandle as well, to avoid having the
|
| + // browser-side Blob get destroyed before the IndexedDB request is processed.
|
| + inline Vector<RefPtr<BlobDataHandle>>* transit_blob_handles() {
|
| + return &transit_blob_handles_;
|
| + }
|
| +
|
| +#if DCHECK_IS_ON()
|
| + inline bool TransactionHasQueuedResults() const {
|
| + return transaction_ && transaction_->HasQueuedResults();
|
| }
|
| +#endif // DCHECK_IS_ON()
|
| +
|
| +#if DCHECK_IS_ON()
|
| + inline IDBRequestQueueItem* QueueItem() const { return queue_item_; }
|
| +#endif // DCHECK_IS_ON()
|
|
|
| protected:
|
| IDBRequest(ScriptState*, IDBAny* source, IDBTransaction*);
|
| @@ -175,10 +226,16 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
|
| void EnqueueResultInternal(IDBAny*);
|
| void SetResult(IDBAny*);
|
|
|
| + // Overridden by IDBOpenDBRequest.
|
| + virtual void EnqueueResponse(int64_t);
|
| +
|
| // EventTarget
|
| DispatchEventResult DispatchEventInternal(Event*) override;
|
|
|
| + // Can be nullptr for requests that are not associated with a transaction,
|
| + // i.e. delete requests and completed or unsuccessful open requests.
|
| Member<IDBTransaction> transaction_;
|
| +
|
| ReadyState ready_state_ = PENDING;
|
| bool request_aborted_ = false; // May be aborted by transaction then receive
|
| // async onsuccess; ignore vs. assert.
|
| @@ -187,14 +244,26 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
|
| v8::Isolate* isolate_;
|
|
|
| private:
|
| + // Calls EnqueueResponse().
|
| + friend class IDBRequestQueueItem;
|
| +
|
| void SetResultCursor(IDBCursor*,
|
| IDBKey*,
|
| IDBKey* primary_key,
|
| - PassRefPtr<IDBValue>);
|
| + RefPtr<IDBValue>&&);
|
| void AckReceivedBlobs(const IDBValue*);
|
| void AckReceivedBlobs(const Vector<RefPtr<IDBValue>>&);
|
|
|
| - void ClearPutOperationBlobs() { transit_blob_handles_.clear(); }
|
| + void EnqueueResponse(DOMException*);
|
| + void EnqueueResponse(IDBKey*);
|
| + void EnqueueResponse(std::unique_ptr<WebIDBCursor>,
|
| + IDBKey*,
|
| + IDBKey* primary_key,
|
| + RefPtr<IDBValue>&&);
|
| + void EnqueueResponse(IDBKey*, IDBKey* primary_key, RefPtr<IDBValue>&&);
|
| + void EnqueueResponse(RefPtr<IDBValue>&&);
|
| + void EnqueueResponse(const Vector<RefPtr<IDBValue>>&);
|
| + void EnqueueResponse();
|
|
|
| Member<IDBAny> source_;
|
| Member<IDBAny> result_;
|
| @@ -215,7 +284,7 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
|
| Member<IDBKey> cursor_primary_key_;
|
| RefPtr<IDBValue> cursor_value_;
|
|
|
| - HashMap<String, RefPtr<BlobDataHandle>> transit_blob_handles_;
|
| + Vector<RefPtr<BlobDataHandle>> transit_blob_handles_;
|
|
|
| bool did_fire_upgrade_needed_event_ = false;
|
| bool prevent_propagation_ = false;
|
| @@ -230,6 +299,12 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
|
| // Pointer back to the WebIDBCallbacks that holds a persistent reference to
|
| // this object.
|
| WebIDBCallbacks* web_callbacks_ = nullptr;
|
| +
|
| + // Non-null while this request is queued behind other requests that are still
|
| + // getting post-processed.
|
| + //
|
| + // The IDBRequestQueueItem is owned by the result queue in IDBTransaction.
|
| + IDBRequestQueueItem* queue_item_ = nullptr;
|
| };
|
|
|
| } // namespace blink
|
|
|