summaryrefslogtreecommitdiffstats
path: root/chrome/browser/download
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-26 18:47:05 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-26 18:47:05 +0000
commitea0b6116e94fb7bbedac074d534ee8c070384ecc (patch)
tree11304c682f4bba6e6197f6c51717198da549401b /chrome/browser/download
parent0b6af7774219645c8c62efde75b9e38fc8451691 (diff)
downloadchromium_src-ea0b6116e94fb7bbedac074d534ee8c070384ecc.zip
chromium_src-ea0b6116e94fb7bbedac074d534ee8c070384ecc.tar.gz
chromium_src-ea0b6116e94fb7bbedac074d534ee8c070384ecc.tar.bz2
Fix save complete web page crasher
Repeatedly saving a page may cause a crash. See the bug for a full discussion. This fixes that by making sure the curretn SavePackage is the same one that called into SaveFileManager::RenameAllFiles. One more hack on the giant, teetering pile of hacks that is the SavePackage system. Can't hurt, right? BUG=42454 TEST=see bug Review URL: http://codereview.chromium.org/1729016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45599 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/download')
-rw-r--r--chrome/browser/download/save_file_manager.cc12
-rw-r--r--chrome/browser/download/save_file_manager.h7
-rw-r--r--chrome/browser/download/save_package.cc9
-rw-r--r--chrome/browser/download/save_package.h18
4 files changed, 28 insertions, 18 deletions
diff --git a/chrome/browser/download/save_file_manager.cc b/chrome/browser/download/save_file_manager.cc
index a985071..5d9ad43 100644
--- a/chrome/browser/download/save_file_manager.cc
+++ b/chrome/browser/download/save_file_manager.cc
@@ -473,7 +473,8 @@ void SaveFileManager::RenameAllFiles(
const FinalNameList& final_names,
const FilePath& resource_dir,
int render_process_id,
- int render_view_id) {
+ int render_view_id,
+ int save_package_id) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
if (!resource_dir.empty() && !file_util::PathExists(resource_dir))
@@ -495,20 +496,19 @@ void SaveFileManager::RenameAllFiles(
ChromeThread::UI, FROM_HERE,
NewRunnableMethod(
this, &SaveFileManager::OnFinishSavePageJob, render_process_id,
- render_view_id));
+ render_view_id, save_package_id));
}
void SaveFileManager::OnFinishSavePageJob(int render_process_id,
- int render_view_id) {
+ int render_view_id,
+ int save_package_id) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
SavePackage* save_package =
GetSavePackageFromRenderIds(render_process_id, render_view_id);
- if (save_package) {
- // save_package is null if save was canceled.
+ if (save_package && save_package->id() == save_package_id)
save_package->Finish();
- }
}
void SaveFileManager::RemoveSavedFileFromFileMap(
diff --git a/chrome/browser/download/save_file_manager.h b/chrome/browser/download/save_file_manager.h
index 24684ff..44597d5 100644
--- a/chrome/browser/download/save_file_manager.h
+++ b/chrome/browser/download/save_file_manager.h
@@ -136,7 +136,8 @@ class SaveFileManager
const FinalNameList& final_names,
const FilePath& resource_dir,
int render_process_id,
- int render_view_id);
+ int render_view_id,
+ int save_package_id);
// When the user cancels the saving, we need to remove all remaining saved
// files of this page saving job from save_file_map_.
@@ -190,7 +191,9 @@ class SaveFileManager
// map:(url, SavePackage) to find the request and remove it.
void OnErrorFinished(GURL save_url, int tab_id);
// Notifies SavePackage that the whole page saving job is finished.
- void OnFinishSavePageJob(int render_process_id, int render_view_id);
+ void OnFinishSavePageJob(int render_process_id,
+ int render_view_id,
+ int save_package_id);
// Notifications sent from the UI thread and run on the file thread.
diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc
index d58cc48..c276517 100644
--- a/chrome/browser/download/save_package.cc
+++ b/chrome/browser/download/save_package.cc
@@ -68,6 +68,9 @@ struct SavePackageParam {
namespace {
+// A counter for uniquely identifying each save package.
+int g_save_package_id = 0;
+
// Default name which will be used when we can not get proper name from
// resource URL.
const FilePath::CharType kDefaultSaveName[] =
@@ -165,6 +168,7 @@ SavePackage::SavePackage(TabContents* web_content,
all_save_items_count_(0),
wait_state_(INITIALIZE),
tab_id_(web_content->GetRenderProcessHost()->id()),
+ unique_id_(g_save_package_id++),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
DCHECK(web_content);
const GURL& current_page_url = GetUrlToBeSaved();
@@ -190,6 +194,7 @@ SavePackage::SavePackage(TabContents* tab_contents)
all_save_items_count_(0),
wait_state_(INITIALIZE),
tab_id_(tab_contents->GetRenderProcessHost()->id()),
+ unique_id_(g_save_package_id++),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
const GURL& current_page_url = GetUrlToBeSaved();
@@ -216,6 +221,7 @@ SavePackage::SavePackage(TabContents* tab_contents,
all_save_items_count_(0),
wait_state_(INITIALIZE),
tab_id_(0),
+ unique_id_(g_save_package_id++),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
DCHECK(!saved_main_file_path_.empty() &&
saved_main_file_path_.value().length() <= kMaxFilePathLength);
@@ -642,7 +648,8 @@ void SavePackage::CheckFinish() {
final_names,
dir,
tab_contents_->GetRenderProcessHost()->id(),
- tab_contents_->render_view_host()->routing_id()));
+ tab_contents_->render_view_host()->routing_id(),
+ id()));
}
// Successfully finished all items of this SavePackage.
diff --git a/chrome/browser/download/save_package.h b/chrome/browser/download/save_package.h
index 67db2bd..8d842d7 100644
--- a/chrome/browser/download/save_package.h
+++ b/chrome/browser/download/save_package.h
@@ -118,15 +118,11 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>,
// Show or Open a saved page via the Windows shell.
void ShowDownloadInShell();
- bool canceled() { return user_canceled_ || disk_error_occurred_; }
-
- // Accessor
- bool finished() { return finished_; }
- SavePackageType save_type() { return save_type_; }
-
- // Since for one tab, it can only have one SavePackage in same time.
- // Now we actually use render_process_id as tab's unique id.
+ bool canceled() const { return user_canceled_ || disk_error_occurred_; }
+ bool finished() const { return finished_; }
+ SavePackageType save_type() const { return save_type_; }
int tab_id() const { return tab_id_; }
+ int id() const { return unique_id_; }
void GetSaveInfo();
void ContinueGetSaveInfo(FilePath save_dir);
@@ -326,9 +322,13 @@ class SavePackage : public base::RefCountedThreadSafe<SavePackage>,
// from outside.
WaitState wait_state_;
- // Unique id for this SavePackage.
+ // Since for one tab, it can only have one SavePackage in same time.
+ // Now we actually use render_process_id as tab's unique id.
const int tab_id_;
+ // Unique ID for this SavePackage.
+ const int unique_id_;
+
// For managing select file dialogs.
scoped_refptr<SelectFileDialog> select_file_dialog_;