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

Side by Side Diff: chrome/browser/chromeos/drive/drive_file_stream_reader.cc

Issue 291483005: drive: Discard stream reader canceller as soon as the required data is obtained. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/browser/chromeos/drive/drive_file_stream_reader.h" 5 #include "chrome/browser/chromeos/drive/drive_file_stream_reader.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 9
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } else { 145 } else {
146 // An error occurs. Close the |file_reader_|. 146 // An error occurs. Close the |file_reader_|.
147 file_reader_.reset(); 147 file_reader_.reset();
148 } 148 }
149 callback.Run(read_result); 149 callback.Run(read_result);
150 } 150 }
151 151
152 NetworkReaderProxy::NetworkReaderProxy( 152 NetworkReaderProxy::NetworkReaderProxy(
153 int64 offset, 153 int64 offset,
154 int64 content_length, 154 int64 content_length,
155 int64 full_content_length,
155 const base::Closure& job_canceller) 156 const base::Closure& job_canceller)
156 : remaining_offset_(offset), 157 : remaining_offset_(offset),
157 remaining_content_length_(content_length), 158 remaining_content_length_(content_length),
159 is_full_download_(offset + content_length == full_content_length),
158 error_code_(net::OK), 160 error_code_(net::OK),
159 buffer_length_(0), 161 buffer_length_(0),
160 job_canceller_(job_canceller) { 162 job_canceller_(job_canceller) {
161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
162 } 164 }
163 165
164 NetworkReaderProxy::~NetworkReaderProxy() { 166 NetworkReaderProxy::~NetworkReaderProxy() {
165 if (!job_canceller_.is_null()) { 167 if (!job_canceller_.is_null()) {
166 job_canceller_.Run(); 168 job_canceller_.Run();
167 } 169 }
(...skipping 30 matching lines...) Expand all
198 // No data is available. Keep the arguments, and return pending status. 200 // No data is available. Keep the arguments, and return pending status.
199 buffer_ = buffer; 201 buffer_ = buffer;
200 buffer_length_ = buffer_length; 202 buffer_length_ = buffer_length;
201 callback_ = callback; 203 callback_ = callback;
202 return net::ERR_IO_PENDING; 204 return net::ERR_IO_PENDING;
203 } 205 }
204 206
205 int result = ReadInternal(&pending_data_, buffer, buffer_length); 207 int result = ReadInternal(&pending_data_, buffer, buffer_length);
206 remaining_content_length_ -= result; 208 remaining_content_length_ -= result;
207 DCHECK_GE(remaining_content_length_, 0); 209 DCHECK_GE(remaining_content_length_, 0);
210
211 // Although OnCompleted() should reset |job_canceller_| when download is done,
212 // due to timing issues the ReaderProxy instance may be destructed before the
213 // notification. To fix the case we reset here earlier.
214 if (is_full_download_ && remaining_content_length_ == 0)
215 job_canceller_.Reset();
216
208 return result; 217 return result;
209 } 218 }
210 219
211 void NetworkReaderProxy::OnGetContent(scoped_ptr<std::string> data) { 220 void NetworkReaderProxy::OnGetContent(scoped_ptr<std::string> data) {
212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
213 DCHECK(data && !data->empty()); 222 DCHECK(data && !data->empty());
214 223
215 if (remaining_offset_ >= static_cast<int64>(data->length())) { 224 if (remaining_offset_ >= static_cast<int64>(data->length())) {
216 // Skip unneeded leading data. 225 // Skip unneeded leading data.
217 remaining_offset_ -= data->length(); 226 remaining_offset_ -= data->length();
218 return; 227 return;
219 } 228 }
220 229
221 if (remaining_offset_ > 0) { 230 if (remaining_offset_ > 0) {
222 // Erase unnecessary leading bytes. 231 // Erase unnecessary leading bytes.
223 data->erase(0, static_cast<size_t>(remaining_offset_)); 232 data->erase(0, static_cast<size_t>(remaining_offset_));
224 remaining_offset_ = 0; 233 remaining_offset_ = 0;
225 } 234 }
226 235
227 pending_data_.push_back(data.release()); 236 pending_data_.push_back(data.release());
228 if (!buffer_.get()) { 237 if (!buffer_.get()) {
229 // No pending Read operation. 238 // No pending Read operation.
230 return; 239 return;
231 } 240 }
232 241
233 int result = ReadInternal(&pending_data_, buffer_.get(), buffer_length_); 242 int result = ReadInternal(&pending_data_, buffer_.get(), buffer_length_);
234 remaining_content_length_ -= result; 243 remaining_content_length_ -= result;
235 DCHECK_GE(remaining_content_length_, 0); 244 DCHECK_GE(remaining_content_length_, 0);
236 245
246 if (is_full_download_ && remaining_content_length_ == 0)
247 job_canceller_.Reset();
248
237 buffer_ = NULL; 249 buffer_ = NULL;
238 buffer_length_ = 0; 250 buffer_length_ = 0;
239 DCHECK(!callback_.is_null()); 251 DCHECK(!callback_.is_null());
240 base::ResetAndReturn(&callback_).Run(result); 252 base::ResetAndReturn(&callback_).Run(result);
241 } 253 }
242 254
243 void NetworkReaderProxy::OnCompleted(FileError error) { 255 void NetworkReaderProxy::OnCompleted(FileError error) {
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
245 // The downloading is completed, so we do not need to cancel the job 257 // The downloading is completed, so we do not need to cancel the job
246 // in the destructor. 258 // in the destructor.
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 weak_ptr_factory_.InvalidateWeakPtrs(); 410 weak_ptr_factory_.InvalidateWeakPtrs();
399 callback.Run( 411 callback.Run(
400 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, scoped_ptr<ResourceEntry>()); 412 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, scoped_ptr<ResourceEntry>());
401 return; 413 return;
402 } 414 }
403 415
404 if (local_cache_file_path.empty()) { 416 if (local_cache_file_path.empty()) {
405 // The file is not cached, and being downloaded. 417 // The file is not cached, and being downloaded.
406 reader_proxy_.reset( 418 reader_proxy_.reset(
407 new internal::NetworkReaderProxy( 419 new internal::NetworkReaderProxy(
408 range_start, range_length, cancel_download_closure_)); 420 range_start, range_length,
421 entry->file_info().size(), cancel_download_closure_));
409 callback.Run(net::OK, entry.Pass()); 422 callback.Run(net::OK, entry.Pass());
410 return; 423 return;
411 } 424 }
412 425
413 // Otherwise, open the stream for file. 426 // Otherwise, open the stream for file.
414 scoped_ptr<util::LocalFileReader> file_reader( 427 scoped_ptr<util::LocalFileReader> file_reader(
415 new util::LocalFileReader(file_task_runner_.get())); 428 new util::LocalFileReader(file_task_runner_.get()));
416 util::LocalFileReader* file_reader_ptr = file_reader.get(); 429 util::LocalFileReader* file_reader_ptr = file_reader.get();
417 file_reader_ptr->Open( 430 file_reader_ptr->Open(
418 local_cache_file_path, 431 local_cache_file_path,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 // Note: due to the same reason, LocalReaderProxy::OnCompleted may 482 // Note: due to the same reason, LocalReaderProxy::OnCompleted may
470 // or may not be called. This is timing issue, and it is difficult to avoid 483 // or may not be called. This is timing issue, and it is difficult to avoid
471 // unfortunately. 484 // unfortunately.
472 if (error != FILE_ERROR_OK) { 485 if (error != FILE_ERROR_OK) {
473 callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>()); 486 callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>());
474 } 487 }
475 } 488 }
476 } 489 }
477 490
478 } // namespace drive 491 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698