diff options
author | yawano <yawano@chromium.org> | 2015-06-16 23:54:23 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-17 06:56:00 +0000 |
commit | fbdc39ddba07a973c23779f3caa7e110e3e22a52 (patch) | |
tree | 034fb8b90c3de40a4b9d94059f71ae6c0d037da6 /storage | |
parent | 1becf72a2d1b5eec4468cc950142b083e9b24fbe (diff) | |
download | chromium_src-fbdc39ddba07a973c23779f3caa7e110e3e22a52.zip chromium_src-fbdc39ddba07a973c23779f3caa7e110e3e22a52.tar.gz chromium_src-fbdc39ddba07a973c23779f3caa7e110e3e22a52.tar.bz2 |
Recursive operation delegate continues operations with ignoring errors.
Previously recursive operation delegate aborted its operation while an error has happened.
This CL adds a method to run a recursive operation with ignoring errors.
BUG=499642
TEST=content_unittests:RecursiveOperationDelegateTest.*
Review URL: https://codereview.chromium.org/1184343002
Cr-Commit-Position: refs/heads/master@{#334783}
Diffstat (limited to 'storage')
-rw-r--r-- | storage/browser/fileapi/file_system_operation.h | 6 | ||||
-rw-r--r-- | storage/browser/fileapi/recursive_operation_delegate.cc | 63 | ||||
-rw-r--r-- | storage/browser/fileapi/recursive_operation_delegate.h | 21 |
3 files changed, 73 insertions, 17 deletions
diff --git a/storage/browser/fileapi/file_system_operation.h b/storage/browser/fileapi/file_system_operation.h index 4b38da0..bc5bc87 100644 --- a/storage/browser/fileapi/file_system_operation.h +++ b/storage/browser/fileapi/file_system_operation.h @@ -68,6 +68,12 @@ class FileSystemOperation { // Used for CreateFile(), etc. |result| is the return code of the operation. typedef base::Callback<void(base::File::Error result)> StatusCallback; + // Called when an error had happened during operation. + // |url| is the url of processed entry. + // |error| is the error code of the failed operation. + typedef base::Callback<void(const FileSystemURL& url, + base::File::Error error)> ErrorCallback; + // Used for GetMetadata(). |result| is the return code of the operation, // |file_info| is the obtained file info. typedef base::Callback< diff --git a/storage/browser/fileapi/recursive_operation_delegate.cc b/storage/browser/fileapi/recursive_operation_delegate.cc index 609df31..a3cb1a86 100644 --- a/storage/browser/fileapi/recursive_operation_delegate.cc +++ b/storage/browser/fileapi/recursive_operation_delegate.cc @@ -21,7 +21,9 @@ RecursiveOperationDelegate::RecursiveOperationDelegate( FileSystemContext* file_system_context) : file_system_context_(file_system_context), inflight_operations_(0), - canceled_(false) { + canceled_(false), + ignore_error_(false), + failed_some_operations_(false) { } RecursiveOperationDelegate::~RecursiveOperationDelegate() { @@ -40,11 +42,29 @@ void RecursiveOperationDelegate::StartRecursiveOperation( DCHECK_EQ(0, inflight_operations_); callback_ = callback; + + TryProcessFile(root); +} + +void RecursiveOperationDelegate::StartRecursiveOperationWithIgnoringError( + const FileSystemURL& root, + const ErrorCallback& error_callback, + const StatusCallback& status_callback) { + DCHECK(pending_directory_stack_.empty()); + DCHECK(pending_files_.empty()); + DCHECK_EQ(0, inflight_operations_); + + error_callback_ = error_callback; + callback_ = status_callback; + ignore_error_ = true; + + TryProcessFile(root); +} + +void RecursiveOperationDelegate::TryProcessFile(const FileSystemURL& root) { ++inflight_operations_; - ProcessFile( - root, - base::Bind(&RecursiveOperationDelegate::DidTryProcessFile, - AsWeakPtr(), root)); + ProcessFile(root, base::Bind(&RecursiveOperationDelegate::DidTryProcessFile, + AsWeakPtr(), root)); } FileSystemOperationRunner* RecursiveOperationDelegate::operation_runner() { @@ -159,23 +179,31 @@ void RecursiveOperationDelegate::ProcessPendingFiles() { ++inflight_operations_; current_task_runner->PostTask( FROM_HERE, - base::Bind(&RecursiveOperationDelegate::ProcessFile, - AsWeakPtr(), pending_files_.front(), + base::Bind(&RecursiveOperationDelegate::ProcessFile, AsWeakPtr(), + pending_files_.front(), base::Bind(&RecursiveOperationDelegate::DidProcessFile, - AsWeakPtr()))); + AsWeakPtr(), pending_files_.front()))); pending_files_.pop(); } } -void RecursiveOperationDelegate::DidProcessFile( - base::File::Error error) { +void RecursiveOperationDelegate::DidProcessFile(const FileSystemURL& url, + base::File::Error error) { --inflight_operations_; + if (error != base::File::FILE_OK) { - // If an error occurs, invoke Done immediately (even if there remain - // running operations). It is because in the callback, this instance is - // deleted. - Done(error); - return; + if (!ignore_error_) { + // If an error occurs, invoke Done immediately (even if there remain + // running operations). It is because in the callback, this instance is + // deleted. + Done(error); + return; + } else { + failed_some_operations_ = true; + + if (!error_callback_.is_null()) + error_callback_.Run(url, error); + } } ProcessPendingFiles(); @@ -234,7 +262,10 @@ void RecursiveOperationDelegate::Done(base::File::Error error) { if (canceled_ && error == base::File::FILE_OK) { callback_.Run(base::File::FILE_ERROR_ABORT); } else { - callback_.Run(error); + if (ignore_error_ && failed_some_operations_) + callback_.Run(base::File::FILE_ERROR_FAILED); + else + callback_.Run(error); } } diff --git a/storage/browser/fileapi/recursive_operation_delegate.h b/storage/browser/fileapi/recursive_operation_delegate.h index f7f07c2..d120c33 100644 --- a/storage/browser/fileapi/recursive_operation_delegate.h +++ b/storage/browser/fileapi/recursive_operation_delegate.h @@ -28,6 +28,7 @@ class STORAGE_EXPORT RecursiveOperationDelegate : public base::SupportsWeakPtr<RecursiveOperationDelegate> { public: typedef FileSystemOperation::StatusCallback StatusCallback; + typedef FileSystemOperation::ErrorCallback ErrorCallback; typedef FileSystemOperation::FileEntryList FileEntryList; virtual ~RecursiveOperationDelegate(); @@ -108,6 +109,20 @@ class STORAGE_EXPORT RecursiveOperationDelegate void StartRecursiveOperation(const FileSystemURL& root, const StatusCallback& callback); + // Starts to process files/directories recursively from the given |root|. + // Compared with StartRecursiveOperation, this continues operation with + // ignoring erros of ProcessFile. + // + // |error_callback| is fired when a ProcessFile has failed in the middle of + // operations. If some errors had happened, |status_callback| is fired with + // base::File::FILE_ERROR_FAILED at the end. + // + // TODO(yawano): Handle errors of ProcessDirectory as well. + void StartRecursiveOperationWithIgnoringError( + const FileSystemURL& root, + const ErrorCallback& error_callback, + const StatusCallback& status_callback); + FileSystemContext* file_system_context() { return file_system_context_; } const FileSystemContext* file_system_context() const { return file_system_context_; @@ -120,6 +135,7 @@ class STORAGE_EXPORT RecursiveOperationDelegate virtual void OnCancel(); private: + void TryProcessFile(const FileSystemURL& root); void DidTryProcessFile(const FileSystemURL& root, base::File::Error error); void ProcessNextDirectory(); @@ -129,7 +145,7 @@ class STORAGE_EXPORT RecursiveOperationDelegate const FileEntryList& entries, bool has_more); void ProcessPendingFiles(); - void DidProcessFile(base::File::Error error); + void DidProcessFile(const FileSystemURL& url, base::File::Error error); void ProcessSubDirectory(); void DidPostProcessDirectory(base::File::Error error); @@ -138,11 +154,14 @@ class STORAGE_EXPORT RecursiveOperationDelegate FileSystemContext* file_system_context_; StatusCallback callback_; + ErrorCallback error_callback_; std::stack<FileSystemURL> pending_directories_; std::stack<std::queue<FileSystemURL> > pending_directory_stack_; std::queue<FileSystemURL> pending_files_; int inflight_operations_; bool canceled_; + bool ignore_error_; + bool failed_some_operations_; DISALLOW_COPY_AND_ASSIGN(RecursiveOperationDelegate); }; |