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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/resource_dispatcher.h ('k') | content/common/resource_dispatcher_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/resource_dispatcher.cc
diff --git a/content/common/resource_dispatcher.cc b/content/common/resource_dispatcher.cc
index 6094fc2768082b0c9162ae5b315727cf6bbaa3cd..38bc0145680261207e50fd2939febad4d3192631 100644
--- a/content/common/resource_dispatcher.cc
+++ b/content/common/resource_dispatcher.cc
@@ -13,6 +13,7 @@
#include "base/message_loop.h"
#include "base/shared_memory.h"
#include "base/string_util.h"
+#include "content/common/inter_process_time_ticks_converter.h"
#include "content/common/request_extra_data.h"
#include "content/common/resource_messages.h"
#include "content/public/common/resource_dispatcher_delegate.h"
@@ -23,6 +24,12 @@
#include "net/http/http_response_headers.h"
#include "webkit/glue/resource_type.h"
+using content::InterProcessTimeTicksConverter;
+using content::LocalTimeDelta;
+using content::LocalTimeTicks;
+using content::RemoteTimeDelta;
+using content::RemoteTimeTicks;
+
// Each resource request is assigned an ID scoped to this process.
static int MakeRequestID() {
// NOTE: The resource_dispatcher_host also needs probably unique
@@ -348,6 +355,7 @@ void ResourceDispatcher::OnReceivedResponse(
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
if (!request_info)
return;
+ request_info->response_start = base::TimeTicks::Now();
if (delegate_) {
webkit_glue::ResourceLoaderBridge::Peer* new_peer =
@@ -357,7 +365,9 @@ void ResourceDispatcher::OnReceivedResponse(
request_info->peer = new_peer;
}
- request_info->peer->OnReceivedResponse(response_head);
+ webkit_glue::ResourceResponseInfo renderer_response_info;
+ ToResourceResponseInfo(*request_info, response_head, &renderer_response_info);
+ request_info->peer->OnReceivedResponse(renderer_response_info);
}
void ResourceDispatcher::OnReceivedCachedMetadata(
@@ -411,17 +421,20 @@ void ResourceDispatcher::OnReceivedRedirect(
const IPC::Message& message,
int request_id,
const GURL& new_url,
- const webkit_glue::ResourceResponseInfo& info) {
+ const content::ResourceResponseHead& response_head) {
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
if (!request_info)
return;
+ request_info->response_start = base::TimeTicks::Now();
int32 routing_id = message.routing_id();
bool has_new_first_party_for_cookies = false;
GURL new_first_party_for_cookies;
- if (request_info->peer->OnReceivedRedirect(new_url, info,
- &has_new_first_party_for_cookies,
- &new_first_party_for_cookies)) {
+ webkit_glue::ResourceResponseInfo renderer_response_info;
+ ToResourceResponseInfo(*request_info, response_head, &renderer_response_info);
+ if (request_info->peer->OnReceivedRedirect(new_url, renderer_response_info,
+ &has_new_first_party_for_cookies,
+ &new_first_party_for_cookies)) {
// Double-check if the request is still around. The call above could
// potentially remove it.
request_info = GetPendingRequestInfo(request_id);
@@ -447,13 +460,15 @@ void ResourceDispatcher::FollowPendingRedirect(
message_sender()->Send(msg);
}
-void ResourceDispatcher::OnRequestComplete(int request_id,
- const net::URLRequestStatus& status,
- const std::string& security_info,
- const base::Time& completion_time) {
+void ResourceDispatcher::OnRequestComplete(
+ int request_id,
+ const net::URLRequestStatus& status,
+ const std::string& security_info,
+ const base::TimeTicks& browser_completion_time) {
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
if (!request_info)
return;
+ request_info->completion_time = base::TimeTicks::Now();
webkit_glue::ResourceLoaderBridge::Peer* peer = request_info->peer;
@@ -465,10 +480,12 @@ void ResourceDispatcher::OnRequestComplete(int request_id,
request_info->peer = new_peer;
}
+ base::TimeTicks renderer_completion_time = ToRendererCompletionTime(
+ *request_info, browser_completion_time);
// The request ID will be removed from our pending list in the destructor.
// Normally, dispatching this message causes the reference-counted request to
// die immediately.
- peer->OnCompletedRequest(status, security_info, completion_time);
+ peer->OnCompletedRequest(status, security_info, renderer_completion_time);
}
int ResourceDispatcher::AddPendingRequest(
@@ -579,6 +596,65 @@ webkit_glue::ResourceLoaderBridge* ResourceDispatcher::CreateBridge(
return new webkit_glue::IPCResourceLoaderBridge(this, request_info);
}
+void ResourceDispatcher::ToResourceResponseInfo(
+ const PendingRequestInfo& request_info,
+ const content::ResourceResponseHead& browser_info,
+ webkit_glue::ResourceResponseInfo* renderer_info) const {
+ *renderer_info = browser_info;
+ if (request_info.request_start.is_null() ||
+ request_info.response_start.is_null() ||
+ browser_info.request_start.is_null() ||
+ browser_info.response_start.is_null()) {
+ return;
+ }
+ content::InterProcessTimeTicksConverter converter(
+ LocalTimeTicks::FromTimeTicks(request_info.request_start),
+ LocalTimeTicks::FromTimeTicks(request_info.response_start),
+ RemoteTimeTicks::FromTimeTicks(browser_info.request_start),
+ RemoteTimeTicks::FromTimeTicks(browser_info.response_start));
+
+ LocalTimeTicks renderer_base_ticks = converter.ToLocalTimeTicks(
+ RemoteTimeTicks::FromTimeTicks(browser_info.load_timing.base_ticks));
+ renderer_info->load_timing.base_ticks = renderer_base_ticks.ToTimeTicks();
+
+#define CONVERT(field) \
+ LocalTimeDelta renderer_##field = converter.ToLocalTimeDelta( \
+ RemoteTimeDelta::FromRawDelta(browser_info.load_timing.field)); \
+ renderer_info->load_timing.field = renderer_##field.ToInt32()
+
+ CONVERT(proxy_start);
+ CONVERT(dns_start);
+ CONVERT(dns_end);
+ CONVERT(connect_start);
+ CONVERT(connect_end);
+ CONVERT(ssl_start);
+ CONVERT(ssl_end);
+ CONVERT(send_start);
+ CONVERT(send_end);
+ CONVERT(receive_headers_start);
+ CONVERT(receive_headers_end);
+
+#undef CONVERT
+}
+
+base::TimeTicks ResourceDispatcher::ToRendererCompletionTime(
+ const PendingRequestInfo& request_info,
+ const base::TimeTicks& browser_completion_time) const {
+ if (request_info.completion_time.is_null()) {
+ return browser_completion_time;
+ }
+
+ // TODO(simonjam): The optimal lower bound should be the most recent value of
+ // TimeTicks::Now() returned to WebKit. Is it worth trying to cache that?
+ // Until then, |response_start| is used as it is the most recent value
+ // returned for this request.
+ int64 result = std::max(browser_completion_time.ToInternalValue(),
+ request_info.response_start.ToInternalValue());
+ result = std::min(result, request_info.completion_time.ToInternalValue());
+ return base::TimeTicks::FromInternalValue(result);
+}
+
+// static
bool ResourceDispatcher::IsResourceDispatcherMessage(
const IPC::Message& message) {
switch (message.type()) {
« 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