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

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: _ 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_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.
willchan no longer on Chromium 2012/09/24 23:37:08 Are we going to be able to fix the chunked data to
hashimoto 2012/09/25 10:47:56 Filed http://crbug.com/152148
73 if (IsInMemory() || is_chunked())
74 return ReadSync(buf, buf_len);
75
76 ReadInternal(buf, buf_len, 0, callback, OK);
77 return ERR_IO_PENDING;
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 void UploadDataStream::ReadInternal(scoped_refptr<IOBuffer> buf,
200 int buf_len,
201 int bytes_copied,
202 const CompletionCallback& callback,
203 int previous_result) {
204 DCHECK(initialized_successfully_);
205 DCHECK_GE(previous_result, 0);
206
207 // Add the last result.
208 bytes_copied += previous_result;
209
210 while (bytes_copied < buf_len && element_index_ < element_readers_.size()) {
211 UploadElementReader* reader = element_readers_[element_index_];
212
213 if (reader->BytesRemaining() == 0) {
214 ++element_index_;
215 continue;
216 }
217 scoped_refptr<DrainableIOBuffer> sub_buffer =
218 new DrainableIOBuffer(buf, buf_len);
219 sub_buffer->SetOffset(bytes_copied);
220 const int result = reader->Read(sub_buffer,
221 sub_buffer->BytesRemaining(),
222 base::Bind(&UploadDataStream::ReadInternal,
223 weak_ptr_factory_.GetWeakPtr(),
224 buf,
225 buf_len,
226 bytes_copied,
227 callback));
228 if (result == ERR_IO_PENDING)
229 return;
230
231 DCHECK_GE(bytes_copied, 0);
232 bytes_copied += result;
233 }
234 current_position_ += bytes_copied;
235
236 // Post task to the message loop to keep the execution order unchanged even if
willchan no longer on Chromium 2012/09/24 23:37:08 What does this mean?
hashimoto 2012/09/25 10:47:56 Sorry for my badly written comment. Introduced mor
237 // there were no asynchronous operation happening.
238 MessageLoop::current()->PostTask(FROM_HERE,
239 base::Bind(callback, bytes_copied));
240 }
241
182 } // namespace net 242 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698