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

Side by Side Diff: content/common/resource_dispatcher.cc

Issue 7602023: Use a monotonic clock (TimeTicks) to report network times to WebCore. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync & Merge Created 9 years 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 | Annotate | Revision Log
« no previous file with comments | « content/common/resource_dispatcher.h ('k') | content/common/resource_dispatcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading
6 6
7 #include "content/common/resource_dispatcher.h" 7 #include "content/common/resource_dispatcher.h"
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/file_path.h" 12 #include "base/file_path.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/shared_memory.h" 14 #include "base/shared_memory.h"
15 #include "base/string_util.h" 15 #include "base/string_util.h"
16 #include "content/common/inter_process_time_ticks_converter.h"
16 #include "content/common/request_extra_data.h" 17 #include "content/common/request_extra_data.h"
17 #include "content/common/resource_messages.h" 18 #include "content/common/resource_messages.h"
18 #include "content/public/common/resource_dispatcher_delegate.h" 19 #include "content/public/common/resource_dispatcher_delegate.h"
19 #include "content/public/common/resource_response.h" 20 #include "content/public/common/resource_response.h"
20 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
21 #include "net/base/net_util.h" 22 #include "net/base/net_util.h"
22 #include "net/base/upload_data.h" 23 #include "net/base/upload_data.h"
23 #include "net/http/http_response_headers.h" 24 #include "net/http/http_response_headers.h"
24 #include "webkit/glue/resource_type.h" 25 #include "webkit/glue/resource_type.h"
25 26
27 using content::InterProcessTimeTicksConverter;
28 using content::LocalTimeDelta;
29 using content::LocalTimeTicks;
30 using content::RemoteTimeDelta;
31 using content::RemoteTimeTicks;
32
26 // Each resource request is assigned an ID scoped to this process. 33 // Each resource request is assigned an ID scoped to this process.
27 static int MakeRequestID() { 34 static int MakeRequestID() {
28 // NOTE: The resource_dispatcher_host also needs probably unique 35 // NOTE: The resource_dispatcher_host also needs probably unique
29 // request_ids, so they count down from -2 (-1 is a special we're 36 // request_ids, so they count down from -2 (-1 is a special we're
30 // screwed value), while the renderer process counts up. 37 // screwed value), while the renderer process counts up.
31 static int next_request_id = 0; 38 static int next_request_id = 0;
32 return next_request_id++; 39 return next_request_id++;
33 } 40 }
34 41
35 // ResourceLoaderBridge implementation ---------------------------------------- 42 // ResourceLoaderBridge implementation ----------------------------------------
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 // Acknowledge receipt 348 // Acknowledge receipt
342 message_sender()->Send( 349 message_sender()->Send(
343 new ResourceHostMsg_UploadProgress_ACK(message.routing_id(), request_id)); 350 new ResourceHostMsg_UploadProgress_ACK(message.routing_id(), request_id));
344 } 351 }
345 352
346 void ResourceDispatcher::OnReceivedResponse( 353 void ResourceDispatcher::OnReceivedResponse(
347 int request_id, const content::ResourceResponseHead& response_head) { 354 int request_id, const content::ResourceResponseHead& response_head) {
348 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 355 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
349 if (!request_info) 356 if (!request_info)
350 return; 357 return;
358 request_info->response_start = base::TimeTicks::Now();
351 359
352 if (delegate_) { 360 if (delegate_) {
353 webkit_glue::ResourceLoaderBridge::Peer* new_peer = 361 webkit_glue::ResourceLoaderBridge::Peer* new_peer =
354 delegate_->OnReceivedResponse( 362 delegate_->OnReceivedResponse(
355 request_info->peer, response_head.mime_type, request_info->url); 363 request_info->peer, response_head.mime_type, request_info->url);
356 if (new_peer) 364 if (new_peer)
357 request_info->peer = new_peer; 365 request_info->peer = new_peer;
358 } 366 }
359 367
360 request_info->peer->OnReceivedResponse(response_head); 368 webkit_glue::ResourceResponseInfo renderer_response_info;
369 ToResourceResponseInfo(*request_info, response_head, &renderer_response_info);
370 request_info->peer->OnReceivedResponse(renderer_response_info);
361 } 371 }
362 372
363 void ResourceDispatcher::OnReceivedCachedMetadata( 373 void ResourceDispatcher::OnReceivedCachedMetadata(
364 int request_id, const std::vector<char>& data) { 374 int request_id, const std::vector<char>& data) {
365 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 375 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
366 if (!request_info) 376 if (!request_info)
367 return; 377 return;
368 378
369 if (data.size()) 379 if (data.size())
370 request_info->peer->OnReceivedCachedMetadata(&data.front(), data.size()); 380 request_info->peer->OnReceivedCachedMetadata(&data.front(), data.size());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 if (!request_info) 414 if (!request_info)
405 return; 415 return;
406 416
407 request_info->peer->OnDownloadedData(data_len); 417 request_info->peer->OnDownloadedData(data_len);
408 } 418 }
409 419
410 void ResourceDispatcher::OnReceivedRedirect( 420 void ResourceDispatcher::OnReceivedRedirect(
411 const IPC::Message& message, 421 const IPC::Message& message,
412 int request_id, 422 int request_id,
413 const GURL& new_url, 423 const GURL& new_url,
414 const webkit_glue::ResourceResponseInfo& info) { 424 const content::ResourceResponseHead& response_head) {
415 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 425 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
416 if (!request_info) 426 if (!request_info)
417 return; 427 return;
428 request_info->response_start = base::TimeTicks::Now();
418 429
419 int32 routing_id = message.routing_id(); 430 int32 routing_id = message.routing_id();
420 bool has_new_first_party_for_cookies = false; 431 bool has_new_first_party_for_cookies = false;
421 GURL new_first_party_for_cookies; 432 GURL new_first_party_for_cookies;
422 if (request_info->peer->OnReceivedRedirect(new_url, info, 433 webkit_glue::ResourceResponseInfo renderer_response_info;
423 &has_new_first_party_for_cookies, 434 ToResourceResponseInfo(*request_info, response_head, &renderer_response_info);
424 &new_first_party_for_cookies)) { 435 if (request_info->peer->OnReceivedRedirect(new_url, renderer_response_info,
436 &has_new_first_party_for_cookies,
437 &new_first_party_for_cookies)) {
425 // Double-check if the request is still around. The call above could 438 // Double-check if the request is still around. The call above could
426 // potentially remove it. 439 // potentially remove it.
427 request_info = GetPendingRequestInfo(request_id); 440 request_info = GetPendingRequestInfo(request_id);
428 if (!request_info) 441 if (!request_info)
429 return; 442 return;
430 request_info->pending_redirect_message.reset( 443 request_info->pending_redirect_message.reset(
431 new ResourceHostMsg_FollowRedirect(routing_id, request_id, 444 new ResourceHostMsg_FollowRedirect(routing_id, request_id,
432 has_new_first_party_for_cookies, 445 has_new_first_party_for_cookies,
433 new_first_party_for_cookies)); 446 new_first_party_for_cookies));
434 if (!request_info->is_deferred) { 447 if (!request_info->is_deferred) {
435 FollowPendingRedirect(request_id, *request_info); 448 FollowPendingRedirect(request_id, *request_info);
436 } 449 }
437 } else { 450 } else {
438 CancelPendingRequest(routing_id, request_id); 451 CancelPendingRequest(routing_id, request_id);
439 } 452 }
440 } 453 }
441 454
442 void ResourceDispatcher::FollowPendingRedirect( 455 void ResourceDispatcher::FollowPendingRedirect(
443 int request_id, 456 int request_id,
444 PendingRequestInfo& request_info) { 457 PendingRequestInfo& request_info) {
445 IPC::Message* msg = request_info.pending_redirect_message.release(); 458 IPC::Message* msg = request_info.pending_redirect_message.release();
446 if (msg) 459 if (msg)
447 message_sender()->Send(msg); 460 message_sender()->Send(msg);
448 } 461 }
449 462
450 void ResourceDispatcher::OnRequestComplete(int request_id, 463 void ResourceDispatcher::OnRequestComplete(
451 const net::URLRequestStatus& status, 464 int request_id,
452 const std::string& security_info, 465 const net::URLRequestStatus& status,
453 const base::Time& completion_time) { 466 const std::string& security_info,
467 const base::TimeTicks& browser_completion_time) {
454 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 468 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
455 if (!request_info) 469 if (!request_info)
456 return; 470 return;
471 request_info->completion_time = base::TimeTicks::Now();
457 472
458 webkit_glue::ResourceLoaderBridge::Peer* peer = request_info->peer; 473 webkit_glue::ResourceLoaderBridge::Peer* peer = request_info->peer;
459 474
460 if (delegate_) { 475 if (delegate_) {
461 webkit_glue::ResourceLoaderBridge::Peer* new_peer = 476 webkit_glue::ResourceLoaderBridge::Peer* new_peer =
462 delegate_->OnRequestComplete( 477 delegate_->OnRequestComplete(
463 request_info->peer, request_info->resource_type, status); 478 request_info->peer, request_info->resource_type, status);
464 if (new_peer) 479 if (new_peer)
465 request_info->peer = new_peer; 480 request_info->peer = new_peer;
466 } 481 }
467 482
483 base::TimeTicks renderer_completion_time = ToRendererCompletionTime(
484 *request_info, browser_completion_time);
468 // The request ID will be removed from our pending list in the destructor. 485 // The request ID will be removed from our pending list in the destructor.
469 // Normally, dispatching this message causes the reference-counted request to 486 // Normally, dispatching this message causes the reference-counted request to
470 // die immediately. 487 // die immediately.
471 peer->OnCompletedRequest(status, security_info, completion_time); 488 peer->OnCompletedRequest(status, security_info, renderer_completion_time);
472 } 489 }
473 490
474 int ResourceDispatcher::AddPendingRequest( 491 int ResourceDispatcher::AddPendingRequest(
475 webkit_glue::ResourceLoaderBridge::Peer* callback, 492 webkit_glue::ResourceLoaderBridge::Peer* callback,
476 ResourceType::Type resource_type, 493 ResourceType::Type resource_type,
477 const GURL& request_url) { 494 const GURL& request_url) {
478 // Compute a unique request_id for this renderer process. 495 // Compute a unique request_id for this renderer process.
479 int id = MakeRequestID(); 496 int id = MakeRequestID();
480 pending_requests_[id] = 497 pending_requests_[id] =
481 PendingRequestInfo(callback, resource_type, request_url); 498 PendingRequestInfo(callback, resource_type, request_url);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 } 589 }
573 } 590 }
574 } 591 }
575 } 592 }
576 593
577 webkit_glue::ResourceLoaderBridge* ResourceDispatcher::CreateBridge( 594 webkit_glue::ResourceLoaderBridge* ResourceDispatcher::CreateBridge(
578 const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) { 595 const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) {
579 return new webkit_glue::IPCResourceLoaderBridge(this, request_info); 596 return new webkit_glue::IPCResourceLoaderBridge(this, request_info);
580 } 597 }
581 598
599 void ResourceDispatcher::ToResourceResponseInfo(
600 const PendingRequestInfo& request_info,
601 const content::ResourceResponseHead& browser_info,
602 webkit_glue::ResourceResponseInfo* renderer_info) const {
603 *renderer_info = browser_info;
604 if (request_info.request_start.is_null() ||
605 request_info.response_start.is_null() ||
606 browser_info.request_start.is_null() ||
607 browser_info.response_start.is_null()) {
608 return;
609 }
610 content::InterProcessTimeTicksConverter converter(
611 LocalTimeTicks::FromTimeTicks(request_info.request_start),
612 LocalTimeTicks::FromTimeTicks(request_info.response_start),
613 RemoteTimeTicks::FromTimeTicks(browser_info.request_start),
614 RemoteTimeTicks::FromTimeTicks(browser_info.response_start));
615
616 LocalTimeTicks renderer_base_ticks = converter.ToLocalTimeTicks(
617 RemoteTimeTicks::FromTimeTicks(browser_info.load_timing.base_ticks));
618 renderer_info->load_timing.base_ticks = renderer_base_ticks.ToTimeTicks();
619
620 #define CONVERT(field) \
621 LocalTimeDelta renderer_##field = converter.ToLocalTimeDelta( \
622 RemoteTimeDelta::FromRawDelta(browser_info.load_timing.field)); \
623 renderer_info->load_timing.field = renderer_##field.ToInt32()
624
625 CONVERT(proxy_start);
626 CONVERT(dns_start);
627 CONVERT(dns_end);
628 CONVERT(connect_start);
629 CONVERT(connect_end);
630 CONVERT(ssl_start);
631 CONVERT(ssl_end);
632 CONVERT(send_start);
633 CONVERT(send_end);
634 CONVERT(receive_headers_start);
635 CONVERT(receive_headers_end);
636
637 #undef CONVERT
638 }
639
640 base::TimeTicks ResourceDispatcher::ToRendererCompletionTime(
641 const PendingRequestInfo& request_info,
642 const base::TimeTicks& browser_completion_time) const {
643 if (request_info.completion_time.is_null()) {
644 return browser_completion_time;
645 }
646
647 // TODO(simonjam): The optimal lower bound should be the most recent value of
648 // TimeTicks::Now() returned to WebKit. Is it worth trying to cache that?
649 // Until then, |response_start| is used as it is the most recent value
650 // returned for this request.
651 int64 result = std::max(browser_completion_time.ToInternalValue(),
652 request_info.response_start.ToInternalValue());
653 result = std::min(result, request_info.completion_time.ToInternalValue());
654 return base::TimeTicks::FromInternalValue(result);
655 }
656
657 // static
582 bool ResourceDispatcher::IsResourceDispatcherMessage( 658 bool ResourceDispatcher::IsResourceDispatcherMessage(
583 const IPC::Message& message) { 659 const IPC::Message& message) {
584 switch (message.type()) { 660 switch (message.type()) {
585 case ResourceMsg_UploadProgress::ID: 661 case ResourceMsg_UploadProgress::ID:
586 case ResourceMsg_ReceivedResponse::ID: 662 case ResourceMsg_ReceivedResponse::ID:
587 case ResourceMsg_ReceivedCachedMetadata::ID: 663 case ResourceMsg_ReceivedCachedMetadata::ID:
588 case ResourceMsg_ReceivedRedirect::ID: 664 case ResourceMsg_ReceivedRedirect::ID:
589 case ResourceMsg_DataReceived::ID: 665 case ResourceMsg_DataReceived::ID:
590 case ResourceMsg_DataDownloaded::ID: 666 case ResourceMsg_DataDownloaded::ID:
591 case ResourceMsg_RequestComplete::ID: 667 case ResourceMsg_RequestComplete::ID:
(...skipping 30 matching lines...) Expand all
622 698
623 // static 699 // static
624 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { 700 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) {
625 while (!queue->empty()) { 701 while (!queue->empty()) {
626 IPC::Message* message = queue->front(); 702 IPC::Message* message = queue->front();
627 ReleaseResourcesInDataMessage(*message); 703 ReleaseResourcesInDataMessage(*message);
628 queue->pop_front(); 704 queue->pop_front();
629 delete message; 705 delete message;
630 } 706 }
631 } 707 }
OLDNEW
« no previous file with comments | « content/common/resource_dispatcher.h ('k') | content/common/resource_dispatcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698