OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "modules/indexeddb/IDBRequestQueueItem.h" |
| 6 |
| 7 #include "core/dom/DOMException.h" |
| 8 #include "modules/indexeddb/IDBKey.h" |
| 9 #include "modules/indexeddb/IDBRequest.h" |
| 10 #include "modules/indexeddb/IDBRequestLoader.h" |
| 11 #include "modules/indexeddb/IDBValue.h" |
| 12 #include "platform/wtf/PtrUtil.h" |
| 13 #include "public/platform/modules/indexeddb/WebIDBCursor.h" |
| 14 |
| 15 namespace blink { |
| 16 |
| 17 IDBRequestQueueItem::IDBRequestQueueItem( |
| 18 IDBRequest* request, |
| 19 DOMException* error, |
| 20 std::unique_ptr<WTF::Closure> on_result_load_complete) |
| 21 : request_(request), |
| 22 error_(error), |
| 23 on_result_load_complete_(std::move(on_result_load_complete)), |
| 24 response_type_(kError), |
| 25 ready_(true) { |
| 26 DCHECK(on_result_load_complete_); |
| 27 DCHECK_EQ(request->queue_item_, nullptr); |
| 28 request_->queue_item_ = this; |
| 29 } |
| 30 |
| 31 IDBRequestQueueItem::IDBRequestQueueItem( |
| 32 IDBRequest* request, |
| 33 int64_t value, |
| 34 std::unique_ptr<WTF::Closure> on_result_load_complete) |
| 35 : request_(request), |
| 36 on_result_load_complete_(std::move(on_result_load_complete)), |
| 37 int64_value_(value), |
| 38 response_type_(kNumber), |
| 39 ready_(true) { |
| 40 DCHECK(on_result_load_complete_); |
| 41 DCHECK_EQ(request->queue_item_, nullptr); |
| 42 request_->queue_item_ = this; |
| 43 } |
| 44 |
| 45 IDBRequestQueueItem::IDBRequestQueueItem( |
| 46 IDBRequest* request, |
| 47 std::unique_ptr<WTF::Closure> on_result_load_complete) |
| 48 : request_(request), |
| 49 on_result_load_complete_(std::move(on_result_load_complete)), |
| 50 response_type_(kVoid), |
| 51 ready_(true) { |
| 52 DCHECK(on_result_load_complete_); |
| 53 DCHECK_EQ(request->queue_item_, nullptr); |
| 54 request_->queue_item_ = this; |
| 55 } |
| 56 |
| 57 IDBRequestQueueItem::IDBRequestQueueItem( |
| 58 IDBRequest* request, |
| 59 IDBKey* key, |
| 60 std::unique_ptr<WTF::Closure> on_result_load_complete) |
| 61 : request_(request), |
| 62 key_(key), |
| 63 on_result_load_complete_(std::move(on_result_load_complete)), |
| 64 response_type_(kKey), |
| 65 ready_(true) { |
| 66 DCHECK(on_result_load_complete_); |
| 67 DCHECK_EQ(request->queue_item_, nullptr); |
| 68 request_->queue_item_ = this; |
| 69 } |
| 70 |
| 71 IDBRequestQueueItem::IDBRequestQueueItem( |
| 72 IDBRequest* request, |
| 73 PassRefPtr<IDBValue> value, |
| 74 bool attach_loader, |
| 75 std::unique_ptr<WTF::Closure> on_result_load_complete) |
| 76 : request_(request), |
| 77 on_result_load_complete_(std::move(on_result_load_complete)), |
| 78 response_type_(kValue), |
| 79 ready_(!attach_loader) { |
| 80 DCHECK(on_result_load_complete_); |
| 81 DCHECK_EQ(request->queue_item_, nullptr); |
| 82 request_->queue_item_ = this; |
| 83 values_.push_back(std::move(value)); |
| 84 if (attach_loader) |
| 85 loader_ = WTF::MakeUnique<IDBRequestLoader>(this, &values_); |
| 86 } |
| 87 |
| 88 IDBRequestQueueItem::IDBRequestQueueItem( |
| 89 IDBRequest* request, |
| 90 const Vector<RefPtr<IDBValue>>& values, |
| 91 bool attach_loader, |
| 92 std::unique_ptr<WTF::Closure> on_result_load_complete) |
| 93 : request_(request), |
| 94 values_(values), |
| 95 on_result_load_complete_(std::move(on_result_load_complete)), |
| 96 response_type_(kValueArray), |
| 97 ready_(!attach_loader) { |
| 98 DCHECK(on_result_load_complete_); |
| 99 DCHECK_EQ(request->queue_item_, nullptr); |
| 100 request_->queue_item_ = this; |
| 101 if (attach_loader) |
| 102 loader_ = WTF::MakeUnique<IDBRequestLoader>(this, &values_); |
| 103 } |
| 104 |
| 105 IDBRequestQueueItem::IDBRequestQueueItem( |
| 106 IDBRequest* request, |
| 107 IDBKey* key, |
| 108 IDBKey* primary_key, |
| 109 PassRefPtr<IDBValue> value, |
| 110 bool attach_loader, |
| 111 std::unique_ptr<WTF::Closure> on_result_load_complete) |
| 112 : request_(request), |
| 113 key_(key), |
| 114 primary_key_(primary_key), |
| 115 on_result_load_complete_(std::move(on_result_load_complete)), |
| 116 response_type_(kKeyPrimaryKeyValue), |
| 117 ready_(!attach_loader) { |
| 118 DCHECK(on_result_load_complete_); |
| 119 DCHECK_EQ(request->queue_item_, nullptr); |
| 120 request_->queue_item_ = this; |
| 121 values_.push_back(std::move(value)); |
| 122 if (attach_loader) |
| 123 loader_ = WTF::MakeUnique<IDBRequestLoader>(this, &values_); |
| 124 } |
| 125 |
| 126 IDBRequestQueueItem::IDBRequestQueueItem( |
| 127 IDBRequest* request, |
| 128 std::unique_ptr<WebIDBCursor> cursor, |
| 129 IDBKey* key, |
| 130 IDBKey* primary_key, |
| 131 PassRefPtr<IDBValue> value, |
| 132 bool attach_loader, |
| 133 std::unique_ptr<WTF::Closure> on_result_load_complete) |
| 134 : request_(request), |
| 135 key_(key), |
| 136 primary_key_(primary_key), |
| 137 cursor_(std::move(cursor)), |
| 138 on_result_load_complete_(std::move(on_result_load_complete)), |
| 139 response_type_(kCursorKeyPrimaryKeyValue), |
| 140 ready_(!attach_loader) { |
| 141 DCHECK(on_result_load_complete_); |
| 142 DCHECK_EQ(request->queue_item_, nullptr); |
| 143 request_->queue_item_ = this; |
| 144 values_.push_back(std::move(value)); |
| 145 if (attach_loader) |
| 146 loader_ = WTF::MakeUnique<IDBRequestLoader>(this, &values_); |
| 147 } |
| 148 |
| 149 IDBRequestQueueItem::~IDBRequestQueueItem() { |
| 150 #if DCHECK_IS_ON() |
| 151 DCHECK(ready_); |
| 152 DCHECK(callback_fired_); |
| 153 #endif // DCHECK_IS_ON() |
| 154 } |
| 155 |
| 156 void IDBRequestQueueItem::OnResultLoadComplete() { |
| 157 DCHECK(!ready_); |
| 158 ready_ = true; |
| 159 |
| 160 DCHECK(on_result_load_complete_); |
| 161 (*on_result_load_complete_)(); |
| 162 } |
| 163 |
| 164 void IDBRequestQueueItem::OnResultLoadComplete(DOMException* error) { |
| 165 DCHECK(!ready_); |
| 166 DCHECK(response_type_ != kError); |
| 167 |
| 168 response_type_ = kError; |
| 169 error_ = error; |
| 170 |
| 171 // This is not necessary, but releases non-trivial amounts of memory early. |
| 172 values_.clear(); |
| 173 |
| 174 OnResultLoadComplete(); |
| 175 } |
| 176 |
| 177 void IDBRequestQueueItem::StartLoading() { |
| 178 if (request_->request_aborted_) { |
| 179 // The backing store can get the result back to the request after it's been |
| 180 // aborted due to a transaction abort. In this case, we can't rely on |
| 181 // IDBRequest::Abort() to call CancelLoading(). |
| 182 CancelLoading(); |
| 183 return; |
| 184 } |
| 185 |
| 186 if (loader_) { |
| 187 DCHECK(!ready_); |
| 188 loader_->Start(); |
| 189 } |
| 190 } |
| 191 |
| 192 void IDBRequestQueueItem::CancelLoading() { |
| 193 if (ready_) |
| 194 return; |
| 195 |
| 196 if (loader_) { |
| 197 loader_->Cancel(); |
| 198 loader_ = nullptr; |
| 199 } |
| 200 |
| 201 // Mark this item as ready so the transaction's result queue can be drained. |
| 202 response_type_ = kCanceled; |
| 203 values_.clear(); |
| 204 OnResultLoadComplete(); |
| 205 } |
| 206 |
| 207 void IDBRequestQueueItem::EnqueueResponse() { |
| 208 DCHECK(ready_); |
| 209 #if DCHECK_IS_ON() |
| 210 DCHECK(!callback_fired_); |
| 211 callback_fired_ = true; |
| 212 #endif // DCHECK_IS_ON() |
| 213 DCHECK_EQ(request_->queue_item_, this); |
| 214 request_->queue_item_ = nullptr; |
| 215 |
| 216 switch (response_type_) { |
| 217 case kCanceled: |
| 218 DCHECK_EQ(values_.size(), 0U); |
| 219 break; |
| 220 |
| 221 case kCursorKeyPrimaryKeyValue: |
| 222 DCHECK_EQ(values_.size(), 1U); |
| 223 request_->EnqueueResponse(std::move(cursor_), key_, primary_key_, |
| 224 std::move(values_.front())); |
| 225 break; |
| 226 |
| 227 case kError: |
| 228 DCHECK(error_); |
| 229 request_->EnqueueResponse(error_); |
| 230 break; |
| 231 |
| 232 case kKeyPrimaryKeyValue: |
| 233 DCHECK_EQ(values_.size(), 1U); |
| 234 request_->EnqueueResponse(key_, primary_key_, std::move(values_.front())); |
| 235 break; |
| 236 |
| 237 case kKey: |
| 238 DCHECK_EQ(values_.size(), 0U); |
| 239 request_->EnqueueResponse(key_); |
| 240 break; |
| 241 |
| 242 case kNumber: |
| 243 DCHECK_EQ(values_.size(), 0U); |
| 244 request_->EnqueueResponse(int64_value_); |
| 245 break; |
| 246 |
| 247 case kValue: |
| 248 DCHECK_EQ(values_.size(), 1U); |
| 249 request_->EnqueueResponse(std::move(values_.front())); |
| 250 break; |
| 251 |
| 252 case kValueArray: |
| 253 request_->EnqueueResponse(values_); |
| 254 break; |
| 255 |
| 256 case kVoid: |
| 257 DCHECK_EQ(values_.size(), 0U); |
| 258 request_->EnqueueResponse(); |
| 259 break; |
| 260 } |
| 261 } |
| 262 |
| 263 } // namespace blink |
OLD | NEW |