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

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

Issue 12036022: Split recursive Copy/Move into async tasks and support cross operation (in local case) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 10 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
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 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/remove_operation_delegate.h" 5 #include "webkit/fileapi/remove_operation_delegate.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "webkit/fileapi/file_system_context.h" 8 #include "webkit/fileapi/file_system_context.h"
9 #include "webkit/fileapi/file_system_operation_context.h" 9 #include "webkit/fileapi/file_system_operation_context.h"
10 #include "webkit/fileapi/local_file_system_operation.h" 10 #include "webkit/fileapi/local_file_system_operation.h"
11 11
12 namespace fileapi { 12 namespace fileapi {
13 13
14 RemoveOperationDelegate::RemoveOperationDelegate( 14 RemoveOperationDelegate::RemoveOperationDelegate(
15 LocalFileSystemOperation* original_operation, 15 LocalFileSystemOperation* original_operation,
16 const FileSystemURL& url,
16 const StatusCallback& callback) 17 const StatusCallback& callback)
17 : original_operation_(original_operation), 18 : RecursiveOperationDelegate(original_operation),
18 callback_(callback), 19 url_(url),
19 inflight_operations_(0) { 20 callback_(callback) {
20 } 21 }
21 22
22 RemoveOperationDelegate::~RemoveOperationDelegate() {} 23 RemoveOperationDelegate::~RemoveOperationDelegate() {}
23 24
24 void RemoveOperationDelegate::Run(const FileSystemURL& url) { 25 void RemoveOperationDelegate::Run() {
25 LocalFileSystemOperation* operation = NewOperation(url); 26 base::PlatformFileError error;
26 if (!operation) 27 LocalFileSystemOperation* operation = NewOperation(url_, &error);
28 if (!operation) {
29 callback_.Run(error);
27 return; 30 return;
28 operation->RemoveFile(url, base::Bind( 31 }
29 &RemoveOperationDelegate::DidTryRemoveFile, AsWeakPtr(), url)); 32 operation->RemoveFile(url_, base::Bind(
33 &RemoveOperationDelegate::DidTryRemoveFile, AsWeakPtr()));
30 } 34 }
31 35
32 void RemoveOperationDelegate::RunRecursively(const FileSystemURL& url) { 36 void RemoveOperationDelegate::RunRecursively() {
33 DCHECK(pending_directories_.empty()); 37 StartRecursiveOperation(
34 pending_directories_.push(url); 38 url_,
35 ProcessNextDirectory(base::PLATFORM_FILE_OK); 39 base::Bind(&RemoveOperationDelegate::RemoveNextDirectory, AsWeakPtr()));
40 }
41
42 void RemoveOperationDelegate::ProcessFile(const FileSystemURL& url,
43 const StatusCallback& callback) {
44 base::PlatformFileError error;
45 LocalFileSystemOperation* operation = NewOperation(url, &error);
46 if (!operation) {
47 callback.Run(error);
48 return;
49 }
50 if (to_remove_directories_.size() == 1u &&
51 to_remove_directories_.top() == url) {
52 // We seem to have been re-directed from ProcessDirectory.
53 to_remove_directories_.pop();
54 }
55 operation->RemoveFile(url, base::Bind(
56 &RemoveOperationDelegate::DidRemoveFile, AsWeakPtr(), callback));
57 }
58
59 void RemoveOperationDelegate::ProcessDirectory(const FileSystemURL& url,
60 const StatusCallback& callback) {
61 to_remove_directories_.push(url);
62 callback.Run(base::PLATFORM_FILE_OK);
36 } 63 }
37 64
38 void RemoveOperationDelegate::DidTryRemoveFile( 65 void RemoveOperationDelegate::DidTryRemoveFile(
39 const FileSystemURL& url,
40 base::PlatformFileError error) { 66 base::PlatformFileError error) {
41 if (error == base::PLATFORM_FILE_OK || 67 if (error == base::PLATFORM_FILE_OK ||
42 error != base::PLATFORM_FILE_ERROR_NOT_A_FILE) { 68 error != base::PLATFORM_FILE_ERROR_NOT_A_FILE) {
43 callback_.Run(error); 69 callback_.Run(error);
44 return; 70 return;
45 } 71 }
46 LocalFileSystemOperation* operation = NewOperation(url); 72 LocalFileSystemOperation* operation = NewOperation(url_, &error);
47 if (!operation) 73 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); 74 callback_.Run(error);
56 return; 75 return;
57 } 76 }
58 if (inflight_operations_ > 0) 77 operation->RemoveDirectory(url_, callback_);
59 return; 78 }
60 if (pending_directories_.empty()) { 79
61 RemoveNextDirectory(error); 80 void RemoveOperationDelegate::DidRemoveFile(const StatusCallback& callback,
81 base::PlatformFileError error) {
82 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) {
83 callback.Run(base::PLATFORM_FILE_OK);
62 return; 84 return;
63 } 85 }
64 FileSystemURL url = pending_directories_.front(); 86 callback.Run(error);
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 } 87 }
127 88
128 void RemoveOperationDelegate::RemoveNextDirectory( 89 void RemoveOperationDelegate::RemoveNextDirectory(
129 base::PlatformFileError error) { 90 base::PlatformFileError error) {
130 DCHECK_EQ(0, inflight_operations_);
131 DCHECK(pending_directories_.empty());
132 if (error != base::PLATFORM_FILE_OK || 91 if (error != base::PLATFORM_FILE_OK ||
133 to_remove_directories_.empty()) { 92 to_remove_directories_.empty()) {
134 callback_.Run(error); 93 callback_.Run(error);
135 return; 94 return;
136 } 95 }
137 FileSystemURL url = to_remove_directories_.top(); 96 FileSystemURL url = to_remove_directories_.top();
138 to_remove_directories_.pop(); 97 to_remove_directories_.pop();
139 LocalFileSystemOperation* operation = NewOperation(url); 98 LocalFileSystemOperation* operation = NewOperation(url, &error);
140 if (!operation) 99 if (!operation) {
100 callback_.Run(error);
141 return; 101 return;
102 }
142 operation->RemoveDirectory(url, base::Bind( 103 operation->RemoveDirectory(url, base::Bind(
143 &RemoveOperationDelegate::RemoveNextDirectory, 104 &RemoveOperationDelegate::RemoveNextDirectory,
144 AsWeakPtr())); 105 AsWeakPtr()));
145 } 106 }
146 107
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 108 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/remove_operation_delegate.h ('k') | webkit/fileapi/syncable/syncable_file_system_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698