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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 public: | 184 public: |
185 DependentIOBuffer(ResourceBuffer* backing, char* memory) | 185 DependentIOBuffer(ResourceBuffer* backing, char* memory) |
186 : net::WrappedIOBuffer(memory), | 186 : net::WrappedIOBuffer(memory), |
187 backing_(backing) { | 187 backing_(backing) { |
188 } | 188 } |
189 private: | 189 private: |
190 ~DependentIOBuffer() override {} | 190 ~DependentIOBuffer() override {} |
191 scoped_refptr<ResourceBuffer> backing_; | 191 scoped_refptr<ResourceBuffer> backing_; |
192 }; | 192 }; |
193 | 193 |
194 AsyncResourceHandler::AsyncResourceHandler( | 194 class AsyncResourceHandler::MojoHelper final { |
195 net::URLRequest* request, | 195 public: |
196 ResourceDispatcherHostImpl* rdh) | 196 explicit MojoHelper(AsyncResourceHandler* owner) : owner_(owner) {} |
| 197 |
| 198 void OnResponseStarted() { |
| 199 MojoCreateDataPipeOptions options; |
| 200 options.struct_size = sizeof(MojoCreateDataPipeOptions); |
| 201 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; |
| 202 options.element_num_bytes = 1; |
| 203 options.capacity_num_bytes = kMaxAllocationSize; |
| 204 mojo::DataPipe data_pipe(options); |
| 205 |
| 206 writer_ = std::move(data_pipe.producer_handle); |
| 207 owner_->GetRequestInfo()->InstallBodyReader( |
| 208 std::move(data_pipe.consumer_handle)); |
| 209 } |
| 210 |
| 211 bool OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| 212 int* buf_size, |
| 213 int min_size) { |
| 214 void* buffer = nullptr; |
| 215 uint32_t available = 0; |
| 216 MojoResult result = mojo::BeginWriteDataRaw( |
| 217 writer_.get(), &buffer, &available, MOJO_WRITE_DATA_FLAG_NONE); |
| 218 // Note that we cannot handle SHOULD_WAIT here. It should be handled in |
| 219 // OnReadCompleted. |
| 220 if (result == MOJO_RESULT_OK) { |
| 221 *buf = new net::WrappedIOBuffer(static_cast<const char*>(buffer)); |
| 222 *buf_size = available; |
| 223 return true; |
| 224 } |
| 225 return false; |
| 226 } |
| 227 |
| 228 bool OnReadCompleted(int bytes_read, bool* defer) { |
| 229 MojoResult result = mojo::EndWriteDataRaw(writer_.get(), bytes_read); |
| 230 if (result != MOJO_RESULT_OK) |
| 231 return false; |
| 232 void* buffer = nullptr; |
| 233 uint32_t available = 0; |
| 234 // To see if we can continue writing. |
| 235 result = mojo::BeginWriteDataRaw(writer_.get(), &buffer, &available, |
| 236 MOJO_WRITE_DATA_FLAG_NONE); |
| 237 if (result == MOJO_RESULT_SHOULD_WAIT || |
| 238 (result == MOJO_RESULT_OK && available == 0)) { |
| 239 *defer = owner_->did_defer_ = true; |
| 240 owner_->OnDefer(); |
| 241 handle_watcher_.Start( |
| 242 writer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, |
| 243 base::Bind(&MojoHelper::OnWritable, base::Unretained(this))); |
| 244 } |
| 245 if (result == MOJO_RESULT_OK) |
| 246 mojo::EndWriteDataRaw(writer_.get(), 0); |
| 247 return true; |
| 248 } |
| 249 |
| 250 private: |
| 251 void OnWritable(MojoResult result) { owner_->ResumeIfDeferred(); } |
| 252 |
| 253 mojo::ScopedDataPipeProducerHandle writer_; |
| 254 mojo::common::HandleWatcher handle_watcher_; |
| 255 AsyncResourceHandler* owner_; |
| 256 |
| 257 DISALLOW_COPY_AND_ASSIGN(MojoHelper); |
| 258 }; |
| 259 |
| 260 AsyncResourceHandler::AsyncResourceHandler(net::URLRequest* request, |
| 261 ResourceDispatcherHostImpl* rdh, |
| 262 bool using_mojo_data_handle) |
197 : ResourceHandler(request), | 263 : ResourceHandler(request), |
198 ResourceMessageDelegate(request), | 264 ResourceMessageDelegate(request), |
199 rdh_(rdh), | 265 rdh_(rdh), |
200 pending_data_count_(0), | 266 pending_data_count_(0), |
201 allocation_size_(0), | 267 allocation_size_(0), |
202 did_defer_(false), | 268 did_defer_(false), |
203 has_checked_for_sufficient_resources_(false), | 269 has_checked_for_sufficient_resources_(false), |
204 sent_received_response_msg_(false), | 270 sent_received_response_msg_(false), |
205 sent_data_buffer_msg_(false), | 271 sent_data_buffer_msg_(false), |
206 inlining_helper_(new InliningHelper), | 272 inlining_helper_(new InliningHelper), |
207 last_upload_position_(0), | 273 last_upload_position_(0), |
208 waiting_for_upload_progress_ack_(false), | 274 waiting_for_upload_progress_ack_(false), |
209 reported_transfer_size_(0) { | 275 reported_transfer_size_(0), |
| 276 mojo_helper_(using_mojo_data_handle ? new MojoHelper(this) : nullptr) { |
210 InitializeResourceBufferConstants(); | 277 InitializeResourceBufferConstants(); |
211 } | 278 } |
212 | 279 |
213 AsyncResourceHandler::~AsyncResourceHandler() { | 280 AsyncResourceHandler::~AsyncResourceHandler() { |
214 if (has_checked_for_sufficient_resources_) | 281 if (has_checked_for_sufficient_resources_) |
215 rdh_->FinishedWithResourcesForRequest(request()); | 282 rdh_->FinishedWithResourcesForRequest(request()); |
216 } | 283 } |
217 | 284 |
218 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { | 285 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { |
219 bool handled = true; | 286 bool handled = true; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 // If the parent handler downloaded the resource to a file, grant the child | 415 // If the parent handler downloaded the resource to a file, grant the child |
349 // read permissions on it. | 416 // read permissions on it. |
350 if (!response->head.download_file_path.empty()) { | 417 if (!response->head.download_file_path.empty()) { |
351 rdh_->RegisterDownloadedTempFile( | 418 rdh_->RegisterDownloadedTempFile( |
352 info->GetChildID(), info->GetRequestID(), | 419 info->GetChildID(), info->GetRequestID(), |
353 response->head.download_file_path); | 420 response->head.download_file_path); |
354 } | 421 } |
355 | 422 |
356 response->head.request_start = request()->creation_time(); | 423 response->head.request_start = request()->creation_time(); |
357 response->head.response_start = TimeTicks::Now(); | 424 response->head.response_start = TimeTicks::Now(); |
| 425 if (mojo_helper_) |
| 426 mojo_helper_->OnResponseStarted(); |
| 427 |
358 info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), | 428 info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), |
359 response->head)); | 429 response->head)); |
360 sent_received_response_msg_ = true; | 430 sent_received_response_msg_ = true; |
361 | 431 |
362 if (request()->response_info().metadata.get()) { | 432 if (request()->response_info().metadata.get()) { |
363 std::vector<char> copy(request()->response_info().metadata->data(), | 433 std::vector<char> copy(request()->response_info().metadata->data(), |
364 request()->response_info().metadata->data() + | 434 request()->response_info().metadata->data() + |
365 request()->response_info().metadata->size()); | 435 request()->response_info().metadata->size()); |
366 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 436 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), |
367 copy)); | 437 copy)); |
(...skipping 21 matching lines...) Expand all Loading... |
389 } | 459 } |
390 | 460 |
391 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 461 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
392 int* buf_size, | 462 int* buf_size, |
393 int min_size) { | 463 int min_size) { |
394 DCHECK_EQ(-1, min_size); | 464 DCHECK_EQ(-1, min_size); |
395 | 465 |
396 if (!CheckForSufficientResource()) | 466 if (!CheckForSufficientResource()) |
397 return false; | 467 return false; |
398 | 468 |
| 469 if (mojo_helper_) |
| 470 return mojo_helper_->OnWillRead(buf, buf_size, min_size); |
| 471 |
399 // Return early if InliningHelper allocates the buffer, so that we should | 472 // Return early if InliningHelper allocates the buffer, so that we should |
400 // inline the data into the IPC message without allocating SharedMemory. | 473 // inline the data into the IPC message without allocating SharedMemory. |
401 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) | 474 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) |
402 return true; | 475 return true; |
403 | 476 |
404 if (!EnsureResourceBufferIsInitialized()) | 477 if (!EnsureResourceBufferIsInitialized()) |
405 return false; | 478 return false; |
406 | 479 |
407 DCHECK(buffer_->CanAllocate()); | 480 DCHECK(buffer_->CanAllocate()); |
408 char* memory = buffer_->Allocate(&allocation_size_); | 481 char* memory = buffer_->Allocate(&allocation_size_); |
409 CHECK(memory); | 482 CHECK(memory); |
410 | 483 |
411 *buf = new DependentIOBuffer(buffer_.get(), memory); | 484 *buf = new DependentIOBuffer(buffer_.get(), memory); |
412 *buf_size = allocation_size_; | 485 *buf_size = allocation_size_; |
413 | 486 |
414 return true; | 487 return true; |
415 } | 488 } |
416 | 489 |
417 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 490 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
418 DCHECK_GE(bytes_read, 0); | 491 DCHECK_GE(bytes_read, 0); |
419 | 492 |
420 if (!bytes_read) | 493 if (!bytes_read) |
421 return true; | 494 return true; |
422 | 495 |
| 496 if (mojo_helper_) |
| 497 return mojo_helper_->OnReadCompleted(bytes_read, defer); |
| 498 |
423 ResourceMessageFilter* filter = GetFilter(); | 499 ResourceMessageFilter* filter = GetFilter(); |
424 if (!filter) | 500 if (!filter) |
425 return false; | 501 return false; |
426 | 502 |
427 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 503 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
428 | 504 |
429 // Return early if InliningHelper handled the received data. | 505 // Return early if InliningHelper handled the received data. |
430 if (inlining_helper_->SendInlinedDataIfApplicable( | 506 if (inlining_helper_->SendInlinedDataIfApplicable( |
431 bytes_read, encoded_data_length, filter, GetRequestID())) | 507 bytes_read, encoded_data_length, filter, GetRequestID())) |
432 return true; | 508 return true; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 } else { | 663 } else { |
588 UMA_HISTOGRAM_CUSTOM_COUNTS( | 664 UMA_HISTOGRAM_CUSTOM_COUNTS( |
589 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", | 665 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", |
590 elapsed_time, 1, 100000, 100); | 666 elapsed_time, 1, 100000, 100); |
591 } | 667 } |
592 | 668 |
593 inlining_helper_->RecordHistogram(elapsed_time); | 669 inlining_helper_->RecordHistogram(elapsed_time); |
594 } | 670 } |
595 | 671 |
596 } // namespace content | 672 } // namespace content |
OLD | NEW |