1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/task_management/sampling/task_manager_io_thread_helper.h"
7 #include "chrome/browser/task_management/sampling/task_manager_impl.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/resource_request_info.h"
11 namespace task_management
{
15 TaskManagerIoThreadHelper
* g_io_thread_helper
= nullptr;
19 IoThreadHelperManager::IoThreadHelperManager() {
20 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
22 content::BrowserThread::PostTask(
23 content::BrowserThread::IO
,
25 base::Bind(&TaskManagerIoThreadHelper::CreateInstance
));
28 IoThreadHelperManager::~IoThreadHelperManager() {
29 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
31 content::BrowserThread::PostTask(
32 content::BrowserThread::IO
,
34 base::Bind(&TaskManagerIoThreadHelper::DeleteInstance
));
38 void TaskManagerIoThreadHelper::CreateInstance() {
39 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
40 DCHECK(!g_io_thread_helper
);
42 g_io_thread_helper
= new TaskManagerIoThreadHelper
;
46 void TaskManagerIoThreadHelper::DeleteInstance() {
47 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
49 delete g_io_thread_helper
;
50 g_io_thread_helper
= nullptr;
54 void TaskManagerIoThreadHelper::OnRawBytesRead(const net::URLRequest
& request
,
56 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
58 if (g_io_thread_helper
)
59 g_io_thread_helper
->OnNetworkBytesRead(request
, bytes_read
);
62 TaskManagerIoThreadHelper::TaskManagerIoThreadHelper()
63 : bytes_read_buffer_() {
64 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
67 TaskManagerIoThreadHelper::~TaskManagerIoThreadHelper() {
68 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
72 void TaskManagerIoThreadHelper::OnMultipleBytesReadIO() {
73 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
75 if (!g_io_thread_helper
)
78 DCHECK(!g_io_thread_helper
->bytes_read_buffer_
.empty());
80 std::vector
<BytesReadParam
>* bytes_read_buffer
=
81 new std::vector
<BytesReadParam
>();
82 g_io_thread_helper
->bytes_read_buffer_
.swap(*bytes_read_buffer
);
84 content::BrowserThread::PostTask(
85 content::BrowserThread::UI
,
87 base::Bind(&TaskManagerImpl::OnMultipleBytesReadUI
,
88 base::Owned(bytes_read_buffer
)));
91 void TaskManagerIoThreadHelper::OnNetworkBytesRead(
92 const net::URLRequest
& request
, int64_t bytes_read
) {
93 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
95 // Only net::URLRequestJob instances created by the ResourceDispatcherHost
96 // have an associated ResourceRequestInfo and a render frame associated.
97 // All other jobs will have -1 returned for the render process child and
98 // routing ids - the jobs may still match a resource based on their origin id,
99 // otherwise BytesRead() will attribute the activity to the Browser resource.
100 const content::ResourceRequestInfo
* info
=
101 content::ResourceRequestInfo::ForRequest(&request
);
105 info
->GetAssociatedRenderFrame(&child_id
, &route_id
);
107 // Get the origin PID of the request's originator. This will only be set for
108 // plugins - for renderer or browser initiated requests it will be zero.
109 int origin_pid
= info
? info
->GetOriginPID() : 0;
111 if (bytes_read_buffer_
.empty()) {
112 // Schedule a task to process the received bytes requests a second from now.
113 // We're trying to calculate the tasks' network usage speed as bytes per
114 // second so we collect as many requests during one seconds before the below
115 // delayed TaskManagerIoThreadHelper::OnMultipleBytesReadIO() process them
116 // after one second from now.
117 content::BrowserThread::PostDelayedTask(
118 content::BrowserThread::IO
,
120 base::Bind(TaskManagerIoThreadHelper::OnMultipleBytesReadIO
),
121 base::TimeDelta::FromSeconds(1));
124 bytes_read_buffer_
.push_back(
125 BytesReadParam(origin_pid
, child_id
, route_id
, bytes_read
));
128 } // namespace task_management