summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/gdata/drive_uploader.cc52
-rw-r--r--chrome/browser/chromeos/gdata/drive_uploader.h16
2 files changed, 31 insertions, 37 deletions
diff --git a/chrome/browser/chromeos/gdata/drive_uploader.cc b/chrome/browser/chromeos/gdata/drive_uploader.cc
index 790ee1d..c02f0b0 100644
--- a/chrome/browser/chromeos/gdata/drive_uploader.cc
+++ b/chrome/browser/chromeos/gdata/drive_uploader.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/stl_util.h"
#include "base/string_number_conversions.h"
#include "chrome/browser/chromeos/gdata/drive_service_interface.h"
#include "chrome/browser/google_apis/gdata_wapi_parser.h"
@@ -37,6 +38,8 @@ DriveUploader::DriveUploader(DriveServiceInterface* drive_service)
}
DriveUploader::~DriveUploader() {
+ STLDeleteContainerPairSecondPointers(pending_uploads_.begin(),
+ pending_uploads_.end());
}
int DriveUploader::UploadNewFile(
@@ -128,7 +131,7 @@ int DriveUploader::StartUploadFile(
DVLOG(1) << "Uploading file: " << info->DebugString();
// Create a FileStream to make sure the file can be opened successfully.
- info->file_stream = new net::FileStream(NULL);
+ info->file_stream.reset(new net::FileStream(NULL));
// Create buffer to hold upload data. The full file size may not be known at
// this point, so it may not be appropriate to use info->file_size.
@@ -285,16 +288,14 @@ void DriveUploader::OpenCompletionCallback(FileOpenType open_type,
upload_file_info->should_retry_file_open = !exceeded_max_attempts;
}
if (!upload_file_info->should_retry_file_open) {
- UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info),
- DRIVE_FILE_ERROR_NOT_FOUND);
+ UploadFailed(upload_file_info, DRIVE_FILE_ERROR_NOT_FOUND);
return;
}
} else {
// Open succeeded, initiate the upload.
upload_file_info->should_retry_file_open = false;
if (upload_file_info->initial_upload_location.is_empty()) {
- UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info),
- DRIVE_FILE_ERROR_ABORT);
+ UploadFailed(upload_file_info, DRIVE_FILE_ERROR_ABORT);
return;
}
drive_service_->InitiateUpload(
@@ -341,8 +342,7 @@ void DriveUploader::OnUploadLocationReceived(
if (code != HTTP_SUCCESS) {
// TODO(achuith): Handle error codes from Google Docs server.
- UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info),
- DRIVE_FILE_ERROR_ABORT);
+ UploadFailed(upload_file_info, DRIVE_FILE_ERROR_ABORT);
return;
}
@@ -470,10 +470,6 @@ void DriveUploader::OnResumeUploadResponseReceived(
DVLOG(1) << "Successfully created uploaded file=["
<< upload_file_info->title;
- // Remove |upload_id| from the UploadFileInfoMap. The UploadFileInfo object
- // will be deleted upon completion of completion_callback.
- RemoveUpload(upload_id);
-
// Done uploading.
upload_file_info->entry = entry.Pass();
if (!upload_file_info->completion_callback.is_null()) {
@@ -483,6 +479,9 @@ void DriveUploader::OnResumeUploadResponseReceived(
upload_file_info->file_path,
upload_file_info->entry.Pass());
}
+
+ // This will delete |upload_file_info|.
+ RemoveUpload(scoped_ptr<UploadFileInfo>(upload_file_info));
return;
}
@@ -500,7 +499,7 @@ void DriveUploader::OnResumeUploadResponseReceived(
<< ", end_range_received=" << response.end_range_received
<< ", expected end range=" << upload_file_info->end_range;
UploadFailed(
- scoped_ptr<UploadFileInfo>(upload_file_info),
+ upload_file_info,
response.code == HTTP_FORBIDDEN ?
DRIVE_FILE_ERROR_NO_SPACE : DRIVE_FILE_ERROR_ABORT);
return;
@@ -514,27 +513,26 @@ void DriveUploader::OnResumeUploadResponseReceived(
UploadNextChunk(upload_file_info);
}
-void DriveUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info,
+void DriveUploader::UploadFailed(UploadFileInfo* upload_file_info,
DriveFileError error) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- RemoveUpload(upload_file_info->upload_id);
-
LOG(ERROR) << "Upload failed " << upload_file_info->DebugString();
- // This is subtle but we should take the callback reference before
- // calling upload_file_info.Pass(). Otherwise, it'll crash.
- const UploadCompletionCallback& callback =
- upload_file_info->completion_callback;
- if (!callback.is_null())
- callback.Run(error,
+
+ if (!upload_file_info->completion_callback.is_null())
+ upload_file_info->completion_callback.Run(
+ error,
upload_file_info->drive_path,
upload_file_info->file_path,
upload_file_info->entry.Pass());
+
+ // This will delete |upload_file_info|.
+ RemoveUpload(scoped_ptr<UploadFileInfo>(upload_file_info));
}
-void DriveUploader::RemoveUpload(int upload_id) {
+void DriveUploader::RemoveUpload(scoped_ptr<UploadFileInfo> upload_file_info) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- pending_uploads_.erase(upload_id);
+ pending_uploads_.erase(upload_file_info->upload_id);
}
DriveUploader::UploadFileInfo::UploadFileInfo()
@@ -552,13 +550,7 @@ DriveUploader::UploadFileInfo::UploadFileInfo()
num_file_open_tries(0) {
}
-DriveUploader::UploadFileInfo::~UploadFileInfo() {
- // The file stream is closed by the destructor asynchronously.
- if (file_stream) {
- delete file_stream;
- file_stream = NULL;
- }
-}
+DriveUploader::UploadFileInfo::~UploadFileInfo() { }
int64 DriveUploader::UploadFileInfo::SizeRemaining() const {
DCHECK(file_size > end_range);
diff --git a/chrome/browser/chromeos/gdata/drive_uploader.h b/chrome/browser/chromeos/gdata/drive_uploader.h
index 4cdb32c..2d8cbae 100644
--- a/chrome/browser/chromeos/gdata/drive_uploader.h
+++ b/chrome/browser/chromeos/gdata/drive_uploader.h
@@ -162,7 +162,7 @@ class DriveUploader : public DriveUploaderInterface {
// to extend a generic stream.
//
// For opening and reading from physical file.
- net::FileStream* file_stream;
+ scoped_ptr<net::FileStream> file_stream;
scoped_refptr<net::IOBuffer> buf; // Holds current content to be uploaded.
// Size of |buf|, max is 512KB; Google Docs requires size of each upload
// chunk to be a multiple of 512KB.
@@ -236,16 +236,16 @@ class DriveUploader : public DriveUploaderInterface {
void InitiateUpload(UploadFileInfo* uploader_file_info);
// Handle failed uploads.
- void UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info,
+ void UploadFailed(UploadFileInfo* upload_file_info,
DriveFileError error);
- // Removes |upload_id| from UploadFileInfoMap |pending_uploads_|.
- // Note that this does not delete the UploadFileInfo object itself,
- // because it may still be in use by an asynchronous function.
- void RemoveUpload(int upload_id);
+ // Removes |upload_file_info| from UploadFileInfoMap |pending_uploads_|.
+ // After its removal from the map, |upload_file_info| is deleted.
+ void RemoveUpload(scoped_ptr<UploadFileInfo> upload_file_info);
// Starts uploading a file with |upload_file_info|. Returns a new upload
- // ID assigned to |upload_file_info|.
+ // ID assigned to |upload_file_info|. |upload_file_info| is added to
+ // |pending_uploads_map_|.
int StartUploadFile(scoped_ptr<UploadFileInfo> upload_file_info);
// Pointers to DriveServiceInterface object owned by DriveSystemService.
@@ -256,6 +256,8 @@ class DriveUploader : public DriveUploaderInterface {
int next_upload_id_; // id counter.
typedef std::map<int, UploadFileInfo*> UploadFileInfoMap;
+ // Upload file infos added to the map are deleted either in |RemoveUpload| or
+ // in DriveUploader dtor (i.e. we can assume |this| takes their ownership).
UploadFileInfoMap pending_uploads_;
// Note: This should remain the last member so it'll be destroyed and