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

Side by Side Diff: webkit/fileapi/recursive_operation_delegate.cc

Issue 12051010: (For-try) Divide recursive Copy/Move into multiple async tasks (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: test fix Created 7 years, 11 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
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/fileapi/recursive_operation_delegate.h"
6
7 #include "base/bind.h"
8 #include "webkit/fileapi/file_system_context.h"
9 #include "webkit/fileapi/file_system_operation_context.h"
10 #include "webkit/fileapi/local_file_system_operation.h"
11
12 namespace fileapi {
13
14 RecursiveOperationDelegate::RecursiveOperationDelegate(
15 LocalFileSystemOperation* original_operation)
16 : original_operation_(original_operation),
17 inflight_operations_(0) {
18 }
19
20 RecursiveOperationDelegate::~RecursiveOperationDelegate() {}
21
22 void RecursiveOperationDelegate::StartRecursiveOperation(
23 const FileSystemURL& root,
24 const StatusCallback& callback) {
25 callback_ = callback;
26 pending_directories_.push(root);
27 ProcessNextDirectory(base::PLATFORM_FILE_OK);
28 }
29
30 LocalFileSystemOperation* RecursiveOperationDelegate::NewOperation(
31 const FileSystemURL& url,
32 base::PlatformFileError* error_out) {
33 base::PlatformFileError error = base::PLATFORM_FILE_OK;
34 FileSystemOperation* operation = original_operation_->file_system_context()->
35 CreateFileSystemOperation(url, &error);
36 if (error != base::PLATFORM_FILE_OK) {
37 if (error_out)
38 *error_out = error;
39 return NULL;
40 }
41 LocalFileSystemOperation* local_operation =
42 operation->AsLocalFileSystemOperation();
43 DCHECK(local_operation);
44
45 // Let the new operation inherit from the original operation.
46 local_operation->set_overriding_operation_context(
47 original_operation_->operation_context());
48 if (error_out)
49 *error_out = base::PLATFORM_FILE_OK;
50 return local_operation;
51 }
52
53 FileSystemContext* RecursiveOperationDelegate::file_system_context() {
54 return original_operation_->file_system_context();
55 }
56
57 void RecursiveOperationDelegate::ProcessNextDirectory(
58 base::PlatformFileError error) {
59 if (error != base::PLATFORM_FILE_OK) {
60 callback_.Run(error);
61 return;
62 }
63 if (inflight_operations_ > 0)
64 return;
65 if (pending_directories_.empty()) {
66 callback_.Run(error);
67 return;
68 }
69 FileSystemURL url = pending_directories_.front();
70 pending_directories_.pop();
71 LocalFileSystemOperation* operation = NewOperation(url, &error);
72 if (!operation) {
73 callback_.Run(error);
74 return;
75 }
76 inflight_operations_++;
77 ProcessDirectory(
78 url, base::Bind(&RecursiveOperationDelegate::DidProcessDirectory,
79 AsWeakPtr(), url));
80 }
81
82 void RecursiveOperationDelegate::DidProcessFile(base::PlatformFileError error) {
83 inflight_operations_--;
84 DCHECK_GE(inflight_operations_, 0);
85 ProcessNextDirectory(error);
86 }
87
88 void RecursiveOperationDelegate::DidProcessDirectory(
89 const FileSystemURL& url,
90 base::PlatformFileError error) {
91 if (error != base::PLATFORM_FILE_OK) {
92 callback_.Run(error);
93 return;
94 }
95 LocalFileSystemOperation* operation = NewOperation(url, &error);
96 if (!operation) {
97 callback_.Run(error);
98 return;
99 }
100 operation->ReadDirectory(
101 url, base::Bind(&RecursiveOperationDelegate::DidReadDirectory,
102 AsWeakPtr(), url));
103 }
104
105 void RecursiveOperationDelegate::DidReadDirectory(
106 const FileSystemURL& parent,
107 base::PlatformFileError error,
108 const FileEntryList& entries,
109 bool has_more) {
110 if (error != base::PLATFORM_FILE_OK) {
111 if (error == base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY) {
112 // The given path may have been a file, so try RemoveFile now.
113 ProcessFile(parent,
114 base::Bind(&RecursiveOperationDelegate::DidTryProcessFile,
115 AsWeakPtr(), error));
116 return;
117 }
118 callback_.Run(error);
119 return;
120 }
121 for (size_t i = 0; i < entries.size(); i++) {
122 FileSystemURL url = parent.WithPath(parent.path().Append(entries[i].name));
123 if (entries[i].is_directory) {
124 pending_directories_.push(url);
125 continue;
126 }
127 inflight_operations_++;
128 ProcessFile(url, base::Bind(&RecursiveOperationDelegate::DidProcessFile,
129 AsWeakPtr()));
130 }
131 if (has_more)
132 return;
133
134 inflight_operations_--;
135 DCHECK_GE(inflight_operations_, 0);
136 ProcessNextDirectory(base::PLATFORM_FILE_OK);
137 }
138
139 void RecursiveOperationDelegate::DidTryProcessFile(
140 base::PlatformFileError previous_error,
141 base::PlatformFileError error) {
142 if (error == base::PLATFORM_FILE_ERROR_NOT_A_FILE) {
143 // It wasn't a file either; returns with the previous error.
144 callback_.Run(previous_error);
145 return;
146 }
147 DidProcessFile(error);
148 }
149
150 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698