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

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: reverted the test Created 8 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 (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/sequenced_task_runner.h" 8 #include "base/sequenced_task_runner.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 path_url, &src_path_, &src_util_, PATH_FOR_WRITE); 283 path_url, &src_path_, &src_util_, PATH_FOR_WRITE);
284 if (result != base::PLATFORM_FILE_OK) { 284 if (result != base::PLATFORM_FILE_OK) {
285 callback.Run(result, 0, false); 285 callback.Run(result, 0, false);
286 delete this; 286 delete this;
287 return; 287 return;
288 } 288 }
289 DCHECK(blob_url.is_valid()); 289 DCHECK(blob_url.is_valid());
290 file_writer_delegate_.reset(new FileWriterDelegate( 290 file_writer_delegate_.reset(new FileWriterDelegate(
291 this, src_path_, offset)); 291 this, src_path_, offset));
292 set_write_callback(callback); 292 set_write_callback(callback);
293 blob_request_.reset( 293 scoped_ptr<net::URLRequest> blob_request(
294 new net::URLRequest(blob_url, file_writer_delegate_.get())); 294 new net::URLRequest(blob_url, file_writer_delegate_.get()));
295 blob_request_->set_context(url_request_context); 295 blob_request->set_context(url_request_context);
296 296
297 GetUsageAndQuotaThenRunTask( 297 GetUsageAndQuotaThenRunTask(
298 src_path_.origin(), src_path_.type(), 298 src_path_.origin(), src_path_.type(),
299 base::Bind(&FileSystemOperation::DoWrite, base::Unretained(this)), 299 base::Bind(&FileSystemOperation::DoWrite, weak_factory_.GetWeakPtr(),
300 base::Passed(&blob_request)),
300 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 0, true)); 301 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 0, true));
301 } 302 }
302 303
303 void FileSystemOperation::Truncate(const GURL& path_url, int64 length, 304 void FileSystemOperation::Truncate(const GURL& path_url, int64 length,
304 const StatusCallback& callback) { 305 const StatusCallback& callback) {
305 DCHECK(SetPendingOperationType(kOperationTruncate)); 306 DCHECK(SetPendingOperationType(kOperationTruncate));
306 307
307 base::PlatformFileError result = SetUpFileSystemPath( 308 base::PlatformFileError result = SetUpFileSystemPath(
308 path_url, &src_path_, &src_util_, PATH_FOR_WRITE); 309 path_url, &src_path_, &src_util_, PATH_FOR_WRITE);
309 if (result != base::PLATFORM_FILE_OK) { 310 if (result != base::PLATFORM_FILE_OK) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 383 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED,
383 base::kInvalidPlatformFileValue, 384 base::kInvalidPlatformFileValue,
384 base::kNullProcessHandle)); 385 base::kNullProcessHandle));
385 } 386 }
386 387
387 // We can only get here on a write or truncate that's not yet completed. 388 // We can only get here on a write or truncate that's not yet completed.
388 // We don't support cancelling any other operation at this time. 389 // We don't support cancelling any other operation at this time.
389 void FileSystemOperation::Cancel(const StatusCallback& cancel_callback) { 390 void FileSystemOperation::Cancel(const StatusCallback& cancel_callback) {
390 if (file_writer_delegate_.get()) { 391 if (file_writer_delegate_.get()) {
391 DCHECK_EQ(kOperationWrite, pending_operation_); 392 DCHECK_EQ(kOperationWrite, pending_operation_);
393
392 // Writes are done without proxying through FileUtilProxy after the initial 394 // Writes are done without proxying through FileUtilProxy after the initial
393 // opening of the PlatformFile. All state changes are done on this thread, 395 // opening of the PlatformFile. All state changes are done on this thread,
394 // so we're guaranteed to be able to shut down atomically. We do need to 396 // so we're guaranteed to be able to shut down atomically.
395 // check that the file has been opened [which means the blob_request_ has 397 const bool delete_now = file_writer_delegate_->Cancel();
396 // been created], so we know how much we need to do.
397 if (blob_request_.get())
398 // This halts any calls to file_writer_delegate_ from blob_request_.
399 blob_request_->Cancel();
400 398
401 if (!write_callback_.is_null()) { 399 if (!write_callback_.is_null()) {
402 // Notify the failure status to the ongoing operation's callback. 400 // Notify the failure status to the ongoing operation's callback.
403 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false); 401 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false);
404 // Do not delete this FileSystemOperation object yet. As a result of
405 // abort, this->DidWrite is called later and there we delete this object.
406 } 402 }
407 cancel_callback.Run(base::PLATFORM_FILE_OK); 403 cancel_callback.Run(base::PLATFORM_FILE_OK);
408 write_callback_.Reset(); 404 write_callback_.Reset();
405
406 if (delete_now) {
407 delete this;
408 return;
409 }
409 } else { 410 } else {
410 DCHECK_EQ(kOperationTruncate, pending_operation_); 411 DCHECK_EQ(kOperationTruncate, pending_operation_);
411 // We're cancelling a truncate operation, but we can't actually stop it 412 // We're cancelling a truncate operation, but we can't actually stop it
412 // since it's been proxied to another thread. We need to save the 413 // since it's been proxied to another thread. We need to save the
413 // cancel_callback so that when the truncate returns, it can see that it's 414 // cancel_callback so that when the truncate returns, it can see that it's
414 // been cancelled, report it, and report that the cancel has succeeded. 415 // been cancelled, report it, and report that the cancel has succeeded.
415 DCHECK(cancel_callback_.is_null()); 416 DCHECK(cancel_callback_.is_null());
416 cancel_callback_ = cancel_callback; 417 cancel_callback_ = cancel_callback;
417 } 418 }
418 } 419 }
(...skipping 24 matching lines...) Expand all
443 const SnapshotFileCallback& callback) { 444 const SnapshotFileCallback& callback) {
444 GetMetadata(path_url, base::Bind(&GetMetadataForSnapshot, callback)); 445 GetMetadata(path_url, base::Bind(&GetMetadataForSnapshot, callback));
445 } 446 }
446 447
447 FileSystemOperation::FileSystemOperation( 448 FileSystemOperation::FileSystemOperation(
448 FileSystemContext* file_system_context) 449 FileSystemContext* file_system_context)
449 : operation_context_(file_system_context), 450 : operation_context_(file_system_context),
450 src_util_(NULL), 451 src_util_(NULL),
451 dest_util_(NULL), 452 dest_util_(NULL),
452 peer_handle_(base::kNullProcessHandle), 453 peer_handle_(base::kNullProcessHandle),
453 pending_operation_(kOperationNone) { 454 pending_operation_(kOperationNone),
455 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
454 } 456 }
455 457
456 void FileSystemOperation::GetUsageAndQuotaThenRunTask( 458 void FileSystemOperation::GetUsageAndQuotaThenRunTask(
457 const GURL& origin, FileSystemType type, 459 const GURL& origin, FileSystemType type,
458 const base::Closure& task, 460 const base::Closure& task,
459 const base::Closure& error_callback) { 461 const base::Closure& error_callback) {
460 quota::QuotaManagerProxy* quota_manager_proxy = 462 quota::QuotaManagerProxy* quota_manager_proxy =
461 file_system_context()->quota_manager_proxy(); 463 file_system_context()->quota_manager_proxy();
462 if (!quota_manager_proxy || 464 if (!quota_manager_proxy ||
463 !file_system_context()->GetQuotaUtil(type)) { 465 !file_system_context()->GetQuotaUtil(type)) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 535
534 void FileSystemOperation::DoMove(const StatusCallback& callback) { 536 void FileSystemOperation::DoMove(const StatusCallback& callback) {
535 FileSystemFileUtilProxy::Move( 537 FileSystemFileUtilProxy::Move(
536 &operation_context_, 538 &operation_context_,
537 src_util_, dest_util_, 539 src_util_, dest_util_,
538 src_path_, dest_path_, 540 src_path_, dest_path_,
539 base::Bind(&FileSystemOperation::DidFinishFileOperation, 541 base::Bind(&FileSystemOperation::DidFinishFileOperation,
540 base::Owned(this), callback)); 542 base::Owned(this), callback));
541 } 543 }
542 544
543 void FileSystemOperation::DoWrite() { 545 void FileSystemOperation::DoWrite(scoped_ptr<net::URLRequest> blob_request) {
544 int file_flags = base::PLATFORM_FILE_OPEN | 546 int file_flags = base::PLATFORM_FILE_OPEN |
545 base::PLATFORM_FILE_WRITE | 547 base::PLATFORM_FILE_WRITE |
546 base::PLATFORM_FILE_ASYNC; 548 base::PLATFORM_FILE_ASYNC;
547 549
550 // We may get deleted on the way so allocate a new operation context
551 // to keep it alive.
552 FileSystemOperationContext* write_context = new FileSystemOperationContext(
553 operation_context_);
548 FileSystemFileUtilProxy::CreateOrOpen( 554 FileSystemFileUtilProxy::CreateOrOpen(
549 &operation_context_, src_util_, src_path_, file_flags, 555 write_context, src_util_, src_path_, file_flags,
550 base::Bind(&FileSystemOperation::OnFileOpenedForWrite, 556 base::Bind(&FileSystemOperation::OnFileOpenedForWrite,
551 base::Unretained(this))); 557 weak_factory_.GetWeakPtr(),
558 base::Passed(&blob_request),
559 base::Owned(write_context)));
552 } 560 }
553 561
554 void FileSystemOperation::DoTruncate(const StatusCallback& callback, 562 void FileSystemOperation::DoTruncate(const StatusCallback& callback,
555 int64 length) { 563 int64 length) {
556 FileSystemFileUtilProxy::Truncate( 564 FileSystemFileUtilProxy::Truncate(
557 &operation_context_, src_util_, src_path_, length, 565 &operation_context_, src_util_, src_path_, length,
558 base::Bind(&FileSystemOperation::DidFinishFileOperation, 566 base::Bind(&FileSystemOperation::DidFinishFileOperation,
559 base::Owned(this), callback)); 567 base::Owned(this), callback));
560 } 568 }
561 569
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 const OpenFileCallback& callback, 665 const OpenFileCallback& callback,
658 base::PlatformFileError rv, 666 base::PlatformFileError rv,
659 base::PassPlatformFile file, 667 base::PassPlatformFile file,
660 bool unused) { 668 bool unused) {
661 if (rv == base::PLATFORM_FILE_OK) 669 if (rv == base::PLATFORM_FILE_OK)
662 CHECK_NE(base::kNullProcessHandle, peer_handle_); 670 CHECK_NE(base::kNullProcessHandle, peer_handle_);
663 callback.Run(rv, file.ReleaseValue(), peer_handle_); 671 callback.Run(rv, file.ReleaseValue(), peer_handle_);
664 } 672 }
665 673
666 void FileSystemOperation::OnFileOpenedForWrite( 674 void FileSystemOperation::OnFileOpenedForWrite(
675 scoped_ptr<net::URLRequest> blob_request,
676 FileSystemOperationContext* unused,
667 base::PlatformFileError rv, 677 base::PlatformFileError rv,
668 base::PassPlatformFile file, 678 base::PassPlatformFile file,
669 bool created) { 679 bool created) {
670 if (rv != base::PLATFORM_FILE_OK) { 680 if (rv != base::PLATFORM_FILE_OK) {
671 if (!write_callback_.is_null()) 681 if (!write_callback_.is_null())
672 write_callback_.Run(rv, 0, false); 682 write_callback_.Run(rv, 0, false);
673 delete this; 683 delete this;
674 return; 684 return;
675 } 685 }
676 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); 686 file_writer_delegate_->Start(file.ReleaseValue(), blob_request.Pass());
677 } 687 }
678 688
679 base::PlatformFileError FileSystemOperation::SetUpFileSystemPath( 689 base::PlatformFileError FileSystemOperation::SetUpFileSystemPath(
680 const GURL& path_url, 690 const GURL& path_url,
681 FileSystemPath* file_system_path, 691 FileSystemPath* file_system_path,
682 FileSystemFileUtil** file_util, 692 FileSystemFileUtil** file_util,
683 SetUpPathMode mode) { 693 SetUpPathMode mode) {
684 DCHECK(file_system_path); 694 DCHECK(file_system_path);
685 GURL origin_url; 695 GURL origin_url;
686 FileSystemType type; 696 FileSystemType type;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 } 746 }
737 747
738 bool FileSystemOperation::SetPendingOperationType(OperationType type) { 748 bool FileSystemOperation::SetPendingOperationType(OperationType type) {
739 if (pending_operation_ != kOperationNone) 749 if (pending_operation_ != kOperationNone)
740 return false; 750 return false;
741 pending_operation_ = type; 751 pending_operation_ = type;
742 return true; 752 return true;
743 } 753 }
744 754
745 } // namespace fileapi 755 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/file_system_operation.h ('k') | webkit/fileapi/file_system_operation_write_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698