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

Side by Side Diff: content/child/url_response_body_consumer.cc

Issue 2644053002: [Mojo-Loading] Split too large data chunk in renderer (Closed)
Patch Set: fix Created 3 years, 11 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/child/url_response_body_consumer.h" 5 #include "content/child/url_response_body_consumer.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "content/child/resource_dispatcher.h" 11 #include "content/child/resource_dispatcher.h"
12 #include "content/common/resource_messages.h" 12 #include "content/common/resource_messages.h"
13 #include "content/common/resource_request_completion_status.h" 13 #include "content/common/resource_request_completion_status.h"
14 #include "content/public/child/request_peer.h" 14 #include "content/public/child/request_peer.h"
15 15
16 namespace content { 16 namespace content {
17 17
18 constexpr uint32_t URLResponseBodyConsumer::kMaxNumConsumedBytesInTask;
19
18 class URLResponseBodyConsumer::ReceivedData final 20 class URLResponseBodyConsumer::ReceivedData final
19 : public RequestPeer::ReceivedData { 21 : public RequestPeer::ReceivedData {
20 public: 22 public:
21 ReceivedData(const char* payload, 23 ReceivedData(const char* payload,
22 int length, 24 int length,
23 scoped_refptr<URLResponseBodyConsumer> consumer) 25 scoped_refptr<URLResponseBodyConsumer> consumer)
24 : payload_(payload), length_(length), consumer_(consumer) {} 26 : payload_(payload), length_(length), consumer_(consumer) {}
25 27
26 ~ReceivedData() override { consumer_->Reclaim(length_); } 28 ~ReceivedData() override { consumer_->Reclaim(length_); }
27 29
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 task_runner_->PostTask( 93 task_runner_->PostTask(
92 FROM_HERE, base::Bind(&URLResponseBodyConsumer::OnReadable, AsWeakPtr(), 94 FROM_HERE, base::Bind(&URLResponseBodyConsumer::OnReadable, AsWeakPtr(),
93 MOJO_RESULT_OK)); 95 MOJO_RESULT_OK));
94 } 96 }
95 97
96 void URLResponseBodyConsumer::OnReadable(MojoResult unused) { 98 void URLResponseBodyConsumer::OnReadable(MojoResult unused) {
97 if (has_been_cancelled_ || has_seen_end_of_data_ || is_deferred_) 99 if (has_been_cancelled_ || has_seen_end_of_data_ || is_deferred_)
98 return; 100 return;
99 101
100 DCHECK(!is_in_on_readable_); 102 DCHECK(!is_in_on_readable_);
103 uint32_t num_bytes_consumed = 0;
101 104
102 // Protect |this| as RequestPeer::OnReceivedData may call deref. 105 // Protect |this| as RequestPeer::OnReceivedData may call deref.
103 scoped_refptr<URLResponseBodyConsumer> protect(this); 106 scoped_refptr<URLResponseBodyConsumer> protect(this);
104 base::AutoReset<bool> is_in_on_readable(&is_in_on_readable_, true); 107 base::AutoReset<bool> is_in_on_readable(&is_in_on_readable_, true);
105 108
106 while (!has_been_cancelled_ && !is_deferred_) { 109 while (!has_been_cancelled_ && !is_deferred_) {
107 const void* buffer = nullptr; 110 const void* buffer = nullptr;
108 uint32_t available = 0; 111 uint32_t available = 0;
109 MojoResult result = mojo::BeginReadDataRaw( 112 MojoResult result = mojo::BeginReadDataRaw(
110 handle_.get(), &buffer, &available, MOJO_READ_DATA_FLAG_NONE); 113 handle_.get(), &buffer, &available, MOJO_READ_DATA_FLAG_NONE);
111 if (result == MOJO_RESULT_SHOULD_WAIT || result == MOJO_RESULT_BUSY) 114 if (result == MOJO_RESULT_SHOULD_WAIT || result == MOJO_RESULT_BUSY)
112 return; 115 return;
113 if (result == MOJO_RESULT_FAILED_PRECONDITION) { 116 if (result == MOJO_RESULT_FAILED_PRECONDITION) {
114 has_seen_end_of_data_ = true; 117 has_seen_end_of_data_ = true;
115 NotifyCompletionIfAppropriate(); 118 NotifyCompletionIfAppropriate();
116 return; 119 return;
117 } 120 }
118 if (result != MOJO_RESULT_OK) { 121 if (result != MOJO_RESULT_OK) {
119 completion_status_.error_code = net::ERR_FAILED; 122 completion_status_.error_code = net::ERR_FAILED;
120 has_seen_end_of_data_ = true; 123 has_seen_end_of_data_ = true;
121 has_received_completion_ = true; 124 has_received_completion_ = true;
122 NotifyCompletionIfAppropriate(); 125 NotifyCompletionIfAppropriate();
123 return; 126 return;
124 } 127 }
128 DCHECK_LE(num_bytes_consumed, kMaxNumConsumedBytesInTask);
129 available =
130 std::min(available, kMaxNumConsumedBytesInTask - num_bytes_consumed);
131 if (available == 0) {
132 // We've already consumed many bytes in this task. Defer the remaining
133 // to the next task.
134 result = mojo::EndReadDataRaw(handle_.get(), 0);
135 DCHECK_EQ(result, MOJO_RESULT_OK);
136 task_runner_->PostTask(FROM_HERE,
137 base::Bind(&URLResponseBodyConsumer::OnReadable,
138 AsWeakPtr(), MOJO_RESULT_OK));
139 return;
140 }
141 num_bytes_consumed += available;
125 ResourceDispatcher::PendingRequestInfo* request_info = 142 ResourceDispatcher::PendingRequestInfo* request_info =
126 resource_dispatcher_->GetPendingRequestInfo(request_id_); 143 resource_dispatcher_->GetPendingRequestInfo(request_id_);
127 DCHECK(request_info); 144 DCHECK(request_info);
128 request_info->peer->OnReceivedData(base::MakeUnique<ReceivedData>( 145 request_info->peer->OnReceivedData(base::MakeUnique<ReceivedData>(
129 static_cast<const char*>(buffer), available, this)); 146 static_cast<const char*>(buffer), available, this));
130 } 147 }
131 } 148 }
132 149
133 void URLResponseBodyConsumer::NotifyCompletionIfAppropriate() { 150 void URLResponseBodyConsumer::NotifyCompletionIfAppropriate() {
134 if (has_been_cancelled_) 151 if (has_been_cancelled_)
135 return; 152 return;
136 if (!has_received_completion_ || !has_seen_end_of_data_) 153 if (!has_received_completion_ || !has_seen_end_of_data_)
137 return; 154 return;
138 // Cancel this instance in order not to notify twice. 155 // Cancel this instance in order not to notify twice.
139 Cancel(); 156 Cancel();
140 157
141 resource_dispatcher_->DispatchMessage( 158 resource_dispatcher_->DispatchMessage(
142 ResourceMsg_RequestComplete(request_id_, completion_status_)); 159 ResourceMsg_RequestComplete(request_id_, completion_status_));
143 // |this| may be deleted. 160 // |this| may be deleted.
144 } 161 }
145 162
146 } // namespace content 163 } // namespace content
OLDNEW
« no previous file with comments | « content/child/url_response_body_consumer.h ('k') | content/child/url_response_body_consumer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698