Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: third_party/WebKit/Source/modules/indexeddb/IDBRequest.h

Issue 2822453003: Wrap large IndexedDB values into Blobs before writing to LevelDB. (Closed)
Patch Set: Addressed last round of feedback. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 28 matching lines...) Expand all
39 #include "modules/EventModules.h" 39 #include "modules/EventModules.h"
40 #include "modules/ModulesExport.h" 40 #include "modules/ModulesExport.h"
41 #include "modules/indexeddb/IDBAny.h" 41 #include "modules/indexeddb/IDBAny.h"
42 #include "modules/indexeddb/IDBTransaction.h" 42 #include "modules/indexeddb/IDBTransaction.h"
43 #include "modules/indexeddb/IndexedDB.h" 43 #include "modules/indexeddb/IndexedDB.h"
44 #include "platform/bindings/ActiveScriptWrappable.h" 44 #include "platform/bindings/ActiveScriptWrappable.h"
45 #include "platform/bindings/ScriptState.h" 45 #include "platform/bindings/ScriptState.h"
46 #include "platform/blob/BlobData.h" 46 #include "platform/blob/BlobData.h"
47 #include "platform/heap/Handle.h" 47 #include "platform/heap/Handle.h"
48 #include "platform/wtf/HashMap.h" 48 #include "platform/wtf/HashMap.h"
49 #include "platform/wtf/RefPtr.h"
49 #include "public/platform/WebBlobInfo.h" 50 #include "public/platform/WebBlobInfo.h"
50 #include "public/platform/modules/indexeddb/WebIDBCursor.h" 51 #include "public/platform/modules/indexeddb/WebIDBCursor.h"
51 #include "public/platform/modules/indexeddb/WebIDBTypes.h" 52 #include "public/platform/modules/indexeddb/WebIDBTypes.h"
52 53
53 namespace blink { 54 namespace blink {
54 55
55 class DOMException; 56 class DOMException;
56 class ExceptionState; 57 class ExceptionState;
57 class IDBCursor; 58 class IDBCursor;
58 struct IDBDatabaseMetadata; 59 struct IDBDatabaseMetadata;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 WebIDBCallbacks* WebCallbacks() const { return web_callbacks_; } 106 WebIDBCallbacks* WebCallbacks() const { return web_callbacks_; }
106 #endif // DCHECK_IS_ON() 107 #endif // DCHECK_IS_ON()
107 108
108 DEFINE_ATTRIBUTE_EVENT_LISTENER(success); 109 DEFINE_ATTRIBUTE_EVENT_LISTENER(success);
109 DEFINE_ATTRIBUTE_EVENT_LISTENER(error); 110 DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
110 111
111 void SetCursorDetails(IndexedDB::CursorType, WebIDBCursorDirection); 112 void SetCursorDetails(IndexedDB::CursorType, WebIDBCursorDirection);
112 void SetPendingCursor(IDBCursor*); 113 void SetPendingCursor(IDBCursor*);
113 void Abort(); 114 void Abort();
114 115
115 void EnqueueResponse(DOMException*); 116 // Blink's delivery of results from IndexedDB's backing store to script is
116 void EnqueueResponse(std::unique_ptr<WebIDBCursor>, 117 // more complicated than prescribed in the IndexedDB specification.
117 IDBKey*, 118 //
118 IDBKey* primary_key, 119 // IDBValue, which holds responses from the backing store, is either the
119 PassRefPtr<IDBValue>); 120 // serialized V8 value, or a reference to a Blob that holds the serialized
120 void EnqueueResponse(IDBKey*); 121 // value. IDBValueWrapping.h has the motivation and details. This introduces
121 void EnqueueResponse(PassRefPtr<IDBValue>); 122 // the following complexities.
122 void EnqueueResponse(const Vector<RefPtr<IDBValue>>&); 123 //
123 void EnqueueResponse(); 124 // 1) De-serialization is expensive, so it is done lazily in
124 void EnqueueResponse(IDBKey*, IDBKey* primary_key, PassRefPtr<IDBValue>); 125 // IDBRequest::result(), which is called synchronously from script. On the
126 // other hand, Blob data can only be fetched asynchronously. So, IDBValues
127 // that reference serialized data stored in Blobs must be processed before
128 // IDBRequest event handlers are invoked, because the event handler script may
129 // call IDBRequest::result().
130 //
131 // 2) The IDBRequest events must be dispatched (enqueued in DOMWindow's event
132 // queue) in the order in which the requests were issued. If an IDBValue
133 // references a Blob, the Blob processing must block event dispatch for all
134 // following IDBRequests in the same transaction.
135 //
136 // The Blob de-referencing and IDBRequest blocking is performed in the
137 // HandleResponse() overloads below. Each HandleResponse() overload is paired
138 // with a matching EnqueueResponse() overload, which is called when an
139 // IDBRequest's result event can be delivered to the application. All the
140 // HandleResponse() variants include a fast path that calls directly into
141 // EnqueueResponse() if no queueing is required.
142 //
143 // Some types of requests, such as indexedDB.openDatabase(), cannot be issued
144 // after a request that needs Blob processing, so their results are handled by
145 // having WebIDBCallbacksImpl call directly into EnqueueResponse(),
146 // EnqueueBlocked(), or EnqueueUpgradeNeeded().
147
148 void HandleResponse(DOMException*);
149 void HandleResponse(IDBKey*);
150 void HandleResponse(std::unique_ptr<WebIDBCursor>,
151 IDBKey*,
152 IDBKey* primary_key,
153 RefPtr<IDBValue>&&);
154 void HandleResponse(IDBKey*, IDBKey* primary_key, RefPtr<IDBValue>&&);
155 void HandleResponse(RefPtr<IDBValue>&&);
156 void HandleResponse(const Vector<RefPtr<IDBValue>>&);
157 void HandleResponse(int64_t);
158 void HandleResponse();
125 159
126 // Only used in webkitGetDatabaseNames(), which is deprecated and hopefully 160 // Only used in webkitGetDatabaseNames(), which is deprecated and hopefully
127 // going away soon. 161 // going away soon.
128 void EnqueueResponse(const Vector<String>&); 162 void EnqueueResponse(const Vector<String>&);
129 163
130 // Overridden by IDBOpenDBRequest.
131 virtual void EnqueueResponse(int64_t);
132
133 // Only IDBOpenDBRequest instances should receive these: 164 // Only IDBOpenDBRequest instances should receive these:
134 virtual void EnqueueBlocked(int64_t old_version) { NOTREACHED(); } 165 virtual void EnqueueBlocked(int64_t old_version) { NOTREACHED(); }
135 virtual void EnqueueUpgradeNeeded(int64_t old_version, 166 virtual void EnqueueUpgradeNeeded(int64_t old_version,
136 std::unique_ptr<WebIDBDatabase>, 167 std::unique_ptr<WebIDBDatabase>,
137 const IDBDatabaseMetadata&, 168 const IDBDatabaseMetadata&,
138 WebIDBDataLoss, 169 WebIDBDataLoss,
139 String data_loss_message) { 170 String data_loss_message) {
140 NOTREACHED(); 171 NOTREACHED();
141 } 172 }
142 virtual void EnqueueResponse(std::unique_ptr<WebIDBDatabase>, 173 virtual void EnqueueResponse(std::unique_ptr<WebIDBDatabase>,
(...skipping 12 matching lines...) Expand all
155 ExecutionContext* GetExecutionContext() const final; 186 ExecutionContext* GetExecutionContext() const final;
156 void UncaughtExceptionInEventHandler() final; 187 void UncaughtExceptionInEventHandler() final;
157 188
158 // Called by a version change transaction that has finished to set this 189 // Called by a version change transaction that has finished to set this
159 // request back from DONE (following "upgradeneeded") back to PENDING (for 190 // request back from DONE (following "upgradeneeded") back to PENDING (for
160 // the upcoming "success" or "error"). 191 // the upcoming "success" or "error").
161 void TransactionDidFinishAndDispatch(); 192 void TransactionDidFinishAndDispatch();
162 193
163 IDBCursor* GetResultCursor() const; 194 IDBCursor* GetResultCursor() const;
164 195
165 void StorePutOperationBlobs( 196 // Used to hang onto Blobs until the browser process handles the request.
166 HashMap<String, RefPtr<BlobDataHandle>> blob_handles) { 197 //
167 transit_blob_handles_ = std::move(blob_handles); 198 // Blobs are ref-counted on the browser side, and BlobDataHandles manage
199 // references from renderers. When a BlobDataHandle gets destroyed, the
200 // browser-side Blob gets derefenced, which might cause it to be destroyed as
201 // well.
202 //
203 // After script uses a Blob in a put() request, the Blink-side Blob object
204 // (which hangs onto the BlobDataHandle) may get garbage-collected. IDBRequest
205 // needs to hang onto the BlobDataHandle as well, to avoid having the
206 // browser-side Blob get destroyed before the IndexedDB request is processed.
207 inline Vector<RefPtr<BlobDataHandle>>* transit_blob_handles() {
208 return &transit_blob_handles_;
168 } 209 }
169 210
211 #if DCHECK_IS_ON()
212 inline bool TransactionHasQueuedResults() const {
213 return transaction_ && transaction_->HasQueuedResults();
214 }
215 #endif // DCHECK_IS_ON()
216
217 #if DCHECK_IS_ON()
218 inline IDBRequestQueueItem* QueueItem() const { return queue_item_; }
219 #endif // DCHECK_IS_ON()
220
170 protected: 221 protected:
171 IDBRequest(ScriptState*, IDBAny* source, IDBTransaction*); 222 IDBRequest(ScriptState*, IDBAny* source, IDBTransaction*);
172 void EnqueueEvent(Event*); 223 void EnqueueEvent(Event*);
173 void DequeueEvent(Event*); 224 void DequeueEvent(Event*);
174 virtual bool ShouldEnqueueEvent() const; 225 virtual bool ShouldEnqueueEvent() const;
175 void EnqueueResultInternal(IDBAny*); 226 void EnqueueResultInternal(IDBAny*);
176 void SetResult(IDBAny*); 227 void SetResult(IDBAny*);
177 228
229 // Overridden by IDBOpenDBRequest.
230 virtual void EnqueueResponse(int64_t);
231
178 // EventTarget 232 // EventTarget
179 DispatchEventResult DispatchEventInternal(Event*) override; 233 DispatchEventResult DispatchEventInternal(Event*) override;
180 234
235 // Can be nullptr for requests that are not associated with a transaction,
236 // i.e. delete requests and completed or unsuccessful open requests.
181 Member<IDBTransaction> transaction_; 237 Member<IDBTransaction> transaction_;
238
182 ReadyState ready_state_ = PENDING; 239 ReadyState ready_state_ = PENDING;
183 bool request_aborted_ = false; // May be aborted by transaction then receive 240 bool request_aborted_ = false; // May be aborted by transaction then receive
184 // async onsuccess; ignore vs. assert. 241 // async onsuccess; ignore vs. assert.
185 // Maintain the isolate so that all externally allocated memory can be 242 // Maintain the isolate so that all externally allocated memory can be
186 // registered against it. 243 // registered against it.
187 v8::Isolate* isolate_; 244 v8::Isolate* isolate_;
188 245
189 private: 246 private:
247 // Calls EnqueueResponse().
248 friend class IDBRequestQueueItem;
249
190 void SetResultCursor(IDBCursor*, 250 void SetResultCursor(IDBCursor*,
191 IDBKey*, 251 IDBKey*,
192 IDBKey* primary_key, 252 IDBKey* primary_key,
193 PassRefPtr<IDBValue>); 253 RefPtr<IDBValue>&&);
194 void AckReceivedBlobs(const IDBValue*); 254 void AckReceivedBlobs(const IDBValue*);
195 void AckReceivedBlobs(const Vector<RefPtr<IDBValue>>&); 255 void AckReceivedBlobs(const Vector<RefPtr<IDBValue>>&);
196 256
197 void ClearPutOperationBlobs() { transit_blob_handles_.clear(); } 257 void EnqueueResponse(DOMException*);
258 void EnqueueResponse(IDBKey*);
259 void EnqueueResponse(std::unique_ptr<WebIDBCursor>,
260 IDBKey*,
261 IDBKey* primary_key,
262 RefPtr<IDBValue>&&);
263 void EnqueueResponse(IDBKey*, IDBKey* primary_key, RefPtr<IDBValue>&&);
264 void EnqueueResponse(RefPtr<IDBValue>&&);
265 void EnqueueResponse(const Vector<RefPtr<IDBValue>>&);
266 void EnqueueResponse();
198 267
199 Member<IDBAny> source_; 268 Member<IDBAny> source_;
200 Member<IDBAny> result_; 269 Member<IDBAny> result_;
201 Member<DOMException> error_; 270 Member<DOMException> error_;
202 271
203 bool has_pending_activity_ = true; 272 bool has_pending_activity_ = true;
204 HeapVector<Member<Event>> enqueued_events_; 273 HeapVector<Member<Event>> enqueued_events_;
205 274
206 // Only used if the result type will be a cursor. 275 // Only used if the result type will be a cursor.
207 IndexedDB::CursorType cursor_type_ = IndexedDB::kCursorKeyAndValue; 276 IndexedDB::CursorType cursor_type_ = IndexedDB::kCursorKeyAndValue;
208 WebIDBCursorDirection cursor_direction_ = kWebIDBCursorDirectionNext; 277 WebIDBCursorDirection cursor_direction_ = kWebIDBCursorDirectionNext;
209 // When a cursor is continued/advanced, |result_| is cleared and 278 // When a cursor is continued/advanced, |result_| is cleared and
210 // |pendingCursor_| holds it. 279 // |pendingCursor_| holds it.
211 Member<IDBCursor> pending_cursor_; 280 Member<IDBCursor> pending_cursor_;
212 // New state is not applied to the cursor object until the event is 281 // New state is not applied to the cursor object until the event is
213 // dispatched. 282 // dispatched.
214 Member<IDBKey> cursor_key_; 283 Member<IDBKey> cursor_key_;
215 Member<IDBKey> cursor_primary_key_; 284 Member<IDBKey> cursor_primary_key_;
216 RefPtr<IDBValue> cursor_value_; 285 RefPtr<IDBValue> cursor_value_;
217 286
218 HashMap<String, RefPtr<BlobDataHandle>> transit_blob_handles_; 287 Vector<RefPtr<BlobDataHandle>> transit_blob_handles_;
219 288
220 bool did_fire_upgrade_needed_event_ = false; 289 bool did_fire_upgrade_needed_event_ = false;
221 bool prevent_propagation_ = false; 290 bool prevent_propagation_ = false;
222 bool result_dirty_ = true; 291 bool result_dirty_ = true;
223 292
224 // Transactions should be aborted after event dispatch if an exception was 293 // Transactions should be aborted after event dispatch if an exception was
225 // not caught. This is cleared before dispatch, set by a call to 294 // not caught. This is cleared before dispatch, set by a call to
226 // UncaughtExceptionInEventHandler() during dispatch, and checked afterwards 295 // UncaughtExceptionInEventHandler() during dispatch, and checked afterwards
227 // to abort if necessary. 296 // to abort if necessary.
228 bool did_throw_in_event_handler_ = false; 297 bool did_throw_in_event_handler_ = false;
229 298
230 // Pointer back to the WebIDBCallbacks that holds a persistent reference to 299 // Pointer back to the WebIDBCallbacks that holds a persistent reference to
231 // this object. 300 // this object.
232 WebIDBCallbacks* web_callbacks_ = nullptr; 301 WebIDBCallbacks* web_callbacks_ = nullptr;
302
303 // Non-null while this request is queued behind other requests that are still
304 // getting post-processed.
305 //
306 // The IDBRequestQueueItem is owned by the result queue in IDBTransaction.
307 IDBRequestQueueItem* queue_item_ = nullptr;
233 }; 308 };
234 309
235 } // namespace blink 310 } // namespace blink
236 311
237 #endif // IDBRequest_h 312 #endif // IDBRequest_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698