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 |
| 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 #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 |
OLD | NEW |