Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |