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 |