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

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: Fix build 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
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 ConvertBrowserResponseToRendererResponse(*request_info, response_head);
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 ConvertBrowserResponseToRendererResponse(*request_info, response_head);
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 =
484 ConvertBrowserCompletionToRendererCompletion(*request_info,
485 browser_completion_time);
468 // The request ID will be removed from our pending list in the destructor. 486 // The request ID will be removed from our pending list in the destructor.
469 // Normally, dispatching this message causes the reference-counted request to 487 // Normally, dispatching this message causes the reference-counted request to
470 // die immediately. 488 // die immediately.
471 peer->OnCompletedRequest(status, security_info, completion_time); 489 peer->OnCompletedRequest(status, security_info, renderer_completion_time);
472 } 490 }
473 491
474 int ResourceDispatcher::AddPendingRequest( 492 int ResourceDispatcher::AddPendingRequest(
475 webkit_glue::ResourceLoaderBridge::Peer* callback, 493 webkit_glue::ResourceLoaderBridge::Peer* callback,
476 ResourceType::Type resource_type, 494 ResourceType::Type resource_type,
477 const GURL& request_url) { 495 const GURL& request_url) {
478 // Compute a unique request_id for this renderer process. 496 // Compute a unique request_id for this renderer process.
479 int id = MakeRequestID(); 497 int id = MakeRequestID();
480 pending_requests_[id] = 498 pending_requests_[id] =
481 PendingRequestInfo(callback, resource_type, request_url); 499 PendingRequestInfo(callback, resource_type, request_url);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 } 590 }
573 } 591 }
574 } 592 }
575 } 593 }
576 594
577 webkit_glue::ResourceLoaderBridge* ResourceDispatcher::CreateBridge( 595 webkit_glue::ResourceLoaderBridge* ResourceDispatcher::CreateBridge(
578 const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) { 596 const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) {
579 return new webkit_glue::IPCResourceLoaderBridge(this, request_info); 597 return new webkit_glue::IPCResourceLoaderBridge(this, request_info);
580 } 598 }
581 599
600 webkit_glue::ResourceResponseInfo
601 ResourceDispatcher::ConvertBrowserResponseToRendererResponse(
darin (slow to review) 2011/12/12 22:25:46 nit: this seems like a good use case for an out-pa
James Simonsen 2011/12/12 23:35:34 Done.
602 const PendingRequestInfo& request_info,
603 const content::ResourceResponseHead& browser_info) const {
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 browser_info;
609 }
610 webkit_glue::ResourceResponseInfo renderer_info = browser_info;
611 content::InterProcessTimeTicksConverter converter(
612 LocalTimeTicks::FromTimeTicks(request_info.request_start),
613 LocalTimeTicks::FromTimeTicks(request_info.response_start),
614 RemoteTimeTicks::FromTimeTicks(browser_info.request_start),
615 RemoteTimeTicks::FromTimeTicks(browser_info.response_start));
616
617 LocalTimeTicks renderer_base_ticks = converter.ConvertMilliseconds(
618 RemoteTimeTicks::FromTimeTicks(browser_info.load_timing.base_ticks));
619 renderer_info.load_timing.base_ticks = renderer_base_ticks.ToTimeTicks();
620
621 #define CONVERT(field) \
622 LocalTimeDelta renderer_##field = converter.ConvertDelta( \
623 RemoteTimeDelta::FromRawDelta(browser_info.load_timing.field)); \
624 renderer_info.load_timing.field = renderer_##field.ToInt32()
625
626 CONVERT(proxy_start);
627 CONVERT(dns_start);
628 CONVERT(dns_end);
629 CONVERT(connect_start);
630 CONVERT(connect_end);
631 CONVERT(ssl_start);
632 CONVERT(ssl_end);
633 CONVERT(send_start);
634 CONVERT(send_end);
635 CONVERT(receive_headers_start);
636 CONVERT(receive_headers_end);
637
638 #undef CONVERT
639
640 return renderer_info;
641 }
642
643 base::TimeTicks
644 ResourceDispatcher::ConvertBrowserCompletionToRendererCompletion(
darin (slow to review) 2011/12/12 22:25:46 nit: maybe just shorten this function named down t
James Simonsen 2011/12/12 23:35:34 Done.
645 const PendingRequestInfo& request_info,
646 const base::TimeTicks& browser_completion_time) const {
647 if (request_info.completion_time.is_null()) {
648 return browser_completion_time;
649 }
650
651 // TODO(simonjam): The optimal lower bound should be the most recent value of
652 // TimeTicks::Now() returned to WebKit. Is it worth trying to cache that?
653 // Until then, |response_start| is used as it is the most recent value
654 // returned for this request.
655 LocalTimeTicks renderer_completion_time =
656 content::InterProcessTimeTicksConverter::ClampTimeInRange(
657 RemoteTimeTicks::FromTimeTicks(browser_completion_time),
658 LocalTimeTicks::FromTimeTicks(request_info.response_start),
659 LocalTimeTicks::FromTimeTicks(request_info.completion_time));
660 return renderer_completion_time.ToTimeTicks();
661 }
662
663 // static
582 bool ResourceDispatcher::IsResourceDispatcherMessage( 664 bool ResourceDispatcher::IsResourceDispatcherMessage(
583 const IPC::Message& message) { 665 const IPC::Message& message) {
584 switch (message.type()) { 666 switch (message.type()) {
585 case ResourceMsg_UploadProgress::ID: 667 case ResourceMsg_UploadProgress::ID:
586 case ResourceMsg_ReceivedResponse::ID: 668 case ResourceMsg_ReceivedResponse::ID:
587 case ResourceMsg_ReceivedCachedMetadata::ID: 669 case ResourceMsg_ReceivedCachedMetadata::ID:
588 case ResourceMsg_ReceivedRedirect::ID: 670 case ResourceMsg_ReceivedRedirect::ID:
589 case ResourceMsg_DataReceived::ID: 671 case ResourceMsg_DataReceived::ID:
590 case ResourceMsg_DataDownloaded::ID: 672 case ResourceMsg_DataDownloaded::ID:
591 case ResourceMsg_RequestComplete::ID: 673 case ResourceMsg_RequestComplete::ID:
(...skipping 30 matching lines...) Expand all
622 704
623 // static 705 // static
624 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { 706 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) {
625 while (!queue->empty()) { 707 while (!queue->empty()) {
626 IPC::Message* message = queue->front(); 708 IPC::Message* message = queue->front();
627 ReleaseResourcesInDataMessage(*message); 709 ReleaseResourcesInDataMessage(*message);
628 queue->pop_front(); 710 queue->pop_front();
629 delete message; 711 delete message;
630 } 712 }
631 } 713 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698