OLD | NEW |
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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 public: | 183 public: |
184 DependentIOBuffer(ResourceBuffer* backing, char* memory) | 184 DependentIOBuffer(ResourceBuffer* backing, char* memory) |
185 : net::WrappedIOBuffer(memory), | 185 : net::WrappedIOBuffer(memory), |
186 backing_(backing) { | 186 backing_(backing) { |
187 } | 187 } |
188 private: | 188 private: |
189 ~DependentIOBuffer() override {} | 189 ~DependentIOBuffer() override {} |
190 scoped_refptr<ResourceBuffer> backing_; | 190 scoped_refptr<ResourceBuffer> backing_; |
191 }; | 191 }; |
192 | 192 |
193 AsyncResourceHandler::AsyncResourceHandler( | 193 AsyncResourceHandler::AsyncResourceHandler(net::URLRequest* request, |
194 net::URLRequest* request, | 194 ResourceDispatcherHostImpl* rdh, |
195 ResourceDispatcherHostImpl* rdh) | 195 bool using_mojo_data_handle) |
196 : ResourceHandler(request), | 196 : ResourceHandler(request), |
197 ResourceMessageDelegate(request), | 197 ResourceMessageDelegate(request), |
198 rdh_(rdh), | 198 rdh_(rdh), |
199 pending_data_count_(0), | 199 pending_data_count_(0), |
200 allocation_size_(0), | 200 allocation_size_(0), |
201 did_defer_(false), | 201 did_defer_(false), |
202 has_checked_for_sufficient_resources_(false), | 202 has_checked_for_sufficient_resources_(false), |
203 sent_received_response_msg_(false), | 203 sent_received_response_msg_(false), |
204 sent_data_buffer_msg_(false), | 204 sent_data_buffer_msg_(false), |
| 205 using_mojo_data_handle_(using_mojo_data_handle), |
205 inlining_helper_(new InliningHelper), | 206 inlining_helper_(new InliningHelper), |
206 last_upload_position_(0), | 207 last_upload_position_(0), |
207 waiting_for_upload_progress_ack_(false), | 208 waiting_for_upload_progress_ack_(false), |
208 reported_transfer_size_(0) { | 209 reported_transfer_size_(0) { |
209 InitializeResourceBufferConstants(); | 210 InitializeResourceBufferConstants(); |
210 } | 211 } |
211 | 212 |
212 AsyncResourceHandler::~AsyncResourceHandler() { | 213 AsyncResourceHandler::~AsyncResourceHandler() { |
213 if (has_checked_for_sufficient_resources_) | 214 if (has_checked_for_sufficient_resources_) |
214 rdh_->FinishedWithResourcesForRequest(request()); | 215 rdh_->FinishedWithResourcesForRequest(request()); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 // If the parent handler downloaded the resource to a file, grant the child | 363 // If the parent handler downloaded the resource to a file, grant the child |
363 // read permissions on it. | 364 // read permissions on it. |
364 if (!response->head.download_file_path.empty()) { | 365 if (!response->head.download_file_path.empty()) { |
365 rdh_->RegisterDownloadedTempFile( | 366 rdh_->RegisterDownloadedTempFile( |
366 info->GetChildID(), info->GetRequestID(), | 367 info->GetChildID(), info->GetRequestID(), |
367 response->head.download_file_path); | 368 response->head.download_file_path); |
368 } | 369 } |
369 | 370 |
370 response->head.request_start = request()->creation_time(); | 371 response->head.request_start = request()->creation_time(); |
371 response->head.response_start = TimeTicks::Now(); | 372 response->head.response_start = TimeTicks::Now(); |
| 373 if (using_mojo_data_handle_) { |
| 374 MojoCreateDataPipeOptions options; |
| 375 options.struct_size = sizeof(MojoCreateDataPipeOptions); |
| 376 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; |
| 377 options.element_num_bytes = 1; |
| 378 options.capacity_num_bytes = kMaxAllocationSize; |
| 379 mojo::DataPipe data_pipe(options); |
| 380 mojo::ScopedDataPipeConsumerHandle handle; |
| 381 |
| 382 writer_ = std::move(data_pipe.producer_handle); |
| 383 GetRequestInfo()->InstallBodyReader(std::move(data_pipe.consumer_handle)); |
| 384 } |
| 385 |
372 info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), | 386 info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), |
373 response->head)); | 387 response->head)); |
374 sent_received_response_msg_ = true; | 388 sent_received_response_msg_ = true; |
375 | 389 |
376 if (request()->response_info().metadata.get()) { | 390 if (request()->response_info().metadata.get()) { |
377 std::vector<char> copy(request()->response_info().metadata->data(), | 391 std::vector<char> copy(request()->response_info().metadata->data(), |
378 request()->response_info().metadata->data() + | 392 request()->response_info().metadata->data() + |
379 request()->response_info().metadata->size()); | 393 request()->response_info().metadata->size()); |
380 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 394 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), |
381 copy)); | 395 copy)); |
(...skipping 21 matching lines...) Expand all Loading... |
403 } | 417 } |
404 | 418 |
405 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 419 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
406 int* buf_size, | 420 int* buf_size, |
407 int min_size) { | 421 int min_size) { |
408 DCHECK_EQ(-1, min_size); | 422 DCHECK_EQ(-1, min_size); |
409 | 423 |
410 if (!CheckForSufficientResource()) | 424 if (!CheckForSufficientResource()) |
411 return false; | 425 return false; |
412 | 426 |
| 427 if (using_mojo_data_handle_) { |
| 428 void* buffer = nullptr; |
| 429 uint32_t available = 0; |
| 430 MojoResult result = mojo::BeginWriteDataRaw( |
| 431 writer_.get(), &buffer, &available, MOJO_WRITE_DATA_FLAG_NONE); |
| 432 // Note that we cannot handle SHOULD_WAIT here. It should be handled in |
| 433 // OnReadCompleted. |
| 434 if (result == MOJO_RESULT_OK) { |
| 435 *buf = new net::WrappedIOBuffer(static_cast<const char*>(buffer)); |
| 436 *buf_size = available; |
| 437 return true; |
| 438 } |
| 439 return false; |
| 440 } |
413 // Return early if InliningHelper allocates the buffer, so that we should | 441 // Return early if InliningHelper allocates the buffer, so that we should |
414 // inline the data into the IPC message without allocating SharedMemory. | 442 // inline the data into the IPC message without allocating SharedMemory. |
415 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) | 443 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) |
416 return true; | 444 return true; |
417 | 445 |
418 if (!EnsureResourceBufferIsInitialized()) | 446 if (!EnsureResourceBufferIsInitialized()) |
419 return false; | 447 return false; |
420 | 448 |
421 DCHECK(buffer_->CanAllocate()); | 449 DCHECK(buffer_->CanAllocate()); |
422 char* memory = buffer_->Allocate(&allocation_size_); | 450 char* memory = buffer_->Allocate(&allocation_size_); |
423 CHECK(memory); | 451 CHECK(memory); |
424 | 452 |
425 *buf = new DependentIOBuffer(buffer_.get(), memory); | 453 *buf = new DependentIOBuffer(buffer_.get(), memory); |
426 *buf_size = allocation_size_; | 454 *buf_size = allocation_size_; |
427 | 455 |
428 return true; | 456 return true; |
429 } | 457 } |
430 | 458 |
431 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 459 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
432 DCHECK_GE(bytes_read, 0); | 460 DCHECK_GE(bytes_read, 0); |
433 | 461 |
434 if (!bytes_read) | 462 if (!bytes_read) |
435 return true; | 463 return true; |
436 | 464 |
| 465 if (using_mojo_data_handle_) { |
| 466 MojoResult result = mojo::EndWriteDataRaw(writer_.get(), bytes_read); |
| 467 if (result != MOJO_RESULT_OK) |
| 468 return false; |
| 469 void* buffer = nullptr; |
| 470 uint32_t available = 0; |
| 471 // To see if we can continue writing. |
| 472 result = mojo::BeginWriteDataRaw(writer_.get(), &buffer, &available, |
| 473 MOJO_WRITE_DATA_FLAG_NONE); |
| 474 if (result == MOJO_RESULT_SHOULD_WAIT || |
| 475 (result == MOJO_RESULT_OK && available == 0)) { |
| 476 *defer = did_defer_ = true; |
| 477 OnDefer(); |
| 478 handle_watcher_.Start(writer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, |
| 479 MOJO_DEADLINE_INDEFINITE, |
| 480 base::Bind(&AsyncResourceHandler::OnWritable, |
| 481 base::Unretained(this))); |
| 482 } |
| 483 if (result == MOJO_RESULT_OK) |
| 484 mojo::EndWriteDataRaw(writer_.get(), 0); |
| 485 return true; |
| 486 } |
| 487 |
437 ResourceMessageFilter* filter = GetFilter(); | 488 ResourceMessageFilter* filter = GetFilter(); |
438 if (!filter) | 489 if (!filter) |
439 return false; | 490 return false; |
440 | 491 |
441 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 492 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
442 | 493 |
443 // Return early if InliningHelper handled the received data. | 494 // Return early if InliningHelper handled the received data. |
444 if (inlining_helper_->SendInlinedDataIfApplicable( | 495 if (inlining_helper_->SendInlinedDataIfApplicable( |
445 bytes_read, encoded_data_length, filter, GetRequestID())) | 496 bytes_read, encoded_data_length, filter, GetRequestID())) |
446 return true; | 497 return true; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 elapsed_time, 1, 100000, 100); | 651 elapsed_time, 1, 100000, 100); |
601 } else { | 652 } else { |
602 UMA_HISTOGRAM_CUSTOM_COUNTS( | 653 UMA_HISTOGRAM_CUSTOM_COUNTS( |
603 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", | 654 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", |
604 elapsed_time, 1, 100000, 100); | 655 elapsed_time, 1, 100000, 100); |
605 } | 656 } |
606 | 657 |
607 inlining_helper_->RecordHistogram(elapsed_time); | 658 inlining_helper_->RecordHistogram(elapsed_time); |
608 } | 659 } |
609 | 660 |
| 661 void AsyncResourceHandler::OnWritable(MojoResult result) { |
| 662 ResumeIfDeferred(); |
| 663 } |
| 664 |
610 } // namespace content | 665 } // namespace content |
OLD | NEW |