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

Side by Side Diff: content/browser/loader/async_resource_handler.cc

Issue 1970693002: Use mojo for Chrome Loading, Part 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser/loader/async_resource_handler.h" 5 #include "content/browser/loader/async_resource_handler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 11 matching lines...) Expand all
22 #include "content/browser/loader/resource_dispatcher_host_impl.h" 22 #include "content/browser/loader/resource_dispatcher_host_impl.h"
23 #include "content/browser/loader/resource_message_filter.h" 23 #include "content/browser/loader/resource_message_filter.h"
24 #include "content/browser/loader/resource_request_info_impl.h" 24 #include "content/browser/loader/resource_request_info_impl.h"
25 #include "content/browser/resource_context_impl.h" 25 #include "content/browser/resource_context_impl.h"
26 #include "content/common/resource_messages.h" 26 #include "content/common/resource_messages.h"
27 #include "content/common/resource_request_completion_status.h" 27 #include "content/common/resource_request_completion_status.h"
28 #include "content/common/view_messages.h" 28 #include "content/common/view_messages.h"
29 #include "content/public/browser/resource_dispatcher_host_delegate.h" 29 #include "content/public/browser/resource_dispatcher_host_delegate.h"
30 #include "content/public/common/content_features.h" 30 #include "content/public/common/content_features.h"
31 #include "content/public/common/resource_response.h" 31 #include "content/public/common/resource_response.h"
32 #include "mojo/message_pump/handle_watcher.h"
33 #include "mojo/public/cpp/system/data_pipe.h"
32 #include "net/base/io_buffer.h" 34 #include "net/base/io_buffer.h"
33 #include "net/base/load_flags.h" 35 #include "net/base/load_flags.h"
34 #include "net/log/net_log.h" 36 #include "net/log/net_log.h"
35 #include "net/url_request/redirect_info.h" 37 #include "net/url_request/redirect_info.h"
36 38
37 using base::TimeDelta; 39 using base::TimeDelta;
38 using base::TimeTicks; 40 using base::TimeTicks;
39 41
40 namespace content { 42 namespace content {
41 namespace { 43 namespace {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 public: 186 public:
185 DependentIOBuffer(ResourceBuffer* backing, char* memory) 187 DependentIOBuffer(ResourceBuffer* backing, char* memory)
186 : net::WrappedIOBuffer(memory), 188 : net::WrappedIOBuffer(memory),
187 backing_(backing) { 189 backing_(backing) {
188 } 190 }
189 private: 191 private:
190 ~DependentIOBuffer() override {} 192 ~DependentIOBuffer() override {}
191 scoped_refptr<ResourceBuffer> backing_; 193 scoped_refptr<ResourceBuffer> backing_;
192 }; 194 };
193 195
194 AsyncResourceHandler::AsyncResourceHandler( 196 // This class is used when the resource is being loaded via mojo. This class
195 net::URLRequest* request, 197 // uses mojo data pipe instead of shared memory transferred via ChromeIPC.
196 ResourceDispatcherHostImpl* rdh) 198 class AsyncResourceHandler::MojoHelper final {
mmenke 2016/05/24 20:01:35 Long term, is the plan to merge this into AsyncRes
yhirano 2016/05/25 12:47:05 Yes, our plan is replacing ChromeIPC with mojo.
199 public:
200 explicit MojoHelper(AsyncResourceHandler* owner) : owner_(owner) {}
201 // Called from AsyncResourceHandler::OnWillRead.
202 bool OnWillRead(scoped_refptr<net::IOBuffer>* buf,
203 int* buf_size,
204 int min_size) {
205 void* buffer = nullptr;
206 uint32_t available = 0;
207 if (!writer_.is_valid()) {
208 MojoCreateDataPipeOptions options;
209 options.struct_size = sizeof(MojoCreateDataPipeOptions);
210 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
211 options.element_num_bytes = 1;
212 options.capacity_num_bytes = kMaxAllocationSize;
213 mojo::DataPipe data_pipe(options);
214
215 writer_ = std::move(data_pipe.producer_handle);
216 ResourceMessageFilter* filter = owner_->GetRequestInfo()->filter();
217 if (filter) {
218 filter->OnStartLoadingResponseBodyWithMojo(
219 owner_->GetRequestInfo()->GetGlobalRequestID(),
220 std::move(data_pipe.consumer_handle));
221 }
222 }
223 if (!writer_.is_valid()) {
224 owner_->controller()->CancelWithError(net::ERR_FAILED);
225 return false;
226 }
227
228 MojoResult result = mojo::BeginWriteDataRaw(
229 writer_.get(), &buffer, &available, MOJO_WRITE_DATA_FLAG_NONE);
230 // Note that SHOULD_WAIT should be handled in OnReadCompleted.
231 if (result == MOJO_RESULT_OK) {
232 *buf = new net::WrappedIOBuffer(static_cast<const char*>(buffer));
233 *buf_size = available;
234 return true;
235 }
236 return false;
mmenke 2016/05/24 20:01:35 This case is currently a fatal error?
yhirano 2016/05/25 12:47:05 Done.
237 }
238
239 // Called from AsyncResourceHandler::OnReadCompleted.
240 bool OnReadCompleted(int bytes_read, bool* defer) {
241 MojoResult result = mojo::EndWriteDataRaw(writer_.get(), bytes_read);
242 if (result != MOJO_RESULT_OK)
243 return false;
244 void* buffer = nullptr;
245 uint32_t available = 0;
246 // To see if the handle is still writable.
247 result = mojo::BeginWriteDataRaw(writer_.get(), &buffer, &available,
248 MOJO_WRITE_DATA_FLAG_NONE);
249 if (result == MOJO_RESULT_SHOULD_WAIT ||
250 (result == MOJO_RESULT_OK && available == 0)) {
251 *defer = owner_->did_defer_ = true;
252 owner_->OnDefer();
253 handle_watcher_.Start(
254 writer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE,
255 base::Bind(&MojoHelper::OnWritable, base::Unretained(this)));
256 }
257 if (result == MOJO_RESULT_OK)
258 mojo::EndWriteDataRaw(writer_.get(), 0);
259 return true;
260 }
261
262 private:
263 void OnWritable(MojoResult result) { owner_->ResumeIfDeferred(); }
264
265 mojo::ScopedDataPipeProducerHandle writer_;
266 mojo::common::HandleWatcher handle_watcher_;
267 AsyncResourceHandler* owner_;
268
269 DISALLOW_COPY_AND_ASSIGN(MojoHelper);
270 };
271
272 AsyncResourceHandler::AsyncResourceHandler(net::URLRequest* request,
273 ResourceDispatcherHostImpl* rdh,
274 bool using_mojo_data_handle)
197 : ResourceHandler(request), 275 : ResourceHandler(request),
198 ResourceMessageDelegate(request), 276 ResourceMessageDelegate(request),
199 rdh_(rdh), 277 rdh_(rdh),
200 pending_data_count_(0), 278 pending_data_count_(0),
201 allocation_size_(0), 279 allocation_size_(0),
202 did_defer_(false), 280 did_defer_(false),
203 has_checked_for_sufficient_resources_(false), 281 has_checked_for_sufficient_resources_(false),
204 sent_received_response_msg_(false), 282 sent_received_response_msg_(false),
205 sent_data_buffer_msg_(false), 283 sent_data_buffer_msg_(false),
206 inlining_helper_(new InliningHelper), 284 inlining_helper_(new InliningHelper),
207 last_upload_position_(0), 285 last_upload_position_(0),
208 waiting_for_upload_progress_ack_(false), 286 waiting_for_upload_progress_ack_(false),
209 reported_transfer_size_(0) { 287 reported_transfer_size_(0),
288 mojo_helper_(using_mojo_data_handle ? new MojoHelper(this) : nullptr) {
210 InitializeResourceBufferConstants(); 289 InitializeResourceBufferConstants();
211 } 290 }
212 291
213 AsyncResourceHandler::~AsyncResourceHandler() { 292 AsyncResourceHandler::~AsyncResourceHandler() {
214 if (has_checked_for_sufficient_resources_) 293 if (has_checked_for_sufficient_resources_)
215 rdh_->FinishedWithResourcesForRequest(request()); 294 rdh_->FinishedWithResourcesForRequest(request());
216 } 295 }
217 296
218 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { 297 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) {
219 bool handled = true; 298 bool handled = true;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 468 }
390 469
391 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, 470 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
392 int* buf_size, 471 int* buf_size,
393 int min_size) { 472 int min_size) {
394 DCHECK_EQ(-1, min_size); 473 DCHECK_EQ(-1, min_size);
395 474
396 if (!CheckForSufficientResource()) 475 if (!CheckForSufficientResource())
397 return false; 476 return false;
398 477
478 if (mojo_helper_)
479 return mojo_helper_->OnWillRead(buf, buf_size, min_size);
480
399 // Return early if InliningHelper allocates the buffer, so that we should 481 // Return early if InliningHelper allocates the buffer, so that we should
400 // inline the data into the IPC message without allocating SharedMemory. 482 // inline the data into the IPC message without allocating SharedMemory.
401 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) 483 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size))
402 return true; 484 return true;
403 485
404 if (!EnsureResourceBufferIsInitialized()) 486 if (!EnsureResourceBufferIsInitialized())
405 return false; 487 return false;
406 488
407 DCHECK(buffer_->CanAllocate()); 489 DCHECK(buffer_->CanAllocate());
408 char* memory = buffer_->Allocate(&allocation_size_); 490 char* memory = buffer_->Allocate(&allocation_size_);
409 CHECK(memory); 491 CHECK(memory);
410 492
411 *buf = new DependentIOBuffer(buffer_.get(), memory); 493 *buf = new DependentIOBuffer(buffer_.get(), memory);
412 *buf_size = allocation_size_; 494 *buf_size = allocation_size_;
413 495
414 return true; 496 return true;
415 } 497 }
416 498
417 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { 499 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
418 DCHECK_GE(bytes_read, 0); 500 DCHECK_GE(bytes_read, 0);
419 501
420 if (!bytes_read) 502 if (!bytes_read)
421 return true; 503 return true;
422 504
505 if (mojo_helper_)
506 return mojo_helper_->OnReadCompleted(bytes_read, defer);
507
423 ResourceMessageFilter* filter = GetFilter(); 508 ResourceMessageFilter* filter = GetFilter();
424 if (!filter) 509 if (!filter)
425 return false; 510 return false;
426 511
427 int encoded_data_length = CalculateEncodedDataLengthToReport(); 512 int encoded_data_length = CalculateEncodedDataLengthToReport();
428 513
429 // Return early if InliningHelper handled the received data. 514 // Return early if InliningHelper handled the received data.
430 if (inlining_helper_->SendInlinedDataIfApplicable( 515 if (inlining_helper_->SendInlinedDataIfApplicable(
431 bytes_read, encoded_data_length, filter, GetRequestID())) 516 bytes_read, encoded_data_length, filter, GetRequestID()))
432 return true; 517 return true;
(...skipping 28 matching lines...) Expand all
461 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { 546 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
462 int encoded_data_length = CalculateEncodedDataLengthToReport(); 547 int encoded_data_length = CalculateEncodedDataLengthToReport();
463 548
464 ResourceMessageFilter* filter = GetFilter(); 549 ResourceMessageFilter* filter = GetFilter();
465 if (filter) { 550 if (filter) {
466 filter->Send(new ResourceMsg_DataDownloaded( 551 filter->Send(new ResourceMsg_DataDownloaded(
467 GetRequestID(), bytes_downloaded, encoded_data_length)); 552 GetRequestID(), bytes_downloaded, encoded_data_length));
468 } 553 }
469 } 554 }
470 555
471 void AsyncResourceHandler::OnResponseCompleted( 556 void AsyncResourceHandler::OnResponseCompleted(
mmenke 2016/05/24 20:01:35 There's no mojo response completed successfully or
yhirano 2016/05/25 12:47:05 There is. In PS25, ResourceMessageFilter traps IPC
472 const net::URLRequestStatus& status, 557 const net::URLRequestStatus& status,
473 const std::string& security_info, 558 const std::string& security_info,
474 bool* defer) { 559 bool* defer) {
475 const ResourceRequestInfoImpl* info = GetRequestInfo(); 560 const ResourceRequestInfoImpl* info = GetRequestInfo();
476 if (!info->filter()) 561 if (!info->filter())
477 return; 562 return;
478 563
479 // If we crash here, figure out what URL the renderer was requesting. 564 // If we crash here, figure out what URL the renderer was requesting.
480 // http://crbug.com/107692 565 // http://crbug.com/107692
481 char url_buf[128]; 566 char url_buf[128];
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 } else { 672 } else {
588 UMA_HISTOGRAM_CUSTOM_COUNTS( 673 UMA_HISTOGRAM_CUSTOM_COUNTS(
589 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", 674 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB",
590 elapsed_time, 1, 100000, 100); 675 elapsed_time, 1, 100000, 100);
591 } 676 }
592 677
593 inlining_helper_->RecordHistogram(elapsed_time); 678 inlining_helper_->RecordHistogram(elapsed_time);
594 } 679 }
595 680
596 } // namespace content 681 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698