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

Unified Diff: content/child/url_response_body_consumer.cc

Issue 1970693002: Use mojo for Chrome Loading, Part 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: content/child/url_response_body_consumer.cc
diff --git a/content/child/url_response_body_consumer.cc b/content/child/url_response_body_consumer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fed2006f4f44391e303ab02d84ff2e250687886a
--- /dev/null
+++ b/content/child/url_response_body_consumer.cc
@@ -0,0 +1,132 @@
+// Copyright 2016 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 "content/child/url_response_body_consumer.h"
+
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "content/child/resource_dispatcher.h"
+#include "content/common/resource_messages.h"
+#include "content/common/resource_request_completion_status.h"
+#include "content/public/child/request_peer.h"
+
+namespace content {
+
+class URLResponseBodyConsumer::ReceivedData final
+ : public RequestPeer::ReceivedData {
+ public:
+ ReceivedData(const char* payload,
+ int length,
+ scoped_refptr<URLResponseBodyConsumer> consumer)
+ : payload_(payload), length_(length), consumer_(consumer) {}
+
+ ~ReceivedData() override { consumer_->Reclaim(length_); }
+
+ const char* payload() const override { return payload_; }
+ int length() const override { return length_; }
+ // TODO(yhirano): These return incorrect values. Remove these from
+ // ReceivedData before enabling Mojo-Loading.
+ int encoded_data_length() const override { return length_; }
+ int encoded_body_length() const override { return length_; }
+
+ private:
+ const char* const payload_;
+ const uint32_t length_;
+
+ scoped_refptr<URLResponseBodyConsumer> consumer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ReceivedData);
+};
+
+URLResponseBodyConsumer::URLResponseBodyConsumer(
+ int request_id,
+ ResourceDispatcher* resource_dispatcher,
+ mojo::ScopedDataPipeConsumerHandle handle)
+ : request_id_(request_id),
+ resource_dispatcher_(resource_dispatcher),
+ handle_(std::move(handle)),
+ has_seen_end_of_data_(!handle_.is_valid()) {
+ StartWatching();
+}
+
+URLResponseBodyConsumer::~URLResponseBodyConsumer() {}
+
+void URLResponseBodyConsumer::OnComplete(
+ const ResourceRequestCompletionStatus& status) {
+ if (has_been_cancelled_)
+ return;
+ has_received_completion_ = true;
+ completion_status_ = status;
+ NotifyCompletionIfAppropriate();
+}
+
+void URLResponseBodyConsumer::Cancel() {
+ has_been_cancelled_ = true;
+ handle_watcher_.Stop();
+}
+
+void URLResponseBodyConsumer::Reclaim(uint32_t size) {
+ MojoResult result = mojo::EndReadDataRaw(handle_.get(), size);
+ DCHECK_EQ(MOJO_RESULT_OK, result);
+ StartWatching();
+}
+
+void URLResponseBodyConsumer::OnReadable(MojoResult unused) {
+ DCHECK(!has_been_cancelled_);
+
+ // TODO(yhirano): Suppress notification when deferred.
+ // TODO(yhirano): Run this operation on the loading task runner.
+ const void* buffer = nullptr;
+ uint32_t available = 0;
+ MojoResult result = mojo::BeginReadDataRaw(handle_.get(), &buffer, &available,
+ MOJO_READ_DATA_FLAG_NONE);
+ if (result == MOJO_RESULT_OK) {
+ ResourceDispatcher::PendingRequestInfo* request_info =
+ resource_dispatcher_->GetPendingRequestInfo(request_id_);
+ DCHECK(request_info);
+ request_info->peer->OnReceivedData(base::WrapUnique(
+ new ReceivedData(static_cast<const char*>(buffer), available, this)));
+ // |this| may be deleted.
+ return;
+ }
+ if (result == MOJO_RESULT_FAILED_PRECONDITION) {
+ has_seen_end_of_data_ = true;
+ NotifyCompletionIfAppropriate();
+ // |this| may be deleted.
+ return;
+ }
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ StartWatching();
+ return;
+ }
+ completion_status_.error_code = net::ERR_FAILED;
+ has_seen_end_of_data_ = true;
+ has_received_completion_ = true;
+ NotifyCompletionIfAppropriate();
+ // |this| may be deleted.
+}
+
+void URLResponseBodyConsumer::StartWatching() {
+ if (has_been_cancelled_ || has_seen_end_of_data_)
+ return;
+ handle_watcher_.Start(
+ handle_.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
+ base::Bind(&URLResponseBodyConsumer::OnReadable, base::Unretained(this)));
+}
+
+void URLResponseBodyConsumer::NotifyCompletionIfAppropriate() {
+ if (has_been_cancelled_)
+ return;
+ if (has_received_completion_ && has_seen_end_of_data_) {
kinuko 2016/08/04 16:07:03 nit: maybe early return in the other way instead
yhirano 2016/08/05 12:21:40 Done.
+ // Cancel this instance in order not to notify twice.
+ Cancel();
+
+ resource_dispatcher_->OnMessageReceived(
+ ResourceMsg_RequestComplete(request_id_, completion_status_));
+ // |this| may be deleted.
+ }
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698