summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resource_dispatcher_host.cc
diff options
context:
space:
mode:
authorpaulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-01 00:14:02 +0000
committerpaulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-01 00:14:02 +0000
commit1ca6df9ae9d23bffa27bb1f5fd19a79a6621939a (patch)
treea9fea3767e301099e4343fd228209df02143130f /chrome/browser/resource_dispatcher_host.cc
parent656e3b3857e315a4a6386944fb140ef202580f77 (diff)
downloadchromium_src-1ca6df9ae9d23bffa27bb1f5fd19a79a6621939a.zip
chromium_src-1ca6df9ae9d23bffa27bb1f5fd19a79a6621939a.tar.gz
chromium_src-1ca6df9ae9d23bffa27bb1f5fd19a79a6621939a.tar.bz2
Eliminate the infinite read loop that can occasionally allow
a large, fast network request to monopolize the IO thread. This particular bug was tickled by an FTP download where pause tasks posted to the IO thread from the UI thread were blocked from running until the FTP transfer was completed, leading to user noticeable jankiness. I added histograms to the previous read loop and noticed that during regular browsing and downloading sessions, the number of times the loop was traversed was 1 for something like 99.5% of the time. This leads me to believe that eliminating the read loop in favor of asynchronous tasks will not impact performance. BUG=1270179 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/resource_dispatcher_host.cc')
-rw-r--r--chrome/browser/resource_dispatcher_host.cc28
1 files changed, 20 insertions, 8 deletions
diff --git a/chrome/browser/resource_dispatcher_host.cc b/chrome/browser/resource_dispatcher_host.cc
index c81f9cb..c3f4e91 100644
--- a/chrome/browser/resource_dispatcher_host.cc
+++ b/chrome/browser/resource_dispatcher_host.cc
@@ -2024,16 +2024,28 @@ void ResourceDispatcherHost::OnReadCompleted(URLRequest* request,
return;
}
- // Keep reading as long as we can.
- while (request->status().is_success() &&
- CompleteRead(request, &bytes_read)) {
+ if (request->status().is_success() && CompleteRead(request, &bytes_read)) {
// The request can be paused if we realize that the renderer is not
// servicing messages fast enough.
- if (info->pause_count > 0)
- break;
-
- if (!Read(request, &bytes_read))
- break; // IO is pending.
+ if (info->pause_count == 0 &&
+ Read(request, &bytes_read) &&
+ request->status().is_success()) {
+ if (bytes_read == 0) {
+ CompleteRead(request, &bytes_read);
+ } else {
+ // Force the next CompleteRead / Read pair to run as a separate task.
+ // This avoids a fast, large network request from monopolizing the IO
+ // thread and starving other IO operations from running.
+ info->paused_read_bytes = bytes_read;
+ info->is_paused = true;
+ GlobalRequestID id(info->render_process_host_id, info->request_id);
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_runner_.NewRunnableMethod(
+ &ResourceDispatcherHost::ResumeRequest, id));
+ return;
+ }
+ }
}
if (PauseRequestIfNeeded(info)) {