OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |