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

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: Rebased. 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
jsbell 2017/05/22 21:54:19 How about: "IDBOpenDBRequests are not associated w
pwnall 2017/05/25 13:27:11 I like your explanation, because it's simpler, but
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
216 inline IDBRequestQueueItem* QueueItem() const { return queue_item_; }
217 #endif // DCHECK_IS_ON()
218
170 protected: 219 protected:
171 IDBRequest(ScriptState*, IDBAny* source, IDBTransaction*); 220 IDBRequest(ScriptState*, IDBAny* source, IDBTransaction*);
172 void EnqueueEvent(Event*); 221 void EnqueueEvent(Event*);
173 void DequeueEvent(Event*); 222 void DequeueEvent(Event*);
174 virtual bool ShouldEnqueueEvent() const; 223 virtual bool ShouldEnqueueEvent() const;
175 void EnqueueResultInternal(IDBAny*); 224 void EnqueueResultInternal(IDBAny*);
176 void SetResult(IDBAny*); 225 void SetResult(IDBAny*);
177 226
227 // Overridden by IDBOpenDBRequest.
228 virtual void EnqueueResponse(int64_t);
229
178 // EventTarget 230 // EventTarget
179 DispatchEventResult DispatchEventInternal(Event*) override; 231 DispatchEventResult DispatchEventInternal(Event*) override;
180 232
233 // Can be nullptr for requests that are not associated with a transaction,
234 // i.e. delete requests and completed or unsuccessful open requests.
181 Member<IDBTransaction> transaction_; 235 Member<IDBTransaction> transaction_;
236
182 ReadyState ready_state_ = PENDING; 237 ReadyState ready_state_ = PENDING;
183 bool request_aborted_ = false; // May be aborted by transaction then receive 238 bool request_aborted_ = false; // May be aborted by transaction then receive
184 // async onsuccess; ignore vs. assert. 239 // async onsuccess; ignore vs. assert.
185 // Maintain the isolate so that all externally allocated memory can be 240 // Maintain the isolate so that all externally allocated memory can be
186 // registered against it. 241 // registered against it.
187 v8::Isolate* isolate_; 242 v8::Isolate* isolate_;
188 243
189 private: 244 private:
245 // Calls EnqueueResponse().
246 friend class IDBRequestQueueItem;
247
190 void SetResultCursor(IDBCursor*, 248 void SetResultCursor(IDBCursor*,
191 IDBKey*, 249 IDBKey*,
192 IDBKey* primary_key, 250 IDBKey* primary_key,
193 PassRefPtr<IDBValue>); 251 RefPtr<IDBValue>&&);
194 void AckReceivedBlobs(const IDBValue*); 252 void AckReceivedBlobs(const IDBValue*);
195 void AckReceivedBlobs(const Vector<RefPtr<IDBValue>>&); 253 void AckReceivedBlobs(const Vector<RefPtr<IDBValue>>&);
196 254
197 void ClearPutOperationBlobs() { transit_blob_handles_.clear(); } 255 void EnqueueResponse(DOMException*);
256 void EnqueueResponse(IDBKey*);
257 void EnqueueResponse(std::unique_ptr<WebIDBCursor>,
258 IDBKey*,
259 IDBKey* primary_key,
260 RefPtr<IDBValue>&&);
261 void EnqueueResponse(IDBKey*, IDBKey* primary_key, RefPtr<IDBValue>&&);
262 void EnqueueResponse(RefPtr<IDBValue>&&);
263 void EnqueueResponse(const Vector<RefPtr<IDBValue>>&);
264 void EnqueueResponse();
198 265
199 Member<IDBAny> source_; 266 Member<IDBAny> source_;
200 Member<IDBAny> result_; 267 Member<IDBAny> result_;
201 Member<DOMException> error_; 268 Member<DOMException> error_;
202 269
203 bool has_pending_activity_ = true; 270 bool has_pending_activity_ = true;
204 HeapVector<Member<Event>> enqueued_events_; 271 HeapVector<Member<Event>> enqueued_events_;
205 272
206 // Only used if the result type will be a cursor. 273 // Only used if the result type will be a cursor.
207 IndexedDB::CursorType cursor_type_ = IndexedDB::kCursorKeyAndValue; 274 IndexedDB::CursorType cursor_type_ = IndexedDB::kCursorKeyAndValue;
208 WebIDBCursorDirection cursor_direction_ = kWebIDBCursorDirectionNext; 275 WebIDBCursorDirection cursor_direction_ = kWebIDBCursorDirectionNext;
209 // When a cursor is continued/advanced, |result_| is cleared and 276 // When a cursor is continued/advanced, |result_| is cleared and
210 // |pendingCursor_| holds it. 277 // |pendingCursor_| holds it.
211 Member<IDBCursor> pending_cursor_; 278 Member<IDBCursor> pending_cursor_;
212 // New state is not applied to the cursor object until the event is 279 // New state is not applied to the cursor object until the event is
213 // dispatched. 280 // dispatched.
214 Member<IDBKey> cursor_key_; 281 Member<IDBKey> cursor_key_;
215 Member<IDBKey> cursor_primary_key_; 282 Member<IDBKey> cursor_primary_key_;
216 RefPtr<IDBValue> cursor_value_; 283 RefPtr<IDBValue> cursor_value_;
217 284
218 HashMap<String, RefPtr<BlobDataHandle>> transit_blob_handles_; 285 Vector<RefPtr<BlobDataHandle>> transit_blob_handles_;
219 286
220 bool did_fire_upgrade_needed_event_ = false; 287 bool did_fire_upgrade_needed_event_ = false;
221 bool prevent_propagation_ = false; 288 bool prevent_propagation_ = false;
222 bool result_dirty_ = true; 289 bool result_dirty_ = true;
223 290
224 // Transactions should be aborted after event dispatch if an exception was 291 // Transactions should be aborted after event dispatch if an exception was
225 // not caught. This is cleared before dispatch, set by a call to 292 // not caught. This is cleared before dispatch, set by a call to
226 // UncaughtExceptionInEventHandler() during dispatch, and checked afterwards 293 // UncaughtExceptionInEventHandler() during dispatch, and checked afterwards
227 // to abort if necessary. 294 // to abort if necessary.
228 bool did_throw_in_event_handler_ = false; 295 bool did_throw_in_event_handler_ = false;
229 296
230 // Pointer back to the WebIDBCallbacks that holds a persistent reference to 297 // Pointer back to the WebIDBCallbacks that holds a persistent reference to
231 // this object. 298 // this object.
232 WebIDBCallbacks* web_callbacks_ = nullptr; 299 WebIDBCallbacks* web_callbacks_ = nullptr;
300
301 #if DCHECK_IS_ON()
302 // Non-null while this request is queued behind other requests that are still
303 // getting post-processed.
304 IDBRequestQueueItem* queue_item_ = nullptr;
305 #endif // DCHECK_IS_ON()
233 }; 306 };
234 307
235 } // namespace blink 308 } // namespace blink
236 309
237 #endif // IDBRequest_h 310 #endif // IDBRequest_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698