Chromium Code Reviews| Index: content/browser/webui/url_data_manager_backend.cc |
| diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc |
| index 404e834ca0d7542a3723e37baa9e0370a4958f98..8a3e910d319ab5e6e23b918aa0c8b835c9ba27e0 100644 |
| --- a/content/browser/webui/url_data_manager_backend.cc |
| +++ b/content/browser/webui/url_data_manager_backend.cc |
| @@ -22,6 +22,7 @@ |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/stringprintf.h" |
| +#include "base/threading/worker_pool.h" |
| #include "base/trace_event/trace_event.h" |
| #include "content/browser/blob_storage/chrome_blob_storage_context.h" |
| #include "content/browser/histogram_internals_request_job.h" |
| @@ -104,6 +105,20 @@ std::string GetOriginHeaderValue(const net::URLRequest* request) { |
| return result; |
| } |
| +// Copy data from source buffer into IO buffer destination. |
| +// TODO(groby): Very similar to URLRequestSimpleJob, unify at some point. |
| +void CopyData(const scoped_refptr<net::IOBuffer>& buf, |
| + int buf_size, |
| + const scoped_refptr<base::RefCountedMemory>& data, |
| + int64_t data_offset) { |
| + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455423 is |
| + // fixed. |
| + tracked_objects::ScopedTracker tracking_profile( |
| + FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| + "455423 URLRequestChromeJob::CompleteRead memcpy")); |
| + memcpy(buf->data(), data->front() + data_offset, buf_size); |
| +} |
| + |
| } // namespace |
| // URLRequestChromeJob is a net::URLRequestJob that manages running |
| @@ -204,10 +219,9 @@ class URLRequestChromeJob : public net::URLRequestJob { |
| static void DelayStartForDevTools( |
| const base::WeakPtr<URLRequestChromeJob>& job); |
| - // Do the actual copy from data_ (the data we're serving) into |buf|. |
| - // Separate from ReadRawData so we can handle async I/O. Returns the number of |
| - // bytes read. |
| - int CompleteRead(net::IOBuffer* buf, int buf_size); |
| + // Post a task to copy |data_| to |buf_| on a worker thread, to avoid browser |
| + // jank. (|data_| might be mem-mapped, so a memcpy can trigger file ops). |
| + int PostReadTask(net::IOBuffer* buf, int buf_size); |
| // The actual data we're serving. NULL until it's been fetched. |
| scoped_refptr<base::RefCountedMemory> data_; |
| @@ -364,17 +378,22 @@ void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) { |
| void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) { |
| TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this); |
| - if (bytes) { |
| - data_ = bytes; |
| - if (pending_buf_.get()) { |
| - CHECK(pending_buf_->data()); |
| - int result = CompleteRead(pending_buf_.get(), pending_buf_size_); |
| - pending_buf_ = NULL; |
| - ReadRawDataComplete(result); |
| - } |
| - } else { |
| - // The request failed. |
| + DCHECK(!data_); |
| + |
| + // A passed-in nullptr signals an error. |
| + if (!bytes) { |
| ReadRawDataComplete(net::ERR_FAILED); |
| + return; |
| + } |
| + |
| + // All further requests will be satisfied from the passed-in data. |
| + data_ = bytes; |
| + |
| + if (pending_buf_) { |
| + int result = PostReadTask(pending_buf_.get(), pending_buf_size_); |
| + if (result != net::ERR_IO_PENDING) |
| + ReadRawDataComplete(result); |
| + pending_buf_ = nullptr; |
|
dproy
2016/07/27 18:15:23
Drive-by comment since we had to revert this CL be
groby-ooo-7-16
2016/08/22 17:20:24
That does seem to be the issue. Finally investigat
mmenke
2016/08/22 17:25:52
Hrm...Surely some of our browser tests run this co
|
| } |
| } |
| @@ -383,32 +402,38 @@ base::WeakPtr<URLRequestChromeJob> URLRequestChromeJob::AsWeakPtr() { |
| } |
| int URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size) { |
| + DCHECK(!pending_buf_.get()); |
| + |
| + // If data isn't available yet, mark this as asynchronous. |
| if (!data_.get()) { |
| - DCHECK(!pending_buf_.get()); |
| - CHECK(buf->data()); |
| pending_buf_ = buf; |
| pending_buf_size_ = buf_size; |
| return net::ERR_IO_PENDING; |
| } |
| - // Otherwise, the data is available. |
| - return CompleteRead(buf, buf_size); |
| + return PostReadTask(buf, buf_size); |
| } |
| -int URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size) { |
| +int URLRequestChromeJob::PostReadTask(net::IOBuffer* buf, int buf_size) { |
| + DCHECK(buf); |
| + DCHECK(data_); |
| + CHECK(buf->data()); |
| + |
| int remaining = data_->size() - data_offset_; |
| if (buf_size > remaining) |
| buf_size = remaining; |
| - if (buf_size > 0) { |
| - // TODO(pkasting): Remove ScopedTracker below once crbug.com/455423 is |
| - // fixed. |
| - tracked_objects::ScopedTracker tracking_profile( |
| - FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| - "455423 URLRequestChromeJob::CompleteRead memcpy")); |
| - memcpy(buf->data(), data_->front() + data_offset_, buf_size); |
| - data_offset_ += buf_size; |
| - } |
| - return buf_size; |
| + |
| + if (buf_size == 0) |
| + return 0; |
| + |
| + base::WorkerPool::GetTaskRunner(false)->PostTaskAndReply( |
|
mmenke
2016/07/20 18:19:44
I think this should be true? Potential disk acces
groby-ooo-7-16
2016/07/26 02:37:45
I'm basing this on URLRequestSimpleJob - that also
|
| + FROM_HERE, base::Bind(&CopyData, base::RetainedRef(buf), buf_size, data_, |
| + data_offset_), |
| + base::Bind(&URLRequestChromeJob::ReadRawDataComplete, AsWeakPtr(), |
| + buf_size)); |
| + data_offset_ += buf_size; |
| + |
| + return net::ERR_IO_PENDING; |
| } |
| void URLRequestChromeJob::DelayStartForDevTools( |