Index: chrome/browser/image_decoder.cc |
diff --git a/chrome/browser/image_decoder.cc b/chrome/browser/image_decoder.cc |
index f8f736ae63c2983a5ff57785f8e99884ae2927ad..b5835bcbe1db03d78c9c17bf40bd6edd9d78fc8b 100644 |
--- a/chrome/browser/image_decoder.cc |
+++ b/chrome/browser/image_decoder.cc |
@@ -177,6 +177,37 @@ void ImageDecoder::StopBatchMode() { |
utility_process_host_.reset(); |
} |
batch_mode_timer_.Stop(); |
+ |
+ // There could be outstanding request that are taking too long. Fail these so |
+ // that there aren't any dangling requests. |
+ FailAllRequests(); |
+} |
+ |
+void ImageDecoder::FailAllRequests() { |
+ RequestMap requests; |
+ { |
+ base::AutoLock lock(map_lock_); |
+ requests = image_request_id_map_; |
+ } |
+ |
+ // Since |OnProcessCrashed| and |OnProcessLaunchFailed| are run asynchronously |
+ // from the actual event, it's possible for a new utility process to have been |
+ // created and sent requests by the time these functions are run. This results |
+ // in failing requests that are unaffected by the crash. Although not ideal, |
+ // this is valid and simpler than tracking which request is sent to which |
+ // utility process, and whether the request has been sent at all. |
+ for (const auto& request : requests) |
+ OnDecodeImageFailed(request.first); |
+} |
+ |
+void ImageDecoder::OnProcessCrashed(int exit_code) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ FailAllRequests(); |
+} |
+ |
+void ImageDecoder::OnProcessLaunchFailed() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ FailAllRequests(); |
} |
bool ImageDecoder::OnMessageReceived( |