Index: third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp |
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..48afd5c486ea5e6f7cb77b7fdc13d96ec4112d49 |
--- /dev/null |
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp |
@@ -0,0 +1,263 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "modules/indexeddb/IDBRequestQueueItem.h" |
+ |
+#include "core/dom/DOMException.h" |
+#include "modules/indexeddb/IDBKey.h" |
+#include "modules/indexeddb/IDBRequest.h" |
+#include "modules/indexeddb/IDBRequestLoader.h" |
+#include "modules/indexeddb/IDBValue.h" |
+#include "platform/wtf/PtrUtil.h" |
+#include "public/platform/modules/indexeddb/WebIDBCursor.h" |
+ |
+namespace blink { |
+ |
+IDBRequestQueueItem::IDBRequestQueueItem( |
+ IDBRequest* request, |
+ DOMException* error, |
+ std::unique_ptr<WTF::Closure> on_result_load_complete) |
+ : request_(request), |
+ error_(error), |
+ on_result_load_complete_(std::move(on_result_load_complete)), |
+ response_type_(kError), |
+ ready_(true) { |
+ DCHECK(on_result_load_complete_); |
+ DCHECK_EQ(request->queue_item_, nullptr); |
+ request_->queue_item_ = this; |
+} |
+ |
+IDBRequestQueueItem::IDBRequestQueueItem( |
+ IDBRequest* request, |
+ int64_t value, |
+ std::unique_ptr<WTF::Closure> on_result_load_complete) |
+ : request_(request), |
+ on_result_load_complete_(std::move(on_result_load_complete)), |
+ int64_value_(value), |
+ response_type_(kNumber), |
+ ready_(true) { |
+ DCHECK(on_result_load_complete_); |
+ DCHECK_EQ(request->queue_item_, nullptr); |
+ request_->queue_item_ = this; |
+} |
+ |
+IDBRequestQueueItem::IDBRequestQueueItem( |
+ IDBRequest* request, |
+ std::unique_ptr<WTF::Closure> on_result_load_complete) |
+ : request_(request), |
+ on_result_load_complete_(std::move(on_result_load_complete)), |
+ response_type_(kVoid), |
+ ready_(true) { |
+ DCHECK(on_result_load_complete_); |
+ DCHECK_EQ(request->queue_item_, nullptr); |
+ request_->queue_item_ = this; |
+} |
+ |
+IDBRequestQueueItem::IDBRequestQueueItem( |
+ IDBRequest* request, |
+ IDBKey* key, |
+ std::unique_ptr<WTF::Closure> on_result_load_complete) |
+ : request_(request), |
+ key_(key), |
+ on_result_load_complete_(std::move(on_result_load_complete)), |
+ response_type_(kKey), |
+ ready_(true) { |
+ DCHECK(on_result_load_complete_); |
+ DCHECK_EQ(request->queue_item_, nullptr); |
+ request_->queue_item_ = this; |
+} |
+ |
+IDBRequestQueueItem::IDBRequestQueueItem( |
+ IDBRequest* request, |
+ PassRefPtr<IDBValue> value, |
+ bool attach_loader, |
+ std::unique_ptr<WTF::Closure> on_result_load_complete) |
+ : request_(request), |
+ on_result_load_complete_(std::move(on_result_load_complete)), |
+ response_type_(kValue), |
+ ready_(!attach_loader) { |
+ DCHECK(on_result_load_complete_); |
+ DCHECK_EQ(request->queue_item_, nullptr); |
+ request_->queue_item_ = this; |
+ values_.push_back(std::move(value)); |
+ if (attach_loader) |
+ loader_ = WTF::MakeUnique<IDBRequestLoader>(this, &values_); |
+} |
+ |
+IDBRequestQueueItem::IDBRequestQueueItem( |
+ IDBRequest* request, |
+ const Vector<RefPtr<IDBValue>>& values, |
+ bool attach_loader, |
+ std::unique_ptr<WTF::Closure> on_result_load_complete) |
+ : request_(request), |
+ values_(values), |
+ on_result_load_complete_(std::move(on_result_load_complete)), |
+ response_type_(kValueArray), |
+ ready_(!attach_loader) { |
+ DCHECK(on_result_load_complete_); |
+ DCHECK_EQ(request->queue_item_, nullptr); |
+ request_->queue_item_ = this; |
+ if (attach_loader) |
+ loader_ = WTF::MakeUnique<IDBRequestLoader>(this, &values_); |
+} |
+ |
+IDBRequestQueueItem::IDBRequestQueueItem( |
+ IDBRequest* request, |
+ IDBKey* key, |
+ IDBKey* primary_key, |
+ PassRefPtr<IDBValue> value, |
+ bool attach_loader, |
+ std::unique_ptr<WTF::Closure> on_result_load_complete) |
+ : request_(request), |
+ key_(key), |
+ primary_key_(primary_key), |
+ on_result_load_complete_(std::move(on_result_load_complete)), |
+ response_type_(kKeyPrimaryKeyValue), |
+ ready_(!attach_loader) { |
+ DCHECK(on_result_load_complete_); |
+ DCHECK_EQ(request->queue_item_, nullptr); |
+ request_->queue_item_ = this; |
+ values_.push_back(std::move(value)); |
+ if (attach_loader) |
+ loader_ = WTF::MakeUnique<IDBRequestLoader>(this, &values_); |
+} |
+ |
+IDBRequestQueueItem::IDBRequestQueueItem( |
+ IDBRequest* request, |
+ std::unique_ptr<WebIDBCursor> cursor, |
+ IDBKey* key, |
+ IDBKey* primary_key, |
+ PassRefPtr<IDBValue> value, |
+ bool attach_loader, |
+ std::unique_ptr<WTF::Closure> on_result_load_complete) |
+ : request_(request), |
+ key_(key), |
+ primary_key_(primary_key), |
+ cursor_(std::move(cursor)), |
+ on_result_load_complete_(std::move(on_result_load_complete)), |
+ response_type_(kCursorKeyPrimaryKeyValue), |
+ ready_(!attach_loader) { |
+ DCHECK(on_result_load_complete_); |
+ DCHECK_EQ(request->queue_item_, nullptr); |
+ request_->queue_item_ = this; |
+ values_.push_back(std::move(value)); |
+ if (attach_loader) |
+ loader_ = WTF::MakeUnique<IDBRequestLoader>(this, &values_); |
+} |
+ |
+IDBRequestQueueItem::~IDBRequestQueueItem() { |
+#if DCHECK_IS_ON() |
+ DCHECK(ready_); |
+ DCHECK(callback_fired_); |
+#endif // DCHECK_IS_ON() |
+} |
+ |
+void IDBRequestQueueItem::OnResultLoadComplete() { |
+ DCHECK(!ready_); |
+ ready_ = true; |
+ |
+ DCHECK(on_result_load_complete_); |
+ (*on_result_load_complete_)(); |
+} |
+ |
+void IDBRequestQueueItem::OnResultLoadComplete(DOMException* error) { |
+ DCHECK(!ready_); |
+ DCHECK(response_type_ != kError); |
+ |
+ response_type_ = kError; |
+ error_ = error; |
+ |
+ // This is not necessary, but releases non-trivial amounts of memory early. |
+ values_.clear(); |
+ |
+ OnResultLoadComplete(); |
+} |
+ |
+void IDBRequestQueueItem::StartLoading() { |
+ if (request_->request_aborted_) { |
+ // The backing store can get the result back to the request after it's been |
+ // aborted due to a transaction abort. In this case, we can't rely on |
+ // IDBRequest::Abort() to call CancelLoading(). |
+ CancelLoading(); |
+ return; |
+ } |
+ |
+ if (loader_) { |
+ DCHECK(!ready_); |
+ loader_->Start(); |
+ } |
+} |
+ |
+void IDBRequestQueueItem::CancelLoading() { |
+ if (ready_) |
+ return; |
+ |
+ if (loader_) { |
+ loader_->Cancel(); |
+ loader_ = nullptr; |
+ } |
+ |
+ // Mark this item as ready so the transaction's result queue can be drained. |
+ response_type_ = kCanceled; |
+ values_.clear(); |
+ OnResultLoadComplete(); |
+} |
+ |
+void IDBRequestQueueItem::EnqueueResponse() { |
+ DCHECK(ready_); |
+#if DCHECK_IS_ON() |
+ DCHECK(!callback_fired_); |
+ callback_fired_ = true; |
+#endif // DCHECK_IS_ON() |
+ DCHECK_EQ(request_->queue_item_, this); |
+ request_->queue_item_ = nullptr; |
+ |
+ switch (response_type_) { |
+ case kCanceled: |
+ DCHECK_EQ(values_.size(), 0U); |
+ break; |
+ |
+ case kCursorKeyPrimaryKeyValue: |
+ DCHECK_EQ(values_.size(), 1U); |
+ request_->EnqueueResponse(std::move(cursor_), key_, primary_key_, |
+ std::move(values_.front())); |
+ break; |
+ |
+ case kError: |
+ DCHECK(error_); |
+ request_->EnqueueResponse(error_); |
+ break; |
+ |
+ case kKeyPrimaryKeyValue: |
+ DCHECK_EQ(values_.size(), 1U); |
+ request_->EnqueueResponse(key_, primary_key_, std::move(values_.front())); |
+ break; |
+ |
+ case kKey: |
+ DCHECK_EQ(values_.size(), 0U); |
+ request_->EnqueueResponse(key_); |
+ break; |
+ |
+ case kNumber: |
+ DCHECK_EQ(values_.size(), 0U); |
+ request_->EnqueueResponse(int64_value_); |
+ break; |
+ |
+ case kValue: |
+ DCHECK_EQ(values_.size(), 1U); |
+ request_->EnqueueResponse(std::move(values_.front())); |
+ break; |
+ |
+ case kValueArray: |
+ request_->EnqueueResponse(values_); |
+ break; |
+ |
+ case kVoid: |
+ DCHECK_EQ(values_.size(), 0U); |
+ request_->EnqueueResponse(); |
+ break; |
+ } |
+} |
+ |
+} // namespace blink |