Index: webkit/fileapi/file_system_operation.cc |
diff --git a/webkit/fileapi/file_system_operation.cc b/webkit/fileapi/file_system_operation.cc |
index 663bace3563faeb7f232772fd0ad9053b394e57e..da2a94df6526cf98e52a26766c15e92420ff101e 100644 |
--- a/webkit/fileapi/file_system_operation.cc |
+++ b/webkit/fileapi/file_system_operation.cc |
@@ -290,13 +290,14 @@ void FileSystemOperation::Write( |
file_writer_delegate_.reset(new FileWriterDelegate( |
this, src_path_, offset)); |
set_write_callback(callback); |
- blob_request_.reset( |
+ scoped_ptr<net::URLRequest> blob_request( |
new net::URLRequest(blob_url, file_writer_delegate_.get())); |
- blob_request_->set_context(url_request_context); |
+ blob_request->set_context(url_request_context); |
GetUsageAndQuotaThenRunTask( |
src_path_.origin(), src_path_.type(), |
- base::Bind(&FileSystemOperation::DoWrite, base::Unretained(this)), |
+ base::Bind(&FileSystemOperation::DoWrite, weak_factory_.GetWeakPtr(), |
+ base::Passed(&blob_request)), |
base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 0, true)); |
} |
@@ -389,23 +390,23 @@ void FileSystemOperation::OpenFile(const GURL& path_url, |
void FileSystemOperation::Cancel(const StatusCallback& cancel_callback) { |
if (file_writer_delegate_.get()) { |
DCHECK_EQ(kOperationWrite, pending_operation_); |
+ |
// Writes are done without proxying through FileUtilProxy after the initial |
// opening of the PlatformFile. All state changes are done on this thread, |
- // so we're guaranteed to be able to shut down atomically. We do need to |
- // check that the file has been opened [which means the blob_request_ has |
- // been created], so we know how much we need to do. |
- if (blob_request_.get()) |
- // This halts any calls to file_writer_delegate_ from blob_request_. |
- blob_request_->Cancel(); |
+ // so we're guaranteed to be able to shut down atomically. |
+ const bool delete_now = file_writer_delegate_->Cancel(); |
if (!write_callback_.is_null()) { |
// Notify the failure status to the ongoing operation's callback. |
write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false); |
- // Do not delete this FileSystemOperation object yet. As a result of |
- // abort, this->DidWrite is called later and there we delete this object. |
} |
cancel_callback.Run(base::PLATFORM_FILE_OK); |
write_callback_.Reset(); |
+ |
+ if (delete_now) { |
+ delete this; |
+ return; |
+ } |
} else { |
DCHECK_EQ(kOperationTruncate, pending_operation_); |
// We're cancelling a truncate operation, but we can't actually stop it |
@@ -450,7 +451,8 @@ FileSystemOperation::FileSystemOperation( |
src_util_(NULL), |
dest_util_(NULL), |
peer_handle_(base::kNullProcessHandle), |
- pending_operation_(kOperationNone) { |
+ pending_operation_(kOperationNone), |
+ weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
} |
void FileSystemOperation::GetUsageAndQuotaThenRunTask( |
@@ -540,15 +542,21 @@ void FileSystemOperation::DoMove(const StatusCallback& callback) { |
base::Owned(this), callback)); |
} |
-void FileSystemOperation::DoWrite() { |
+void FileSystemOperation::DoWrite(scoped_ptr<net::URLRequest> blob_request) { |
int file_flags = base::PLATFORM_FILE_OPEN | |
base::PLATFORM_FILE_WRITE | |
base::PLATFORM_FILE_ASYNC; |
+ // We may get deleted on the way so allocate a new operation context |
+ // to keep it alive. |
+ FileSystemOperationContext* write_context = new FileSystemOperationContext( |
+ operation_context_); |
FileSystemFileUtilProxy::CreateOrOpen( |
- &operation_context_, src_util_, src_path_, file_flags, |
+ write_context, src_util_, src_path_, file_flags, |
base::Bind(&FileSystemOperation::OnFileOpenedForWrite, |
- base::Unretained(this))); |
+ weak_factory_.GetWeakPtr(), |
+ base::Passed(&blob_request), |
+ base::Owned(write_context))); |
} |
void FileSystemOperation::DoTruncate(const StatusCallback& callback, |
@@ -664,6 +672,8 @@ void FileSystemOperation::DidOpenFile( |
} |
void FileSystemOperation::OnFileOpenedForWrite( |
+ scoped_ptr<net::URLRequest> blob_request, |
+ FileSystemOperationContext* unused, |
base::PlatformFileError rv, |
base::PassPlatformFile file, |
bool created) { |
@@ -673,7 +683,7 @@ void FileSystemOperation::OnFileOpenedForWrite( |
delete this; |
return; |
} |
- file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); |
+ file_writer_delegate_->Start(file.ReleaseValue(), blob_request.Pass()); |
} |
base::PlatformFileError FileSystemOperation::SetUpFileSystemPath( |