summaryrefslogtreecommitdiffstats
path: root/storage
diff options
context:
space:
mode:
authoryawano <yawano@chromium.org>2015-06-16 23:54:23 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-17 06:56:00 +0000
commitfbdc39ddba07a973c23779f3caa7e110e3e22a52 (patch)
tree034fb8b90c3de40a4b9d94059f71ae6c0d037da6 /storage
parent1becf72a2d1b5eec4468cc950142b083e9b24fbe (diff)
downloadchromium_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.h6
-rw-r--r--storage/browser/fileapi/recursive_operation_delegate.cc63
-rw-r--r--storage/browser/fileapi/recursive_operation_delegate.h21
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);
};