Index: content/browser/loader/resource_loader.cc |
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc |
index 0b3833a655ec3c9a6f44b7826de333f460f26f68..bb77021ac8fa20c3d369154da1b6f0adcd0df945 100644 |
--- a/content/browser/loader/resource_loader.cc |
+++ b/content/browser/loader/resource_loader.cc |
@@ -350,13 +350,13 @@ void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { |
CompleteResponseStarted(); |
- if (is_deferred()) |
+ // If the handler deferred the request, it will resume the request later. If |
+ // the request was cancelled, the request will call back into |this| with a |
+ // bogus read completed error. |
+ if (is_deferred() || !request_->status().is_success()) |
return; |
- if (request_->status().is_success()) |
- StartReading(false); // Read the first chunk. |
- else |
- ResponseCompleted(); |
+ ReadMore(false); // Read the first chunk. |
} |
void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { |
@@ -375,17 +375,14 @@ void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { |
CompleteRead(bytes_read); |
// If the handler cancelled or deferred the request, do not continue |
- // processing the read. If cancelled, the URLRequest has already been |
- // cancelled and will schedule an erroring OnReadCompleted later. If deferred, |
- // do nothing until resumed. |
- // |
- // Note: if bytes_read is 0 (EOF) and the handler defers, resumption will call |
- // ResponseCompleted(). |
+ // processing the read. If canceled, either the request will call into |this| |
+ // with a bogus read error, or, if the request was completed, a task posted |
+ // from ResourceLoader::CancelREquestInternal will run OnResponseCompleted. |
if (is_deferred() || !request_->status().is_success()) |
return; |
if (bytes_read > 0) { |
- StartReading(true); // Read the next chunk. |
+ ReadMore(true); // Read the next chunk. |
} else { |
// TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. |
tracked_objects::ScopedTracker tracking_profile( |
@@ -557,42 +554,7 @@ void ResourceLoader::CompleteResponseStarted() { |
} |
} |
-void ResourceLoader::StartReading(bool is_continuation) { |
- int bytes_read = 0; |
- ReadMore(&bytes_read); |
- |
- // If IO is pending, wait for the URLRequest to call OnReadCompleted. |
- if (request_->status().is_io_pending()) |
- return; |
- |
- if (!is_continuation || bytes_read <= 0) { |
- OnReadCompleted(request_.get(), bytes_read); |
- } else { |
- // Else, trigger OnReadCompleted asynchronously to avoid starving the IO |
- // thread in case the URLRequest can provide data synchronously. |
- base::ThreadTaskRunnerHandle::Get()->PostTask( |
- FROM_HERE, |
- base::Bind(&ResourceLoader::OnReadCompleted, |
- weak_ptr_factory_.GetWeakPtr(), request_.get(), bytes_read)); |
- } |
-} |
- |
-void ResourceLoader::ResumeReading() { |
- DCHECK(!is_deferred()); |
- |
- if (!read_deferral_start_time_.is_null()) { |
- UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", |
- base::TimeTicks::Now() - read_deferral_start_time_); |
- read_deferral_start_time_ = base::TimeTicks(); |
- } |
- if (request_->status().is_success()) { |
- StartReading(false); // Read the next chunk (OK to complete synchronously). |
- } else { |
- ResponseCompleted(); |
- } |
-} |
- |
-void ResourceLoader::ReadMore(int* bytes_read) { |
+void ResourceLoader::ReadMore(bool is_continuation) { |
TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ReadMore", this, |
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); |
DCHECK(!is_deferred()); |
@@ -608,6 +570,8 @@ void ResourceLoader::ReadMore(int* bytes_read) { |
FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnWillRead()")); |
if (!handler_->OnWillRead(&buf, &buf_size, -1)) { |
+ // Cancel the request, which will then call back into |this| to inform it |
+ // of a "read error". |
Cancel(); |
return; |
} |
@@ -616,10 +580,36 @@ void ResourceLoader::ReadMore(int* bytes_read) { |
DCHECK(buf.get()); |
DCHECK(buf_size > 0); |
- request_->Read(buf.get(), buf_size, bytes_read); |
+ int result = request_->Read(buf.get(), buf_size); |
+ |
+ if (result == net::ERR_IO_PENDING) |
+ return; |
+ |
+ if (!is_continuation || result <= 0) { |
+ OnReadCompleted(request_.get(), result); |
+ } else { |
+ // Else, trigger OnReadCompleted asynchronously to avoid starving the IO |
+ // thread in case the URLRequest can provide data synchronously. |
+ base::ThreadTaskRunnerHandle::Get()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&ResourceLoader::OnReadCompleted, |
+ weak_ptr_factory_.GetWeakPtr(), request_.get(), result)); |
+ } |
+} |
- // No need to check the return value here as we'll detect errors by |
- // inspecting the URLRequest's status. |
+void ResourceLoader::ResumeReading() { |
+ DCHECK(!is_deferred()); |
+ |
+ if (!read_deferral_start_time_.is_null()) { |
+ UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", |
+ base::TimeTicks::Now() - read_deferral_start_time_); |
+ read_deferral_start_time_ = base::TimeTicks(); |
+ } |
+ if (request_->status().is_success()) { |
+ ReadMore(false); // Read the next chunk (OK to complete synchronously). |
+ } else { |
+ ResponseCompleted(); |
+ } |
} |
void ResourceLoader::CompleteRead(int bytes_read) { |