Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Unified Diff: net/url_request/url_fetcher_response_writer.cc

Issue 2425673006: Make URLFetcherFileWriter::Finish() skip closing file when there is an error (Closed)
Patch Set: Fix test Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/url_request/url_fetcher_response_writer.cc
diff --git a/net/url_request/url_fetcher_response_writer.cc b/net/url_request/url_fetcher_response_writer.cc
index fcc8cbf38ffc4129245cd2cf2ceb63466e112a67..3286e675ca1819c3a13bd2bc84953b9c56360e74 100644
--- a/net/url_request/url_fetcher_response_writer.cc
+++ b/net/url_request/url_fetcher_response_writer.cc
@@ -4,6 +4,7 @@
#include "net/url_request/url_fetcher_response_writer.h"
+#include "base/callback_helpers.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/sequenced_task_runner.h"
@@ -40,7 +41,8 @@ int URLFetcherStringWriter::Write(IOBuffer* buffer,
return num_bytes;
}
-int URLFetcherStringWriter::Finish(const CompletionCallback& callback) {
+int URLFetcherStringWriter::Finish(int net_error,
+ const CompletionCallback& callback) {
// Do nothing.
return OK;
}
@@ -64,9 +66,12 @@ URLFetcherFileWriter::~URLFetcherFileWriter() {
}
int URLFetcherFileWriter::Initialize(const CompletionCallback& callback) {
+ DCHECK(!callback_);
+
file_stream_.reset(new FileStream(file_task_runner_));
int result = ERR_IO_PENDING;
+ owns_file_ = true;
if (file_path_.empty()) {
base::FilePath* temp_file_path = new base::FilePath;
base::PostTaskAndReplyWithResult(
@@ -75,18 +80,22 @@ int URLFetcherFileWriter::Initialize(const CompletionCallback& callback) {
base::Bind(&base::CreateTemporaryFile, temp_file_path),
base::Bind(&URLFetcherFileWriter::DidCreateTempFile,
weak_factory_.GetWeakPtr(),
- callback,
base::Owned(temp_file_path)));
} else {
- result = file_stream_->Open(
- file_path_,
- base::File::FLAG_WRITE | base::File::FLAG_ASYNC |
- base::File::FLAG_CREATE_ALWAYS,
- base::Bind(&URLFetcherFileWriter::DidOpenFile,
- weak_factory_.GetWeakPtr(),
- callback));
+ result = file_stream_->Open(file_path_, base::File::FLAG_WRITE |
+ base::File::FLAG_ASYNC |
+ base::File::FLAG_CREATE_ALWAYS,
+ base::Bind(&URLFetcherFileWriter::OnIOCompleted,
+ weak_factory_.GetWeakPtr()));
DCHECK_NE(OK, result);
}
+
+ if (result == ERR_IO_PENDING) {
+ callback_ = callback;
+ return result;
+ }
+ if (result < 0)
+ CloseAndDeleteFile();
return result;
}
@@ -95,25 +104,44 @@ int URLFetcherFileWriter::Write(IOBuffer* buffer,
const CompletionCallback& callback) {
DCHECK(file_stream_);
DCHECK(owns_file_);
+ DCHECK(!callback_);
- int result = file_stream_->Write(buffer, num_bytes,
- base::Bind(&URLFetcherFileWriter::DidWrite,
- weak_factory_.GetWeakPtr(),
- callback));
- if (result < 0 && result != ERR_IO_PENDING)
+ int result = file_stream_->Write(
+ buffer, num_bytes, base::Bind(&URLFetcherFileWriter::OnIOCompleted,
+ weak_factory_.GetWeakPtr()));
+ if (result == ERR_IO_PENDING) {
+ callback_ = callback;
+ return result;
+ }
+ if (result < 0)
CloseAndDeleteFile();
-
return result;
}
-int URLFetcherFileWriter::Finish(const CompletionCallback& callback) {
+int URLFetcherFileWriter::Finish(int net_error,
+ const CompletionCallback& callback) {
+ DCHECK_NE(ERR_IO_PENDING, net_error);
+
+ // If an error occurred, simply delete the file after any pending operation
+ // is done. Do not call file_stream_->Close() because there might be an
+ // operation pending. See crbug.com/487732.
+ if (net_error < 0) {
+ // Cancel callback and invalid weak ptrs so as to cancel any posted task.
+ callback_.Reset();
+ weak_factory_.InvalidateWeakPtrs();
+ CloseAndDeleteFile();
+ return OK;
+ }
+ DCHECK(!callback_);
// If the file_stream_ still exists at this point, close it.
if (file_stream_) {
int result = file_stream_->Close(base::Bind(
- &URLFetcherFileWriter::CloseComplete,
- weak_factory_.GetWeakPtr(), callback));
- if (result != ERR_IO_PENDING)
- file_stream_.reset();
+ &URLFetcherFileWriter::CloseComplete, weak_factory_.GetWeakPtr()));
+ if (result == ERR_IO_PENDING) {
+ callback_ = callback;
+ return result;
+ }
+ file_stream_.reset();
return result;
}
return OK;
@@ -131,14 +159,6 @@ void URLFetcherFileWriter::DisownFile() {
owns_file_ = false;
}
-void URLFetcherFileWriter::DidWrite(const CompletionCallback& callback,
- int result) {
- if (result < 0)
- CloseAndDeleteFile();
-
- callback.Run(result);
-}
-
void URLFetcherFileWriter::CloseAndDeleteFile() {
if (!owns_file_)
return;
@@ -151,41 +171,35 @@ void URLFetcherFileWriter::CloseAndDeleteFile() {
false /* recursive */));
}
-void URLFetcherFileWriter::DidCreateTempFile(const CompletionCallback& callback,
- base::FilePath* temp_file_path,
+void URLFetcherFileWriter::DidCreateTempFile(base::FilePath* temp_file_path,
bool success) {
if (!success) {
- callback.Run(ERR_FILE_NOT_FOUND);
+ OnIOCompleted(ERR_FILE_NOT_FOUND);
return;
}
file_path_ = *temp_file_path;
- owns_file_ = true;
const int result = file_stream_->Open(
file_path_,
- base::File::FLAG_WRITE | base::File::FLAG_ASYNC |
- base::File::FLAG_OPEN,
- base::Bind(&URLFetcherFileWriter::DidOpenFile,
- weak_factory_.GetWeakPtr(),
- callback));
+ base::File::FLAG_WRITE | base::File::FLAG_ASYNC | base::File::FLAG_OPEN,
+ base::Bind(&URLFetcherFileWriter::OnIOCompleted,
+ weak_factory_.GetWeakPtr()));
if (result != ERR_IO_PENDING)
- DidOpenFile(callback, result);
+ OnIOCompleted(result);
}
-void URLFetcherFileWriter::DidOpenFile(const CompletionCallback& callback,
- int result) {
- if (result == OK)
- owns_file_ = true;
- else
+void URLFetcherFileWriter::OnIOCompleted(int result) {
+ if (result < OK)
CloseAndDeleteFile();
- callback.Run(result);
+ if (!callback_.is_null())
+ base::ResetAndReturn(&callback_).Run(result);
}
-void URLFetcherFileWriter::CloseComplete(const CompletionCallback& callback,
- int result) {
+void URLFetcherFileWriter::CloseComplete(int result) {
// Destroy |file_stream_| whether or not the close succeeded.
file_stream_.reset();
- callback.Run(result);
+ if (!callback_.is_null())
+ base::ResetAndReturn(&callback_).Run(result);
}
} // namespace net
« no previous file with comments | « net/url_request/url_fetcher_response_writer.h ('k') | net/url_request/url_fetcher_response_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698