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

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

Issue 12051055: 2nd try: FileAPI: Split recursive remove into multiple tasks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased 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/remove_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 RemoveOperationDelegate::RemoveOperationDelegate(
15 LocalFileSystemOperation* original_operation,
16 const StatusCallback& callback)
17 : original_operation_(original_operation),
18 callback_(callback),
19 inflight_operations_(0) {
20 }
21
22 RemoveOperationDelegate::~RemoveOperationDelegate() {}
23
24 void RemoveOperationDelegate::Run(const FileSystemURL& url) {
25 LocalFileSystemOperation* operation = NewOperation(url);
26 if (!operation)
27 return;
28 operation->RemoveFile(url, base::Bind(
29 &RemoveOperationDelegate::DidTryRemoveFile, AsWeakPtr(), url));
30 }
31
32 void RemoveOperationDelegate::RunRecursively(const FileSystemURL& url) {
33 DCHECK(pending_directories_.empty());
34 pending_directories_.push(url);
35 ProcessNextDirectory(base::PLATFORM_FILE_OK);
36 }
37
38 void RemoveOperationDelegate::DidTryRemoveFile(
39 const FileSystemURL& url,
40 base::PlatformFileError error) {
41 if (error == base::PLATFORM_FILE_OK ||
42 error != base::PLATFORM_FILE_ERROR_NOT_A_FILE) {
43 callback_.Run(error);
44 return;
45 }
46 LocalFileSystemOperation* operation = NewOperation(url);
47 if (!operation)
48 return;
49 operation->RemoveDirectory(url, callback_);
50 }
51
52 void RemoveOperationDelegate::ProcessNextDirectory(
53 base::PlatformFileError error) {
54 if (error != base::PLATFORM_FILE_OK) {
55 callback_.Run(error);
56 return;
57 }
58 if (inflight_operations_ > 0)
59 return;
60 if (pending_directories_.empty()) {
61 RemoveNextDirectory(error);
62 return;
63 }
64 FileSystemURL url = pending_directories_.front();
65 pending_directories_.pop();
66 LocalFileSystemOperation* operation = NewOperation(url);
67 if (!operation)
68 return;
69 inflight_operations_++;
70 operation->ReadDirectory(
71 url, base::Bind(&RemoveOperationDelegate::DidReadDirectory,
72 AsWeakPtr(), url));
73 }
74
75 void RemoveOperationDelegate::DidReadDirectory(
76 const FileSystemURL& parent,
77 base::PlatformFileError error,
78 const FileEntryList& entries,
79 bool has_more) {
80 if (error != base::PLATFORM_FILE_OK) {
81 if (error == base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY) {
82 // The given path may have been a file, so try RemoveFile.
83 inflight_operations_--;
84 DCHECK_GE(inflight_operations_, 0);
85 RemoveFile(parent);
86 return;
87 }
88 callback_.Run(error);
89 return;
90 }
91 for (size_t i = 0; i < entries.size(); i++) {
92 FileSystemURL url = parent.WithPath(parent.path().Append(entries[i].name));
93 if (entries[i].is_directory) {
94 pending_directories_.push(url);
95 continue;
96 }
97 RemoveFile(url);
98 }
99 if (has_more)
100 return;
101
102 to_remove_directories_.push(parent);
103 inflight_operations_--;
104 DCHECK_GE(inflight_operations_, 0);
105 ProcessNextDirectory(base::PLATFORM_FILE_OK);
106 }
107
108 void RemoveOperationDelegate::RemoveFile(const FileSystemURL& url) {
109 LocalFileSystemOperation* operation = NewOperation(url);
110 if (!operation)
111 return;
112 inflight_operations_++;
113 operation->RemoveFile(url, base::Bind(
114 &RemoveOperationDelegate::DidRemoveFile, AsWeakPtr()));
115 }
116
117 void RemoveOperationDelegate::DidRemoveFile(base::PlatformFileError error) {
118 inflight_operations_--;
119 DCHECK_GE(inflight_operations_, 0);
120 if (error != base::PLATFORM_FILE_OK &&
121 error != base::PLATFORM_FILE_ERROR_NOT_FOUND) {
122 callback_.Run(error);
123 return;
124 }
125 ProcessNextDirectory(error);
126 }
127
128 void RemoveOperationDelegate::RemoveNextDirectory(
129 base::PlatformFileError error) {
130 DCHECK_EQ(0, inflight_operations_);
131 DCHECK(pending_directories_.empty());
132 if (error != base::PLATFORM_FILE_OK ||
133 to_remove_directories_.empty()) {
134 callback_.Run(error);
135 return;
136 }
137 FileSystemURL url = to_remove_directories_.top();
138 to_remove_directories_.pop();
139 LocalFileSystemOperation* operation = NewOperation(url);
140 if (!operation)
141 return;
142 operation->RemoveDirectory(url, base::Bind(
143 &RemoveOperationDelegate::RemoveNextDirectory,
144 AsWeakPtr()));
145 }
146
147 LocalFileSystemOperation* RemoveOperationDelegate::NewOperation(
148 const FileSystemURL& url) {
149 base::PlatformFileError error;
150 FileSystemOperation* operation = original_operation_->file_system_context()->
151 CreateFileSystemOperation(url, &error);
152 if (error != base::PLATFORM_FILE_OK) {
153 callback_.Run(error);
154 return NULL;
155 }
156 LocalFileSystemOperation* local_operation =
157 operation->AsLocalFileSystemOperation();
158 DCHECK(local_operation);
159
160 // Let the new operation inherit from the original operation.
161 local_operation->set_overriding_operation_context(
162 original_operation_->operation_context());
163 return local_operation;
164 }
165
166 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/remove_operation_delegate.h ('k') | webkit/fileapi/syncable/syncable_file_system_operation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698