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

Side by Side Diff: content/browser/webui/url_data_manager_backend.cc

Issue 2158123003: [MD Settings] Remove jank for webui. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Do all the things on a worker thread. Created 4 years, 5 months 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
« no previous file with comments | « no previous file | no next file » | 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) 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/webui/url_data_manager_backend.h" 5 #include "content/browser/webui/url_data_manager_backend.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/debug/alias.h" 12 #include "base/debug/alias.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/memory/ref_counted.h" 17 #include "base/memory/ref_counted.h"
18 #include "base/memory/ref_counted_memory.h" 18 #include "base/memory/ref_counted_memory.h"
19 #include "base/memory/weak_ptr.h" 19 #include "base/memory/weak_ptr.h"
20 #include "base/profiler/scoped_tracker.h" 20 #include "base/profiler/scoped_tracker.h"
21 #include "base/single_thread_task_runner.h" 21 #include "base/single_thread_task_runner.h"
22 #include "base/strings/string_number_conversions.h" 22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/string_util.h" 23 #include "base/strings/string_util.h"
24 #include "base/strings/stringprintf.h" 24 #include "base/strings/stringprintf.h"
25 #include "base/threading/worker_pool.h"
25 #include "base/trace_event/trace_event.h" 26 #include "base/trace_event/trace_event.h"
26 #include "content/browser/blob_storage/chrome_blob_storage_context.h" 27 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
27 #include "content/browser/histogram_internals_request_job.h" 28 #include "content/browser/histogram_internals_request_job.h"
28 #include "content/browser/net/view_blob_internals_job_factory.h" 29 #include "content/browser/net/view_blob_internals_job_factory.h"
29 #include "content/browser/net/view_http_cache_job_factory.h" 30 #include "content/browser/net/view_http_cache_job_factory.h"
30 #include "content/browser/resource_context_impl.h" 31 #include "content/browser/resource_context_impl.h"
31 #include "content/browser/webui/shared_resources_data_source.h" 32 #include "content/browser/webui/shared_resources_data_source.h"
32 #include "content/browser/webui/url_data_source_impl.h" 33 #include "content/browser/webui/url_data_source_impl.h"
33 #include "content/public/browser/browser_context.h" 34 #include "content/public/browser/browser_context.h"
34 #include "content/public/browser/browser_thread.h" 35 #include "content/public/browser/browser_thread.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 std::string result; 98 std::string result;
98 if (request->extra_request_headers().GetHeader( 99 if (request->extra_request_headers().GetHeader(
99 net::HttpRequestHeaders::kOrigin, &result)) 100 net::HttpRequestHeaders::kOrigin, &result))
100 return result; 101 return result;
101 net::HttpRequestHeaders headers; 102 net::HttpRequestHeaders headers;
102 if (request->GetFullRequestHeaders(&headers)) 103 if (request->GetFullRequestHeaders(&headers))
103 headers.GetHeader(net::HttpRequestHeaders::kOrigin, &result); 104 headers.GetHeader(net::HttpRequestHeaders::kOrigin, &result);
104 return result; 105 return result;
105 } 106 }
106 107
108 // Copy data from source buffer into IO buffer destination.
109 // TODO(groby): Very similar to URLRequestSimpleJob, unify at some point.
110 void CopyData(const scoped_refptr<net::IOBuffer>& buf,
111 int buf_size,
112 const scoped_refptr<base::RefCountedMemory>& data,
113 int64_t data_offset) {
114 if (buf_size > 0) {
Dan Beam 2016/07/19 23:27:33 when will this ever be == 0?
groby-ooo-7-16 2016/07/20 01:01:40 It used to be possible in a previous iteration of
115 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455423 is
116 // fixed.
117 tracked_objects::ScopedTracker tracking_profile(
118 FROM_HERE_WITH_EXPLICIT_FUNCTION(
119 "455423 URLRequestChromeJob::CompleteRead memcpy"));
120 memcpy(buf->data(), data->front() + data_offset, buf_size);
121 }
122 }
123
107 } // namespace 124 } // namespace
108 125
109 // URLRequestChromeJob is a net::URLRequestJob that manages running 126 // URLRequestChromeJob is a net::URLRequestJob that manages running
110 // chrome-internal resource requests asynchronously. 127 // chrome-internal resource requests asynchronously.
111 // It hands off URL requests to ChromeURLDataManager, which asynchronously 128 // It hands off URL requests to ChromeURLDataManager, which asynchronously
112 // calls back once the data is available. 129 // calls back once the data is available.
113 class URLRequestChromeJob : public net::URLRequestJob { 130 class URLRequestChromeJob : public net::URLRequestJob {
114 public: 131 public:
115 // |is_incognito| set when job is generated from an incognito profile. 132 // |is_incognito| set when job is generated from an incognito profile.
116 URLRequestChromeJob(net::URLRequest* request, 133 URLRequestChromeJob(net::URLRequest* request,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 // (This pattern is shared by most net::URLRequestJob implementations.) 214 // (This pattern is shared by most net::URLRequestJob implementations.)
198 void StartAsync(); 215 void StartAsync();
199 216
200 // Due to a race condition, DevTools relies on a legacy thread hop to the UI 217 // Due to a race condition, DevTools relies on a legacy thread hop to the UI
201 // thread before calling StartAsync. 218 // thread before calling StartAsync.
202 // TODO(caseq): Fix the race condition and remove this thread hop in 219 // TODO(caseq): Fix the race condition and remove this thread hop in
203 // https://crbug.com/616641. 220 // https://crbug.com/616641.
204 static void DelayStartForDevTools( 221 static void DelayStartForDevTools(
205 const base::WeakPtr<URLRequestChromeJob>& job); 222 const base::WeakPtr<URLRequestChromeJob>& job);
206 223
207 // Do the actual copy from data_ (the data we're serving) into |buf|. 224 // Post a task to copy |data_| to |buf_| on a worker thread, to avoid browser
208 // Separate from ReadRawData so we can handle async I/O. Returns the number of 225 // jank. (|data_| might be mem-mapped, so a memcpy can trigger file ops).
209 // bytes read. 226 int PostReadTask(net::IOBuffer* buf, int buf_size);
210 int CompleteRead(net::IOBuffer* buf, int buf_size);
211 227
212 // The actual data we're serving. NULL until it's been fetched. 228 // The actual data we're serving. NULL until it's been fetched.
213 scoped_refptr<base::RefCountedMemory> data_; 229 scoped_refptr<base::RefCountedMemory> data_;
214 // The current offset into the data that we're handing off to our 230 // The current offset into the data that we're handing off to our
215 // callers via the Read interfaces. 231 // callers via the Read interfaces.
216 int data_offset_; 232 int data_offset_;
217 233
218 // For async reads, we keep around a pointer to the buffer that 234 // For async reads, we keep around a pointer to the buffer that
219 // we're reading into. 235 // we're reading into.
220 scoped_refptr<net::IOBuffer> pending_buf_; 236 scoped_refptr<net::IOBuffer> pending_buf_;
(...skipping 22 matching lines...) Expand all
243 // If not empty, "Access-Control-Allow-Origin:" is set to the value of this 259 // If not empty, "Access-Control-Allow-Origin:" is set to the value of this
244 // string. 260 // string.
245 std::string access_control_allow_origin_; 261 std::string access_control_allow_origin_;
246 262
247 // True when job is generated from an incognito profile. 263 // True when job is generated from an incognito profile.
248 const bool is_incognito_; 264 const bool is_incognito_;
249 265
250 // The backend is owned by net::URLRequestContext and always outlives us. 266 // The backend is owned by net::URLRequestContext and always outlives us.
251 URLDataManagerBackend* backend_; 267 URLDataManagerBackend* backend_;
252 268
269 scoped_refptr<base::TaskRunner> task_runner_;
253 base::WeakPtrFactory<URLRequestChromeJob> weak_factory_; 270 base::WeakPtrFactory<URLRequestChromeJob> weak_factory_;
254 271
255 DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob); 272 DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob);
256 }; 273 };
257 274
258 URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request, 275 URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request,
259 net::NetworkDelegate* network_delegate, 276 net::NetworkDelegate* network_delegate,
260 URLDataManagerBackend* backend, 277 URLDataManagerBackend* backend,
261 bool is_incognito) 278 bool is_incognito)
262 : net::URLRequestJob(request, network_delegate), 279 : net::URLRequestJob(request, network_delegate),
263 data_offset_(0), 280 data_offset_(0),
264 pending_buf_size_(0), 281 pending_buf_size_(0),
265 allow_caching_(true), 282 allow_caching_(true),
266 add_content_security_policy_(true), 283 add_content_security_policy_(true),
267 deny_xframe_options_(true), 284 deny_xframe_options_(true),
268 send_content_type_header_(false), 285 send_content_type_header_(false),
269 is_incognito_(is_incognito), 286 is_incognito_(is_incognito),
270 backend_(backend), 287 backend_(backend),
288 task_runner_(base::WorkerPool::GetTaskRunner(false)),
Dan Beam 2016/07/19 23:27:33 do we want to ref the workerpool the whole time th
groby-ooo-7-16 2016/07/20 01:01:40 We'll need it at the very least until all read req
mmenke 2016/07/20 16:47:58 You don't need to hold onto it - it's a leaked glo
groby-ooo-7-16 2016/07/20 18:10:11 Sounds good.
271 weak_factory_(this) { 289 weak_factory_(this) {
272 DCHECK(backend); 290 DCHECK(backend);
273 } 291 }
274 292
275 URLRequestChromeJob::~URLRequestChromeJob() { 293 URLRequestChromeJob::~URLRequestChromeJob() {
276 CHECK(!backend_->HasPendingJob(this)); 294 CHECK(!backend_->HasPendingJob(this));
277 } 295 }
278 296
279 void URLRequestChromeJob::Start() { 297 void URLRequestChromeJob::Start() {
280 const GURL url = request_->url(); 298 const GURL url = request_->url();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 } 375 }
358 } 376 }
359 377
360 void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) { 378 void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) {
361 set_mime_type(mime_type); 379 set_mime_type(mime_type);
362 NotifyHeadersComplete(); 380 NotifyHeadersComplete();
363 } 381 }
364 382
365 void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) { 383 void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) {
366 TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this); 384 TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this);
367 if (bytes) { 385 DCHECK(!data_);
368 data_ = bytes; 386
369 if (pending_buf_.get()) { 387 // If we don't have data, signal an error.
mmenke 2016/07/20 16:47:58 Here and below, some people hold pretty strongly t
groby-ooo-7-16 2016/07/20 18:10:12 Clearly, it's the royal "we" ;) Fixed
370 CHECK(pending_buf_->data()); 388 if (!bytes) {
371 int result = CompleteRead(pending_buf_.get(), pending_buf_size_); 389 ReadRawDataComplete(net::ERR_FAILED);
372 pending_buf_ = NULL; 390 return;
391 }
392
393 // We have data, let's try to satisfy the request.
394 data_ = bytes;
395
396 if (pending_buf_.get()) {
mmenke 2016/07/20 16:47:58 optioanl nit: .get() not needed. (I feel if it's
groby-ooo-7-16 2016/07/20 18:10:12 Thanks for flagging, fixed.
397 int result = PostReadTask(pending_buf_.get(), pending_buf_size_);
398 if (result != net::ERR_IO_PENDING)
373 ReadRawDataComplete(result); 399 ReadRawDataComplete(result);
374 } 400 pending_buf_ = nullptr;
375 } else {
376 // The request failed.
377 ReadRawDataComplete(net::ERR_FAILED);
378 } 401 }
379 } 402 }
380 403
381 base::WeakPtr<URLRequestChromeJob> URLRequestChromeJob::AsWeakPtr() { 404 base::WeakPtr<URLRequestChromeJob> URLRequestChromeJob::AsWeakPtr() {
382 return weak_factory_.GetWeakPtr(); 405 return weak_factory_.GetWeakPtr();
383 } 406 }
384 407
385 int URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size) { 408 int URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
409 DCHECK(!pending_buf_.get());
410
411 // If data isn't available yet, mark this as asynchronous.
386 if (!data_.get()) { 412 if (!data_.get()) {
387 DCHECK(!pending_buf_.get());
388 CHECK(buf->data());
389 pending_buf_ = buf; 413 pending_buf_ = buf;
390 pending_buf_size_ = buf_size; 414 pending_buf_size_ = buf_size;
391 return net::ERR_IO_PENDING; 415 return net::ERR_IO_PENDING;
392 } 416 }
393 417
394 // Otherwise, the data is available. 418 return PostReadTask(buf, buf_size);
395 return CompleteRead(buf, buf_size);
396 } 419 }
397 420
398 int URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size) { 421 int URLRequestChromeJob::PostReadTask(net::IOBuffer* buf, int buf_size) {
mmenke 2016/07/20 16:47:58 Seems a little weird to take bug and buf_size as a
groby-ooo-7-16 2016/07/20 18:10:11 That was my original solution - I switched to this
mmenke 2016/07/20 18:19:43 I don't have a particularly strong opinion here, j
groby-ooo-7-16 2016/07/26 02:37:45 Acknowledged.
422 DCHECK(buf && data_);
mmenke 2016/07/20 16:47:58 Should split this into two DCHECKs, so if one fail
groby-ooo-7-16 2016/07/20 18:10:12 Done.
423 CHECK(buf->data());
424
399 int remaining = data_->size() - data_offset_; 425 int remaining = data_->size() - data_offset_;
400 if (buf_size > remaining) 426 if (buf_size > remaining)
401 buf_size = remaining; 427 buf_size = remaining;
402 if (buf_size > 0) { 428
403 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455423 is 429 if (buf_size == 0)
404 // fixed. 430 return 0;
405 tracked_objects::ScopedTracker tracking_profile( 431
Dan Beam 2016/07/19 23:27:33 can we just do if (buf_size == 0) { task_runner
groby-ooo-7-16 2016/07/20 01:01:40 We could - but there's no benefit to it. See above
406 FROM_HERE_WITH_EXPLICIT_FUNCTION( 432 task_runner_->PostTaskAndReply(
mmenke 2016/07/20 16:47:58 Could just use WorkerPool::PostTaskAndReply, and g
groby-ooo-7-16 2016/07/20 18:10:11 I looked at it, but it creates two additional obje
mmenke 2016/07/20 18:19:43 Code size generally matters more, and the single c
groby-ooo-7-16 2016/07/26 02:37:45 Digging deeper, the relay is necessary anyways, an
407 "455423 URLRequestChromeJob::CompleteRead memcpy")); 433 FROM_HERE, base::Bind(&CopyData, base::RetainedRef(buf), buf_size, data_,
408 memcpy(buf->data(), data_->front() + data_offset_, buf_size); 434 data_offset_),
409 data_offset_ += buf_size; 435 base::Bind(&URLRequestChromeJob::ReadRawDataComplete, AsWeakPtr(),
410 } 436 buf_size));
411 return buf_size; 437 data_offset_ += buf_size;
438
439 return net::ERR_IO_PENDING;
412 } 440 }
413 441
414 void URLRequestChromeJob::DelayStartForDevTools( 442 void URLRequestChromeJob::DelayStartForDevTools(
415 const base::WeakPtr<URLRequestChromeJob>& job) { 443 const base::WeakPtr<URLRequestChromeJob>& job) {
416 BrowserThread::PostTask( 444 BrowserThread::PostTask(
417 BrowserThread::IO, 445 BrowserThread::IO,
418 FROM_HERE, 446 FROM_HERE,
419 base::Bind(&URLRequestChromeJob::StartAsync, job)); 447 base::Bind(&URLRequestChromeJob::StartAsync, job));
420 } 448 }
421 449
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 822
795 } // namespace 823 } // namespace
796 824
797 net::URLRequestJobFactory::ProtocolHandler* 825 net::URLRequestJobFactory::ProtocolHandler*
798 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context, 826 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context,
799 bool is_incognito) { 827 bool is_incognito) {
800 return new DevToolsJobFactory(resource_context, is_incognito); 828 return new DevToolsJobFactory(resource_context, is_incognito);
801 } 829 }
802 830
803 } // namespace content 831 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698