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

Side by Side Diff: webkit/fileapi/file_system_operation.cc

Issue 10008047: FileWriterDelegate should not call URLRequest::Start() after Cancel(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixing.. Created 8 years, 8 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 "webkit/fileapi/file_system_operation.h" 5 #include "webkit/fileapi/file_system_operation.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/time.h" 8 #include "base/time.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "net/base/escape.h" 10 #include "net/base/escape.h"
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 path_url, &src_path_, &src_util_, PATH_FOR_WRITE); 282 path_url, &src_path_, &src_util_, PATH_FOR_WRITE);
283 if (result != base::PLATFORM_FILE_OK) { 283 if (result != base::PLATFORM_FILE_OK) {
284 callback.Run(result, 0, false); 284 callback.Run(result, 0, false);
285 delete this; 285 delete this;
286 return; 286 return;
287 } 287 }
288 DCHECK(blob_url.is_valid()); 288 DCHECK(blob_url.is_valid());
289 file_writer_delegate_.reset(new FileWriterDelegate( 289 file_writer_delegate_.reset(new FileWriterDelegate(
290 this, src_path_, offset, proxy_)); 290 this, src_path_, offset, proxy_));
291 set_write_callback(callback); 291 set_write_callback(callback);
292 blob_request_.reset(
293 new net::URLRequest(blob_url, file_writer_delegate_.get()));
294 blob_request_->set_context(url_request_context);
295 292
296 GetUsageAndQuotaThenRunTask( 293 GetUsageAndQuotaThenRunTask(
297 src_path_.origin(), src_path_.type(), 294 src_path_.origin(), src_path_.type(),
298 base::Bind(&FileSystemOperation::DoWrite, base::Unretained(this)), 295 base::Bind(&FileSystemOperation::DoWrite, base::Unretained(this),
296 blob_url, make_scoped_refptr(url_request_context)),
299 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 0, true)); 297 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 0, true));
300 } 298 }
301 299
302 void FileSystemOperation::Truncate(const GURL& path_url, int64 length, 300 void FileSystemOperation::Truncate(const GURL& path_url, int64 length,
303 const StatusCallback& callback) { 301 const StatusCallback& callback) {
304 DCHECK(SetPendingOperationType(kOperationTruncate)); 302 DCHECK(SetPendingOperationType(kOperationTruncate));
305 303
306 base::PlatformFileError result = SetUpFileSystemPath( 304 base::PlatformFileError result = SetUpFileSystemPath(
307 path_url, &src_path_, &src_util_, PATH_FOR_WRITE); 305 path_url, &src_path_, &src_util_, PATH_FOR_WRITE);
308 if (result != base::PLATFORM_FILE_OK) { 306 if (result != base::PLATFORM_FILE_OK) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 379 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED,
382 base::kInvalidPlatformFileValue, 380 base::kInvalidPlatformFileValue,
383 base::kNullProcessHandle)); 381 base::kNullProcessHandle));
384 } 382 }
385 383
386 // We can only get here on a write or truncate that's not yet completed. 384 // We can only get here on a write or truncate that's not yet completed.
387 // We don't support cancelling any other operation at this time. 385 // We don't support cancelling any other operation at this time.
388 void FileSystemOperation::Cancel(const StatusCallback& cancel_callback) { 386 void FileSystemOperation::Cancel(const StatusCallback& cancel_callback) {
389 if (file_writer_delegate_.get()) { 387 if (file_writer_delegate_.get()) {
390 DCHECK_EQ(kOperationWrite, pending_operation_); 388 DCHECK_EQ(kOperationWrite, pending_operation_);
389
391 // Writes are done without proxying through FileUtilProxy after the initial 390 // Writes are done without proxying through FileUtilProxy after the initial
392 // opening of the PlatformFile. All state changes are done on this thread, 391 // opening of the PlatformFile. All state changes are done on this thread,
393 // so we're guaranteed to be able to shut down atomically. We do need to 392 // so we're guaranteed to be able to shut down atomically. We do need to
394 // check that the file has been opened [which means the blob_request_ has 393 // check that the file has been opened [which means the blob_request_ has
395 // been created], so we know how much we need to do. 394 // been created], so we know how much we need to do.
396 if (blob_request_.get()) 395 file_writer_delegate_->Cancel();
397 // This halts any calls to file_writer_delegate_ from blob_request_.
398 blob_request_->Cancel();
399 396
400 if (!write_callback_.is_null()) { 397 if (!write_callback_.is_null()) {
401 // Notify the failure status to the ongoing operation's callback. 398 // Notify the failure status to the ongoing operation's callback.
402 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false); 399 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false);
403 // Do not delete this FileSystemOperation object yet. As a result of 400 // Do not delete this FileSystemOperation object yet. As a result of
404 // abort, this->DidWrite is called later and there we delete this object. 401 // abort, this->DidWrite is called later and there we delete this object.
ericu 2012/04/10 22:10:32 I'm not sure this is still true; see comments in f
405 } 402 }
406 cancel_callback.Run(base::PLATFORM_FILE_OK); 403 cancel_callback.Run(base::PLATFORM_FILE_OK);
407 write_callback_.Reset(); 404 write_callback_.Reset();
408 } else { 405 } else {
409 DCHECK_EQ(kOperationTruncate, pending_operation_); 406 DCHECK_EQ(kOperationTruncate, pending_operation_);
410 // We're cancelling a truncate operation, but we can't actually stop it 407 // We're cancelling a truncate operation, but we can't actually stop it
411 // since it's been proxied to another thread. We need to save the 408 // since it's been proxied to another thread. We need to save the
412 // cancel_callback so that when the truncate returns, it can see that it's 409 // cancel_callback so that when the truncate returns, it can see that it's
413 // been cancelled, report it, and report that the cancel has succeeded. 410 // been cancelled, report it, and report that the cancel has succeeded.
414 DCHECK(cancel_callback_.is_null()); 411 DCHECK(cancel_callback_.is_null());
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 529
533 void FileSystemOperation::DoMove(const StatusCallback& callback) { 530 void FileSystemOperation::DoMove(const StatusCallback& callback) {
534 FileSystemFileUtilProxy::Move( 531 FileSystemFileUtilProxy::Move(
535 proxy_, &operation_context_, 532 proxy_, &operation_context_,
536 src_util_, dest_util_, 533 src_util_, dest_util_,
537 src_path_, dest_path_, 534 src_path_, dest_path_,
538 base::Bind(&FileSystemOperation::DidFinishFileOperation, 535 base::Bind(&FileSystemOperation::DidFinishFileOperation,
539 base::Owned(this), callback)); 536 base::Owned(this), callback));
540 } 537 }
541 538
542 void FileSystemOperation::DoWrite() { 539 void FileSystemOperation::DoWrite(
540 const GURL& blob_url,
541 const net::URLRequestContext* request_context) {
543 int file_flags = base::PLATFORM_FILE_OPEN | 542 int file_flags = base::PLATFORM_FILE_OPEN |
544 base::PLATFORM_FILE_WRITE | 543 base::PLATFORM_FILE_WRITE |
545 base::PLATFORM_FILE_ASYNC; 544 base::PLATFORM_FILE_ASYNC;
546 545
547 FileSystemFileUtilProxy::CreateOrOpen( 546 FileSystemFileUtilProxy::CreateOrOpen(
548 proxy_, &operation_context_, src_util_, src_path_, file_flags, 547 proxy_, &operation_context_, src_util_, src_path_, file_flags,
549 base::Bind(&FileSystemOperation::OnFileOpenedForWrite, 548 base::Bind(&FileSystemOperation::OnFileOpenedForWrite,
550 base::Unretained(this))); 549 base::Unretained(this),
550 blob_url, make_scoped_refptr(request_context)));
551 } 551 }
552 552
553 void FileSystemOperation::DoTruncate(const StatusCallback& callback, 553 void FileSystemOperation::DoTruncate(const StatusCallback& callback,
554 int64 length) { 554 int64 length) {
555 FileSystemFileUtilProxy::Truncate( 555 FileSystemFileUtilProxy::Truncate(
556 proxy_, &operation_context_, src_util_, src_path_, length, 556 proxy_, &operation_context_, src_util_, src_path_, length,
557 base::Bind(&FileSystemOperation::DidFinishFileOperation, 557 base::Bind(&FileSystemOperation::DidFinishFileOperation,
558 base::Owned(this), callback)); 558 base::Owned(this), callback));
559 } 559 }
560 560
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 const OpenFileCallback& callback, 656 const OpenFileCallback& callback,
657 base::PlatformFileError rv, 657 base::PlatformFileError rv,
658 base::PassPlatformFile file, 658 base::PassPlatformFile file,
659 bool unused) { 659 bool unused) {
660 if (rv == base::PLATFORM_FILE_OK) 660 if (rv == base::PLATFORM_FILE_OK)
661 CHECK_NE(base::kNullProcessHandle, peer_handle_); 661 CHECK_NE(base::kNullProcessHandle, peer_handle_);
662 callback.Run(rv, file.ReleaseValue(), peer_handle_); 662 callback.Run(rv, file.ReleaseValue(), peer_handle_);
663 } 663 }
664 664
665 void FileSystemOperation::OnFileOpenedForWrite( 665 void FileSystemOperation::OnFileOpenedForWrite(
666 const GURL& blob_url,
667 const net::URLRequestContext* request_context,
666 base::PlatformFileError rv, 668 base::PlatformFileError rv,
667 base::PassPlatformFile file, 669 base::PassPlatformFile file,
668 bool created) { 670 bool created) {
669 if (rv != base::PLATFORM_FILE_OK) { 671 if (rv != base::PLATFORM_FILE_OK) {
670 if (!write_callback_.is_null()) 672 if (!write_callback_.is_null())
671 write_callback_.Run(rv, 0, false); 673 write_callback_.Run(rv, 0, false);
672 delete this; 674 delete this;
673 return; 675 return;
674 } 676 }
675 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); 677 if (write_callback_.is_null()) {
678 // If cancelled, callback is already invoked and set to null in Cancel().
679 // We must not call it twice. Just shut down this operation object.
680 delete this;
681 return;
682 }
683 scoped_ptr<net::URLRequest> blob_request(
684 new net::URLRequest(blob_url, file_writer_delegate_.get()));
685 blob_request->set_context(request_context);
686 file_writer_delegate_->Start(file.ReleaseValue(), blob_request.Pass());
676 } 687 }
677 688
678 base::PlatformFileError FileSystemOperation::SetUpFileSystemPath( 689 base::PlatformFileError FileSystemOperation::SetUpFileSystemPath(
679 const GURL& path_url, 690 const GURL& path_url,
680 FileSystemPath* file_system_path, 691 FileSystemPath* file_system_path,
681 FileSystemFileUtil** file_util, 692 FileSystemFileUtil** file_util,
682 SetUpPathMode mode) { 693 SetUpPathMode mode) {
683 DCHECK(file_system_path); 694 DCHECK(file_system_path);
684 GURL origin_url; 695 GURL origin_url;
685 FileSystemType type; 696 FileSystemType type;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 } 746 }
736 747
737 bool FileSystemOperation::SetPendingOperationType(OperationType type) { 748 bool FileSystemOperation::SetPendingOperationType(OperationType type) {
738 if (pending_operation_ != kOperationNone) 749 if (pending_operation_ != kOperationNone)
739 return false; 750 return false;
740 pending_operation_ = type; 751 pending_operation_ = type;
741 return true; 752 return true;
742 } 753 }
743 754
744 } // namespace fileapi 755 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698