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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "content/child/url_response_body_consumer.h"
6
7 #include "base/bind.h"
8 #include "base/macros.h"
9 #include "base/memory/ptr_util.h"
10 #include "content/child/resource_dispatcher.h"
11 #include "content/common/resource_messages.h"
12 #include "content/common/resource_request_completion_status.h"
13 #include "content/public/child/request_peer.h"
14
15 namespace content {
16
17 class URLResponseBodyConsumer::ReceivedData final
18 : public RequestPeer::ReceivedData {
19 public:
20 ReceivedData(const char* payload,
21 int length,
22 scoped_refptr<URLResponseBodyConsumer> consumer)
23 : payload_(payload), length_(length), consumer_(consumer) {}
24
25 ~ReceivedData() override { consumer_->Reclaim(length_); }
26
27 const char* payload() const override { return payload_; }
28 int length() const override { return length_; }
29 // TODO(yhirano): These return incorrect values. Remove these from
30 // ReceivedData before enabling Mojo-Loading.
31 int encoded_data_length() const override { return length_; }
32 int encoded_body_length() const override { return length_; }
33
34 private:
35 const char* const payload_;
36 const uint32_t length_;
37
38 scoped_refptr<URLResponseBodyConsumer> consumer_;
39
40 DISALLOW_COPY_AND_ASSIGN(ReceivedData);
41 };
42
43 URLResponseBodyConsumer::URLResponseBodyConsumer(
44 int request_id,
45 ResourceDispatcher* resource_dispatcher,
46 mojo::ScopedDataPipeConsumerHandle handle)
47 : request_id_(request_id),
48 resource_dispatcher_(resource_dispatcher),
49 handle_(std::move(handle)),
50 has_seen_end_of_data_(!handle_.is_valid()) {
51 StartWatching();
52 }
53
54 URLResponseBodyConsumer::~URLResponseBodyConsumer() {}
55
56 void URLResponseBodyConsumer::OnComplete(
57 const ResourceRequestCompletionStatus& status) {
58 if (has_been_cancelled_)
59 return;
60 has_received_completion_ = true;
61 completion_status_ = status;
62 NotifyCompletionIfAppropriate();
63 }
64
65 void URLResponseBodyConsumer::Cancel() {
66 has_been_cancelled_ = true;
67 handle_watcher_.Stop();
68 }
69
70 void URLResponseBodyConsumer::Reclaim(uint32_t size) {
71 MojoResult result = mojo::EndReadDataRaw(handle_.get(), size);
72 DCHECK_EQ(MOJO_RESULT_OK, result);
73 StartWatching();
74 }
75
76 void URLResponseBodyConsumer::OnReadable(MojoResult unused) {
77 DCHECK(!has_been_cancelled_);
78
79 // TODO(yhirano): Suppress notification when deferred.
80 // TODO(yhirano): Run this operation on the loading task runner.
81 const void* buffer = nullptr;
82 uint32_t available = 0;
83 MojoResult result = mojo::BeginReadDataRaw(handle_.get(), &buffer, &available,
84 MOJO_READ_DATA_FLAG_NONE);
85 if (result == MOJO_RESULT_OK) {
86 ResourceDispatcher::PendingRequestInfo* request_info =
87 resource_dispatcher_->GetPendingRequestInfo(request_id_);
88 DCHECK(request_info);
89 request_info->peer->OnReceivedData(base::WrapUnique(
90 new ReceivedData(static_cast<const char*>(buffer), available, this)));
91 // |this| may be deleted.
92 return;
93 }
94 if (result == MOJO_RESULT_FAILED_PRECONDITION) {
95 has_seen_end_of_data_ = true;
96 NotifyCompletionIfAppropriate();
97 // |this| may be deleted.
98 return;
99 }
100 if (result == MOJO_RESULT_SHOULD_WAIT) {
101 StartWatching();
102 return;
103 }
104 completion_status_.error_code = net::ERR_FAILED;
105 has_seen_end_of_data_ = true;
106 has_received_completion_ = true;
107 NotifyCompletionIfAppropriate();
108 // |this| may be deleted.
109 }
110
111 void URLResponseBodyConsumer::StartWatching() {
112 if (has_been_cancelled_ || has_seen_end_of_data_)
113 return;
114 handle_watcher_.Start(
115 handle_.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
116 base::Bind(&URLResponseBodyConsumer::OnReadable, base::Unretained(this)));
117 }
118
119 void URLResponseBodyConsumer::NotifyCompletionIfAppropriate() {
120 if (has_been_cancelled_)
121 return;
122 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.
123 // Cancel this instance in order not to notify twice.
124 Cancel();
125
126 resource_dispatcher_->OnMessageReceived(
127 ResourceMsg_RequestComplete(request_id_, completion_status_));
128 // |this| may be deleted.
129 }
130 }
131
132 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698