net: Move write flush responsiblity from URLFetcherResponseWriter to URLFetcherCore

URLFetcherCore is now responsible to write all data stored in |buffer_|.

BUG=126753
TEST=net_unittests

Review URL: https://chromiumcodereview.appspot.com/15711003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202003 0039d316-1c4b-4281-b951-d872f2087c98
parent b1672516
......@@ -431,9 +431,7 @@ void URLFetcherCore::OnReadCompleted(URLRequest* request,
InformDelegateDownloadProgress();
InformDelegateDownloadDataIfNecessary(bytes_read);
const int result = response_writer_->Write(
buffer_, bytes_read,
base::Bind(&URLFetcherCore::DidWriteBuffer, this));
const int result = WriteBuffer(new DrainableIOBuffer(buffer_, bytes_read));
if (result < 0) {
// Write failed or waiting for write completion.
if (result == ERR_IO_PENDING)
......@@ -822,14 +820,35 @@ void URLFetcherCore::CompleteAddingUploadDataChunk(
is_last_chunk);
}
void URLFetcherCore::DidWriteBuffer(int result) {
if (result < 0) {
int URLFetcherCore::WriteBuffer(scoped_refptr<DrainableIOBuffer> data) {
while (data->BytesRemaining() > 0) {
const int result = response_writer_->Write(
data, data->BytesRemaining(),
base::Bind(&URLFetcherCore::DidWriteBuffer, this, data));
if (result < 0)
return result;
data->DidConsume(result);
}
return OK;
}
void URLFetcherCore::DidWriteBuffer(scoped_refptr<DrainableIOBuffer> data,
int result) {
if (result >= 0) { // Continue writing.
data->DidConsume(result);
result = WriteBuffer(data);
if (result == ERR_IO_PENDING)
return;
}
if (result < 0) { // Handle errors.
delegate_task_runner_->PostTask(
FROM_HERE,
base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, this));
return;
}
// Finished writing buffer_. Read some more.
DCHECK_EQ(0, data->BytesRemaining());
ReadResponse();
}
......
......@@ -28,6 +28,7 @@ class SingleThreadTaskRunner;
} // namespace base
namespace net {
class DrainableIOBuffer;
class HttpResponseHeaders;
class IOBuffer;
class URLFetcherDelegate;
......@@ -193,8 +194,13 @@ class URLFetcherCore
void CompleteAddingUploadDataChunk(const std::string& data,
bool is_last_chunk);
// Handles the result of WriteBuffer.
void DidWriteBuffer(int result);
// Writes all bytes stored in |data| with |response_writer_|.
// Returns OK if all bytes in |data| get written synchronously. Otherwise,
// returns ERR_IO_PENDING or a network error code.
int WriteBuffer(scoped_refptr<DrainableIOBuffer> data);
// Used to implement WriteBuffer().
void DidWriteBuffer(scoped_refptr<DrainableIOBuffer> data, int result);
// Read response bytes from the request.
void ReadResponse();
......
......@@ -91,8 +91,15 @@ int URLFetcherFileWriter::Write(IOBuffer* buffer,
DCHECK(file_stream_);
DCHECK(owns_file_);
ContinueWrite(new DrainableIOBuffer(buffer, num_bytes), callback, OK);
return ERR_IO_PENDING;
int result = file_stream_->Write(buffer, num_bytes,
base::Bind(&URLFetcherFileWriter::DidWrite,
weak_factory_.GetWeakPtr(),
callback));
if (result < 0 && result != ERR_IO_PENDING) {
error_code_ = result;
CloseAndDeleteFile();
}
return result;
}
int URLFetcherFileWriter::Finish(const CompletionCallback& callback) {
......@@ -100,33 +107,13 @@ int URLFetcherFileWriter::Finish(const CompletionCallback& callback) {
return OK;
}
void URLFetcherFileWriter::ContinueWrite(
scoped_refptr<DrainableIOBuffer> buffer,
const CompletionCallback& callback,
void URLFetcherFileWriter::DidWrite(const CompletionCallback& callback,
int result) {
// |file_stream_| should be alive when write is in progress.
DCHECK(file_stream_);
if (result < 0) {
error_code_ = result;
CloseAndDeleteFile();
callback.Run(result);
return;
}
total_bytes_written_ += result;
buffer->DidConsume(result);
if (buffer->BytesRemaining() > 0) {
file_stream_->Write(buffer, buffer->BytesRemaining(),
base::Bind(&URLFetcherFileWriter::ContinueWrite,
weak_factory_.GetWeakPtr(),
buffer,
callback));
} else {
// Finished writing buffer to the file.
callback.Run(buffer->size());
}
callback.Run(result);
}
void URLFetcherFileWriter::DisownFile() {
......
......@@ -84,11 +84,8 @@ class URLFetcherFileWriter : public URLFetcherResponseWriter {
const CompletionCallback& callback) OVERRIDE;
virtual int Finish(const CompletionCallback& callback) OVERRIDE;
// Called when a write has been done. Continues writing if there are more
// bytes to write. Otherwise, runs |callback|.
void ContinueWrite(scoped_refptr<DrainableIOBuffer> buffer,
const CompletionCallback& callback,
int result);
// Called when a write has been done.
void DidWrite(const CompletionCallback& callback, int result);
// Drops ownership of the file at |file_path_|.
// This class will not delete it or write to it again.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment