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

Side by Side Diff: net/base/upload_file_element_reader.cc

Issue 10913179: net: Make UploadDataStream::Init() asynchronous. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: _ Created 8 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/upload_file_element_reader.h" 5 #include "net/base/upload_file_element_reader.h"
6 6
7 #include "base/bind.h"
7 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/location.h"
8 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
11 #include "base/threading/worker_pool.h"
9 #include "net/base/file_stream.h" 12 #include "net/base/file_stream.h"
10 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
11 14
12 namespace net { 15 namespace net {
13 16
14 namespace { 17 namespace {
15 18
16 // In tests, this value is used to override the return value of 19 // In tests, this value is used to override the return value of
17 // UploadFileElementReader::GetContentLength() when set to non-zero. 20 // UploadFileElementReader::GetContentLength() when set to non-zero.
18 uint64 overriding_content_length = 0; 21 uint64 overriding_content_length = 0;
19 22
23 // This method is used to implement Init().
24 void InitInternal(const FilePath& path,
25 uint64 range_offset,
26 uint64 range_length,
27 const base::Time& expected_modification_time,
28 scoped_ptr<FileStream>* out_file_stream,
29 uint64* out_content_length,
30 int* out_result) {
willchan no longer on Chromium 2012/09/11 19:32:40 Should we add a ThreadRestrictions assertion here
hashimoto 2012/09/11 22:51:31 According to the comment in base/threading/thread_
31 scoped_ptr<FileStream> file_stream(new FileStream(NULL));
32 int64 rv = file_stream->OpenSync(
33 path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
34 if (rv != OK) {
35 // If the file can't be opened, we'll just upload an empty file.
36 DLOG(WARNING) << "Failed to open \"" << path.value()
37 << "\" for reading: " << rv;
38 file_stream.reset();
39 }
40 if (file_stream.get() && range_offset) {
41 rv = file_stream->SeekSync(FROM_BEGIN, range_offset);
42 if (rv < 0) {
43 DLOG(WARNING) << "Failed to seek \"" << path.value()
44 << "\" to offset: " << range_offset << " (" << rv
45 << ")";
46 file_stream->CloseSync();
47 file_stream.reset();
48 }
49 }
50
51 int64 length = 0;
52 if (file_stream.get() &&
53 file_util::GetFileSize(path, &length) &&
54 range_offset < static_cast<uint64>(length)) {
55 // Compensate for the offset.
56 length = std::min(length - range_offset, range_length);
57 }
58 *out_content_length = length;
59 out_file_stream->reset(file_stream.release());
60
61 // If the underlying file has been changed and the expected file
62 // modification time is set, treat it as error. Note that the expected
63 // modification time from WebKit is based on time_t precision. So we
64 // have to convert both to time_t to compare. This check is used for
65 // sliced files.
66 if (!expected_modification_time.is_null()) {
67 base::PlatformFileInfo info;
68 if (file_util::GetFileInfo(path, &info) &&
69 expected_modification_time.ToTimeT() !=
70 info.last_modified.ToTimeT()) {
71 *out_result = ERR_UPLOAD_FILE_CHANGED;
72 return;
73 }
74 }
75
76 *out_result = OK;
77 }
78
20 } // namespace 79 } // namespace
21 80
22 UploadFileElementReader::UploadFileElementReader( 81 UploadFileElementReader::UploadFileElementReader(
23 const FilePath& path, 82 const FilePath& path,
24 uint64 range_offset, 83 uint64 range_offset,
25 uint64 range_length, 84 uint64 range_length,
26 const base::Time& expected_modification_time) 85 const base::Time& expected_modification_time)
27 : path_(path), 86 : path_(path),
28 range_offset_(range_offset), 87 range_offset_(range_offset),
29 range_length_(range_length), 88 range_length_(range_length),
30 expected_modification_time_(expected_modification_time), 89 expected_modification_time_(expected_modification_time),
31 content_length_(0), 90 content_length_(0),
32 bytes_remaining_(0) { 91 bytes_remaining_(0),
92 weak_ptr_factory_(this) {
33 } 93 }
34 94
35 UploadFileElementReader::~UploadFileElementReader() { 95 UploadFileElementReader::~UploadFileElementReader() {
36 // Temporarily allow until fix: http://crbug.com/72001. 96 // Temporarily allow until fix: http://crbug.com/72001.
37 base::ThreadRestrictions::ScopedAllowIO allow_io; 97 base::ThreadRestrictions::ScopedAllowIO allow_io;
38 if (file_stream_.get()) 98 if (file_stream_.get())
39 file_stream_->CloseSync(); 99 file_stream_->CloseSync();
40 } 100 }
41 101
102 int UploadFileElementReader::Init(const CompletionCallback& callback) {
103 scoped_ptr<FileStream>* file_stream = new scoped_ptr<FileStream>;
104 uint64* content_length = new uint64;
105 int* result = new int;
106 const bool posted = base::WorkerPool::PostTaskAndReply(
107 FROM_HERE,
108 base::Bind(&InitInternal,
109 path_,
110 range_offset_,
111 range_length_,
112 expected_modification_time_,
113 file_stream,
114 content_length,
115 result),
116 base::Bind(&UploadFileElementReader::OnInitCompleted,
117 weak_ptr_factory_.GetWeakPtr(),
118 base::Owned(file_stream),
119 base::Owned(content_length),
120 base::Owned(result),
121 callback),
122 true /* task_is_slow */);
123 DCHECK(posted);
124 return ERR_IO_PENDING;
125 }
126
42 int UploadFileElementReader::InitSync() { 127 int UploadFileElementReader::InitSync() {
43 // Temporarily allow until fix: http://crbug.com/72001. 128 // Temporarily allow until fix: http://crbug.com/72001.
44 base::ThreadRestrictions::ScopedAllowIO allow_io; 129 base::ThreadRestrictions::ScopedAllowIO allow_io;
45 130
46 scoped_ptr<FileStream> file_stream(new FileStream(NULL)); 131 scoped_ptr<FileStream> file_stream;
47 int64 rv = file_stream->OpenSync( 132 uint64 content_length = 0;
48 path_, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); 133 int result = OK;
49 if (rv != OK) { 134 InitInternal(path_, range_offset_, range_length_, expected_modification_time_,
50 // If the file can't be opened, we'll just upload an empty file. 135 &file_stream, &content_length, &result);
51 DLOG(WARNING) << "Failed to open \"" << path_.value() 136 OnInitCompleted(&file_stream, &content_length, &result, CompletionCallback());
52 << "\" for reading: " << rv; 137 return result;
53 file_stream.reset();
54 }
55 if (file_stream.get() && range_offset_) {
56 rv = file_stream->SeekSync(FROM_BEGIN, range_offset_);
57 if (rv < 0) {
58 DLOG(WARNING) << "Failed to seek \"" << path_.value()
59 << "\" to offset: " << range_offset_ << " (" << rv
60 << ")";
61 file_stream->CloseSync();
62 file_stream.reset();
63 }
64 }
65 file_stream_.reset(file_stream.release());
66
67 int64 length = 0;
68 if (file_stream_.get() &&
69 file_util::GetFileSize(path_, &length) &&
70 range_offset_ < static_cast<uint64>(length)) {
71 // Compensate for the offset.
72 length = std::min(length - range_offset_, range_length_);
73 }
74 content_length_ = length;
75 bytes_remaining_ = GetContentLength();
76
77 // If the underlying file has been changed and the expected file
78 // modification time is set, treat it as error. Note that the expected
79 // modification time from WebKit is based on time_t precision. So we
80 // have to convert both to time_t to compare. This check is used for
81 // sliced files.
82 if (!expected_modification_time_.is_null()) {
83 base::PlatformFileInfo info;
84 if (file_util::GetFileInfo(path_, &info) &&
85 expected_modification_time_.ToTimeT() !=
86 info.last_modified.ToTimeT()) {
87 return ERR_UPLOAD_FILE_CHANGED;
88 }
89 }
90
91 return OK;
92 } 138 }
93 139
94 uint64 UploadFileElementReader::GetContentLength() const { 140 uint64 UploadFileElementReader::GetContentLength() const {
95 if (overriding_content_length) 141 if (overriding_content_length)
96 return overriding_content_length; 142 return overriding_content_length;
97 return content_length_; 143 return content_length_;
98 } 144 }
99 145
100 uint64 UploadFileElementReader::BytesRemaining() const { 146 uint64 UploadFileElementReader::BytesRemaining() const {
101 return bytes_remaining_; 147 return bytes_remaining_;
(...skipping 20 matching lines...) Expand all
122 // pad with zero. Otherwise the server will hang waiting for the 168 // pad with zero. Otherwise the server will hang waiting for the
123 // rest of the data. 169 // rest of the data.
124 memset(buf, 0, num_bytes_to_read); 170 memset(buf, 0, num_bytes_to_read);
125 } 171 }
126 } 172 }
127 DCHECK_GE(bytes_remaining_, num_bytes_to_read); 173 DCHECK_GE(bytes_remaining_, num_bytes_to_read);
128 bytes_remaining_ -= num_bytes_to_read; 174 bytes_remaining_ -= num_bytes_to_read;
129 return num_bytes_to_read; 175 return num_bytes_to_read;
130 } 176 }
131 177
178 void UploadFileElementReader::OnInitCompleted(
179 scoped_ptr<FileStream>* file_stream,
180 uint64* content_length,
181 int* result,
182 const CompletionCallback& callback) {
183 file_stream_.reset(file_stream->release());
184 content_length_ = *content_length;
185 bytes_remaining_ = GetContentLength();
186 if (!callback.is_null())
187 callback.Run(*result);
188 }
189
132 UploadFileElementReader::ScopedOverridingContentLengthForTests:: 190 UploadFileElementReader::ScopedOverridingContentLengthForTests::
133 ScopedOverridingContentLengthForTests(uint64 value) { 191 ScopedOverridingContentLengthForTests(uint64 value) {
134 overriding_content_length = value; 192 overriding_content_length = value;
135 } 193 }
136 194
137 UploadFileElementReader::ScopedOverridingContentLengthForTests:: 195 UploadFileElementReader::ScopedOverridingContentLengthForTests::
138 ~ScopedOverridingContentLengthForTests() { 196 ~ScopedOverridingContentLengthForTests() {
139 overriding_content_length = 0; 197 overriding_content_length = 0;
140 } 198 }
141 199
142 } // namespace net 200 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698