From 4c402bfd7602197a2d19fe68c9d89a5f6484b4e3 Mon Sep 17 00:00:00 2001
From: "phajdan.jr@chromium.org"
 <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Thu, 2 Sep 2010 17:25:09 +0000
Subject: Fix a race condition after my latest download cleanup change.

We need to pause the download request until the on-disk file
is actually created. Otherwise all data received from network would
be discarded.

BUG=54131
TEST=see bug

Review URL: http://codereview.chromium.org/3333007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58374 0039d316-1c4b-4281-b951-d872f2087c98
---
 chrome/browser/download/download_file_manager.cc | 13 +++++++++++++
 chrome/browser/download/download_file_manager.h  |  4 ++++
 2 files changed, 17 insertions(+)

(limited to 'chrome/browser/download')

diff --git a/chrome/browser/download/download_file_manager.cc b/chrome/browser/download/download_file_manager.cc
index 3c1edf9..df28bbf 100644
--- a/chrome/browser/download/download_file_manager.cc
+++ b/chrome/browser/download/download_file_manager.cc
@@ -96,6 +96,12 @@ void DownloadFileManager::CreateDownloadFile(
   // TODO(phajdan.jr): fix the duplication of path info below.
   info->path = info->save_info.file_path;
 
+  // The file is now ready, we can un-pause the request and start saving data.
+  ChromeThread::PostTask(
+      ChromeThread::IO, FROM_HERE,
+      NewRunnableMethod(this, &DownloadFileManager::ResumeDownloadRequest,
+                        info->child_id, info->request_id));
+
   StartUpdateTimer();
 
   ChromeThread::PostTask(
@@ -104,6 +110,13 @@ void DownloadFileManager::CreateDownloadFile(
                         &DownloadManager::StartDownload, info));
 }
 
+void DownloadFileManager::ResumeDownloadRequest(int child_id, int request_id) {
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+
+  // This balances the pause in DownloadResourceHandler::OnResponseStarted.
+  resource_dispatcher_host_->PauseRequest(child_id, request_id, false);
+}
+
 DownloadFile* DownloadFileManager::GetDownloadFile(int id) {
   DownloadFileMap::iterator it = downloads_.find(id);
   return it == downloads_.end() ? NULL : it->second;
diff --git a/chrome/browser/download/download_file_manager.h b/chrome/browser/download/download_file_manager.h
index d51d35f..9b909d9 100644
--- a/chrome/browser/download/download_file_manager.h
+++ b/chrome/browser/download/download_file_manager.h
@@ -130,6 +130,10 @@ class DownloadFileManager
   void CreateDownloadFile(DownloadCreateInfo* info,
                           DownloadManager* download_manager);
 
+  // Tells the ResourceDispatcherHost to resume a download request
+  // that was paused to wait for the on-disk file to be created.
+  void ResumeDownloadRequest(int child_id, int request_id);
+
   // Called only on the download thread.
   DownloadFile* GetDownloadFile(int id);
 
-- 
cgit v1.1