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

Unified Diff: net/base/upload_file_element_reader.cc

Issue 10910268: net: Make UploadDataStream::Read() asynchronous (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 8 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
« no previous file with comments | « net/base/upload_file_element_reader.h ('k') | net/base/upload_file_element_reader_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/upload_file_element_reader.cc
diff --git a/net/base/upload_file_element_reader.cc b/net/base/upload_file_element_reader.cc
index 5cb143984c9e39f6bff1dcbcaf4185ed65fb4ab1..0c1d08bf4e11ed710205d48b71949ad611ee9732 100644
--- a/net/base/upload_file_element_reader.cc
+++ b/net/base/upload_file_element_reader.cc
@@ -7,9 +7,11 @@
#include "base/bind.h"
#include "base/file_util.h"
#include "base/location.h"
+#include "base/task_runner_util.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/worker_pool.h"
#include "net/base/file_stream.h"
+#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
namespace net {
@@ -20,14 +22,13 @@ namespace {
// UploadFileElementReader::GetContentLength() when set to non-zero.
uint64 overriding_content_length = 0;
-// This method is used to implement Init().
-void InitInternal(const FilePath& path,
- uint64 range_offset,
- uint64 range_length,
- const base::Time& expected_modification_time,
- scoped_ptr<FileStream>* out_file_stream,
- uint64* out_content_length,
- int* out_result) {
+// This function is used to implement Init().
+int InitInternal(const FilePath& path,
+ uint64 range_offset,
+ uint64 range_length,
+ const base::Time& expected_modification_time,
+ scoped_ptr<FileStream>* out_file_stream,
+ uint64* out_content_length) {
scoped_ptr<FileStream> file_stream(new FileStream(NULL));
int64 rv = file_stream->OpenSync(
path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
@@ -64,12 +65,38 @@ void InitInternal(const FilePath& path,
base::PlatformFileInfo info;
if (file_util::GetFileInfo(path, &info) &&
expected_modification_time.ToTimeT() != info.last_modified.ToTimeT()) {
- *out_result = ERR_UPLOAD_FILE_CHANGED;
- return;
+ return ERR_UPLOAD_FILE_CHANGED;
}
}
- *out_result = OK;
+ return OK;
+}
+
+// This function is used to implement Read().
+int ReadInternal(scoped_refptr<IOBuffer> buf,
+ int buf_length,
+ uint64 bytes_remaining,
+ FileStream* file_stream) {
+ DCHECK_LT(0, buf_length);
+
+ const uint64 num_bytes_to_read =
+ std::min(bytes_remaining, static_cast<uint64>(buf_length));
+
+ if (num_bytes_to_read > 0) {
+ int num_bytes_consumed = 0;
+ // file_stream is NULL if the target file is missing or not readable.
+ if (file_stream) {
+ num_bytes_consumed = file_stream->ReadSync(buf->data(),
+ num_bytes_to_read);
+ }
+ if (num_bytes_consumed <= 0) {
+ // If there's less data to read than we initially observed, then
+ // pad with zero. Otherwise the server will hang waiting for the
+ // rest of the data.
+ memset(buf->data(), 0, num_bytes_to_read);
+ }
+ }
+ return num_bytes_to_read;
}
} // namespace
@@ -100,8 +127,8 @@ UploadFileElementReader::~UploadFileElementReader() {
int UploadFileElementReader::Init(const CompletionCallback& callback) {
scoped_ptr<FileStream>* file_stream = new scoped_ptr<FileStream>;
uint64* content_length = new uint64;
- int* result = new int;
- const bool posted = base::WorkerPool::PostTaskAndReply(
+ const bool posted = base::PostTaskAndReplyWithResult(
+ base::WorkerPool::GetTaskRunner(true /* task_is_slow */),
FROM_HERE,
base::Bind(&InitInternal,
path_,
@@ -109,15 +136,12 @@ int UploadFileElementReader::Init(const CompletionCallback& callback) {
range_length_,
expected_modification_time_,
file_stream,
- content_length,
- result),
+ content_length),
base::Bind(&UploadFileElementReader::OnInitCompleted,
weak_ptr_factory_.GetWeakPtr(),
base::Owned(file_stream),
base::Owned(content_length),
- base::Owned(result),
- callback),
- true /* task_is_slow */);
+ callback));
DCHECK(posted);
return ERR_IO_PENDING;
}
@@ -128,10 +152,10 @@ int UploadFileElementReader::InitSync() {
scoped_ptr<FileStream> file_stream;
uint64 content_length = 0;
- int result = OK;
- InitInternal(path_, range_offset_, range_length_, expected_modification_time_,
- &file_stream, &content_length, &result);
- OnInitCompleted(&file_stream, &content_length, &result, CompletionCallback());
+ const int result = InitInternal(path_, range_offset_, range_length_,
+ expected_modification_time_,
+ &file_stream, &content_length);
+ OnInitCompleted(&file_stream, &content_length, CompletionCallback(), result);
return result;
}
@@ -145,44 +169,64 @@ uint64 UploadFileElementReader::BytesRemaining() const {
return bytes_remaining_;
}
-int UploadFileElementReader::ReadSync(char* buf, int buf_length) {
+int UploadFileElementReader::Read(IOBuffer* buf,
+ int buf_length,
+ const CompletionCallback& callback) {
+ DCHECK(!callback.is_null());
+
+ if (BytesRemaining() == 0)
+ return 0;
+
+ // Save the value of file_stream_.get() before base::Passed() invalidates it.
+ FileStream* file_stream_ptr = file_stream_.get();
+ // Pass the ownership of file_stream_ to the worker pool to safely perform
+ // operation even when |this| is destructed before the read completes.
+ const bool posted = base::PostTaskAndReplyWithResult(
+ base::WorkerPool::GetTaskRunner(true /* task_is_slow */),
+ FROM_HERE,
+ base::Bind(&ReadInternal,
+ scoped_refptr<IOBuffer>(buf),
+ buf_length,
+ BytesRemaining(),
+ file_stream_ptr),
+ base::Bind(&UploadFileElementReader::OnReadCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(&file_stream_),
+ callback));
+ DCHECK(posted);
+ return ERR_IO_PENDING;
+}
+
+int UploadFileElementReader::ReadSync(IOBuffer* buf, int buf_length) {
// Temporarily allow until fix: http://crbug.com/72001.
base::ThreadRestrictions::ScopedAllowIO allow_io;
- DCHECK_LT(0, buf_length);
-
- const uint64 num_bytes_to_read =
- static_cast<int>(std::min(BytesRemaining(),
- static_cast<uint64>(buf_length)));
- if (num_bytes_to_read > 0) {
- int num_bytes_consumed = 0;
- // file_stream_ is NULL if the target file is
- // missing or not readable.
- if (file_stream_.get()) {
- num_bytes_consumed =
- file_stream_->ReadSync(buf, num_bytes_to_read);
- }
- if (num_bytes_consumed <= 0) {
- // If there's less data to read than we initially observed, then
- // pad with zero. Otherwise the server will hang waiting for the
- // rest of the data.
- memset(buf, 0, num_bytes_to_read);
- }
- }
- DCHECK_GE(bytes_remaining_, num_bytes_to_read);
- bytes_remaining_ -= num_bytes_to_read;
- return num_bytes_to_read;
+ const int result = ReadInternal(buf, buf_length, BytesRemaining(),
+ file_stream_.get());
+ OnReadCompleted(file_stream_.Pass(), CompletionCallback(), result);
+ return result;
}
void UploadFileElementReader::OnInitCompleted(
scoped_ptr<FileStream>* file_stream,
uint64* content_length,
- int* result,
- const CompletionCallback& callback) {
+ const CompletionCallback& callback,
+ int result) {
file_stream_.swap(*file_stream);
content_length_ = *content_length;
bytes_remaining_ = GetContentLength();
if (!callback.is_null())
- callback.Run(*result);
+ callback.Run(result);
+}
+
+void UploadFileElementReader::OnReadCompleted(
+ scoped_ptr<FileStream> file_stream,
+ const CompletionCallback& callback,
+ int result) {
+ file_stream_.swap(file_stream);
+ DCHECK_GE(static_cast<int>(bytes_remaining_), result);
+ bytes_remaining_ -= result;
+ if (!callback.is_null())
+ callback.Run(result);
}
UploadFileElementReader::ScopedOverridingContentLengthForTests::
« no previous file with comments | « net/base/upload_file_element_reader.h ('k') | net/base/upload_file_element_reader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698