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

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

Issue 10910268: net: Make UploadDataStream::Read() asynchronous (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revised 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 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_data_stream.h" 5 #include "net/base/upload_data_stream.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/message_loop.h"
8 #include "net/base/io_buffer.h" 9 #include "net/base/io_buffer.h"
9 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
10 #include "net/base/upload_element_reader.h" 11 #include "net/base/upload_element_reader.h"
11 12
12 namespace net { 13 namespace net {
13 14
14 bool UploadDataStream::merge_chunks_ = true; 15 bool UploadDataStream::merge_chunks_ = true;
15 16
16 // static 17 // static
17 void UploadDataStream::ResetMergeChunks() { 18 void UploadDataStream::ResetMergeChunks() {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 if (result != OK) { 56 if (result != OK) {
56 element_readers_.clear(); 57 element_readers_.clear();
57 return result; 58 return result;
58 } 59 }
59 } 60 }
60 61
61 FinalizeInitialization(); 62 FinalizeInitialization();
62 return OK; 63 return OK;
63 } 64 }
64 65
65 int UploadDataStream::Read(IOBuffer* buf, int buf_len) { 66 int UploadDataStream::Read(IOBuffer* buf,
67 int buf_len,
68 const CompletionCallback& callback) {
69 DCHECK(initialized_successfully_);
70
71 // Use fast path when all data is in memory, chunked data is also processed
72 // with ReadSync() since it requires special logic.
mmenke 2012/10/12 21:30:29 "since it requires special logic, and is already i
hashimoto 2012/10/15 11:21:37 Done.
73 if (IsInMemory() || is_chunked())
74 return ReadSync(buf, buf_len);
75
76 const bool invoked_asynchronously = false;
77 return ReadInternal(buf, buf_len, 0, invoked_asynchronously, callback, 0);
78 }
79
80 int UploadDataStream::ReadSync(IOBuffer* buf, int buf_len) {
66 DCHECK(initialized_successfully_); 81 DCHECK(initialized_successfully_);
67 82
68 // Initialize readers for newly appended chunks. 83 // Initialize readers for newly appended chunks.
69 if (is_chunked()) { 84 if (is_chunked()) {
70 const std::vector<UploadElement>& elements = *upload_data_->elements(); 85 const std::vector<UploadElement>& elements = *upload_data_->elements();
71 DCHECK_LE(element_readers_.size(), elements.size()); 86 DCHECK_LE(element_readers_.size(), elements.size());
72 87
73 for (size_t i = element_readers_.size(); i < elements.size(); ++i) { 88 for (size_t i = element_readers_.size(); i < elements.size(); ++i) {
74 const UploadElement& element = elements[i]; 89 const UploadElement& element = elements[i];
75 DCHECK_EQ(UploadElement::TYPE_BYTES, element.type()); 90 DCHECK_EQ(UploadElement::TYPE_BYTES, element.type());
76 UploadElementReader* reader = UploadElementReader::Create(element); 91 UploadElementReader* reader = UploadElementReader::Create(element);
77 92
78 const int rv = reader->InitSync(); 93 const int rv = reader->InitSync();
79 DCHECK_EQ(rv, OK); 94 DCHECK_EQ(rv, OK);
80 element_readers_.push_back(reader); 95 element_readers_.push_back(reader);
81 } 96 }
82 } 97 }
83 98
84 int bytes_copied = 0; 99 int bytes_copied = 0;
85 while (bytes_copied < buf_len && element_index_ < element_readers_.size()) { 100 while (bytes_copied < buf_len && element_index_ < element_readers_.size()) {
86 UploadElementReader* reader = element_readers_[element_index_]; 101 UploadElementReader* reader = element_readers_[element_index_];
87 bytes_copied += reader->ReadSync(buf->data() + bytes_copied, 102 scoped_refptr<DrainableIOBuffer> sub_buffer =
88 buf_len - bytes_copied); 103 new DrainableIOBuffer(buf, buf_len);
104 sub_buffer->SetOffset(bytes_copied);
105 bytes_copied += reader->ReadSync(sub_buffer, sub_buffer->BytesRemaining());
89 if (reader->BytesRemaining() == 0) 106 if (reader->BytesRemaining() == 0)
90 ++element_index_; 107 ++element_index_;
91 108
92 if (is_chunked() && !merge_chunks_) 109 if (is_chunked() && !merge_chunks_)
93 break; 110 break;
94 } 111 }
95 112
96 current_position_ += bytes_copied; 113 current_position_ += bytes_copied;
97 if (is_chunked() && !IsEOF() && bytes_copied == 0) 114 if (is_chunked() && !IsEOF() && bytes_copied == 0)
98 return ERR_IO_PENDING; 115 return ERR_IO_PENDING;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 uint64 total_size = 0; 189 uint64 total_size = 0;
173 for (size_t i = 0; i < element_readers_.size(); ++i) { 190 for (size_t i = 0; i < element_readers_.size(); ++i) {
174 UploadElementReader* reader = element_readers_[i]; 191 UploadElementReader* reader = element_readers_[i];
175 total_size += reader->GetContentLength(); 192 total_size += reader->GetContentLength();
176 } 193 }
177 total_size_ = total_size; 194 total_size_ = total_size;
178 } 195 }
179 initialized_successfully_ = true; 196 initialized_successfully_ = true;
180 } 197 }
181 198
199 int UploadDataStream::ReadInternal(scoped_refptr<IOBuffer> buf,
200 int buf_len,
201 int bytes_copied,
202 bool invoked_asynchronously,
203 const CompletionCallback& callback,
204 int previous_result) {
205 DCHECK(initialized_successfully_);
206 DCHECK_GE(previous_result, 0);
207
208 // Add the last result.
209 bytes_copied += previous_result;
210
211 while (bytes_copied < buf_len && element_index_ < element_readers_.size()) {
212 UploadElementReader* reader = element_readers_[element_index_];
213
214 if (reader->BytesRemaining() == 0) {
215 ++element_index_;
216 continue;
217 }
218 scoped_refptr<DrainableIOBuffer> sub_buffer =
219 new DrainableIOBuffer(buf, buf_len);
220 sub_buffer->SetOffset(bytes_copied);
221 const int result = reader->Read(
222 sub_buffer,
223 sub_buffer->BytesRemaining(),
224 base::Bind(base::IgnoreResult(&UploadDataStream::ReadInternal),
225 weak_ptr_factory_.GetWeakPtr(),
226 buf,
227 buf_len,
228 bytes_copied,
229 true, // invoked_asynchronously
230 callback));
231 if (result == ERR_IO_PENDING)
232 return ERR_IO_PENDING;
233
234 DCHECK_GE(bytes_copied, 0);
235 bytes_copied += result;
236 }
237 current_position_ += bytes_copied;
238
239 // When invoked asynchronously, callback is the only way to return the result.
240 if (invoked_asynchronously)
241 callback.Run(bytes_copied);
242 return bytes_copied;
243 }
244
182 } // namespace net 245 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698