OLD | NEW |
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/browser/fileapi/recursive_operation_delegate.h" | 5 #include "storage/browser/fileapi/recursive_operation_delegate.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "webkit/browser/fileapi/file_system_context.h" | 8 #include "storage/browser/fileapi/file_system_context.h" |
9 #include "webkit/browser/fileapi/file_system_operation_runner.h" | 9 #include "storage/browser/fileapi/file_system_operation_runner.h" |
10 | 10 |
11 namespace fileapi { | 11 namespace storage { |
12 | 12 |
13 namespace { | 13 namespace { |
14 // Don't start too many inflight operations. | 14 // Don't start too many inflight operations. |
15 const int kMaxInflightOperations = 5; | 15 const int kMaxInflightOperations = 5; |
16 } | 16 } |
17 | 17 |
18 RecursiveOperationDelegate::RecursiveOperationDelegate( | 18 RecursiveOperationDelegate::RecursiveOperationDelegate( |
19 FileSystemContext* file_system_context) | 19 FileSystemContext* file_system_context) |
20 : file_system_context_(file_system_context), | 20 : file_system_context_(file_system_context), |
21 inflight_operations_(0), | 21 inflight_operations_(0), |
(...skipping 12 matching lines...) Expand all Loading... |
34 const FileSystemURL& root, | 34 const FileSystemURL& root, |
35 const StatusCallback& callback) { | 35 const StatusCallback& callback) { |
36 DCHECK(pending_directory_stack_.empty()); | 36 DCHECK(pending_directory_stack_.empty()); |
37 DCHECK(pending_files_.empty()); | 37 DCHECK(pending_files_.empty()); |
38 DCHECK_EQ(0, inflight_operations_); | 38 DCHECK_EQ(0, inflight_operations_); |
39 | 39 |
40 callback_ = callback; | 40 callback_ = callback; |
41 ++inflight_operations_; | 41 ++inflight_operations_; |
42 ProcessFile( | 42 ProcessFile( |
43 root, | 43 root, |
44 base::Bind(&RecursiveOperationDelegate::DidTryProcessFile, | 44 base::Bind( |
45 AsWeakPtr(), root)); | 45 &RecursiveOperationDelegate::DidTryProcessFile, AsWeakPtr(), root)); |
46 } | 46 } |
47 | 47 |
48 FileSystemOperationRunner* RecursiveOperationDelegate::operation_runner() { | 48 FileSystemOperationRunner* RecursiveOperationDelegate::operation_runner() { |
49 return file_system_context_->operation_runner(); | 49 return file_system_context_->operation_runner(); |
50 } | 50 } |
51 | 51 |
52 void RecursiveOperationDelegate::OnCancel() { | 52 void RecursiveOperationDelegate::OnCancel() { |
53 } | 53 } |
54 | 54 |
55 void RecursiveOperationDelegate::DidTryProcessFile( | 55 void RecursiveOperationDelegate::DidTryProcessFile(const FileSystemURL& root, |
56 const FileSystemURL& root, | 56 base::File::Error error) { |
57 base::File::Error error) { | |
58 DCHECK(pending_directory_stack_.empty()); | 57 DCHECK(pending_directory_stack_.empty()); |
59 DCHECK(pending_files_.empty()); | 58 DCHECK(pending_files_.empty()); |
60 DCHECK_EQ(1, inflight_operations_); | 59 DCHECK_EQ(1, inflight_operations_); |
61 | 60 |
62 --inflight_operations_; | 61 --inflight_operations_; |
63 if (canceled_ || error != base::File::FILE_ERROR_NOT_A_FILE) { | 62 if (canceled_ || error != base::File::FILE_ERROR_NOT_A_FILE) { |
64 Done(error); | 63 Done(error); |
65 return; | 64 return; |
66 } | 65 } |
67 | 66 |
68 pending_directory_stack_.push(std::queue<FileSystemURL>()); | 67 pending_directory_stack_.push(std::queue<FileSystemURL>()); |
69 pending_directory_stack_.top().push(root); | 68 pending_directory_stack_.top().push(root); |
70 ProcessNextDirectory(); | 69 ProcessNextDirectory(); |
71 } | 70 } |
72 | 71 |
73 void RecursiveOperationDelegate::ProcessNextDirectory() { | 72 void RecursiveOperationDelegate::ProcessNextDirectory() { |
74 DCHECK(pending_files_.empty()); | 73 DCHECK(pending_files_.empty()); |
75 DCHECK(!pending_directory_stack_.empty()); | 74 DCHECK(!pending_directory_stack_.empty()); |
76 DCHECK(!pending_directory_stack_.top().empty()); | 75 DCHECK(!pending_directory_stack_.top().empty()); |
77 DCHECK_EQ(0, inflight_operations_); | 76 DCHECK_EQ(0, inflight_operations_); |
78 | 77 |
79 const FileSystemURL& url = pending_directory_stack_.top().front(); | 78 const FileSystemURL& url = pending_directory_stack_.top().front(); |
80 | 79 |
81 ++inflight_operations_; | 80 ++inflight_operations_; |
82 ProcessDirectory( | 81 ProcessDirectory(url, |
83 url, | 82 base::Bind(&RecursiveOperationDelegate::DidProcessDirectory, |
84 base::Bind( | 83 AsWeakPtr())); |
85 &RecursiveOperationDelegate::DidProcessDirectory, AsWeakPtr())); | |
86 } | 84 } |
87 | 85 |
88 void RecursiveOperationDelegate::DidProcessDirectory( | 86 void RecursiveOperationDelegate::DidProcessDirectory(base::File::Error error) { |
89 base::File::Error error) { | |
90 DCHECK(pending_files_.empty()); | 87 DCHECK(pending_files_.empty()); |
91 DCHECK(!pending_directory_stack_.empty()); | 88 DCHECK(!pending_directory_stack_.empty()); |
92 DCHECK(!pending_directory_stack_.top().empty()); | 89 DCHECK(!pending_directory_stack_.top().empty()); |
93 DCHECK_EQ(1, inflight_operations_); | 90 DCHECK_EQ(1, inflight_operations_); |
94 | 91 |
95 --inflight_operations_; | 92 --inflight_operations_; |
96 if (canceled_ || error != base::File::FILE_OK) { | 93 if (canceled_ || error != base::File::FILE_OK) { |
97 Done(error); | 94 Done(error); |
98 return; | 95 return; |
99 } | 96 } |
100 | 97 |
101 const FileSystemURL& parent = pending_directory_stack_.top().front(); | 98 const FileSystemURL& parent = pending_directory_stack_.top().front(); |
102 pending_directory_stack_.push(std::queue<FileSystemURL>()); | 99 pending_directory_stack_.push(std::queue<FileSystemURL>()); |
103 operation_runner()->ReadDirectory( | 100 operation_runner()->ReadDirectory( |
104 parent, | 101 parent, |
105 base::Bind(&RecursiveOperationDelegate::DidReadDirectory, | 102 base::Bind( |
106 AsWeakPtr(), parent)); | 103 &RecursiveOperationDelegate::DidReadDirectory, AsWeakPtr(), parent)); |
107 } | 104 } |
108 | 105 |
109 void RecursiveOperationDelegate::DidReadDirectory( | 106 void RecursiveOperationDelegate::DidReadDirectory(const FileSystemURL& parent, |
110 const FileSystemURL& parent, | 107 base::File::Error error, |
111 base::File::Error error, | 108 const FileEntryList& entries, |
112 const FileEntryList& entries, | 109 bool has_more) { |
113 bool has_more) { | |
114 DCHECK(!pending_directory_stack_.empty()); | 110 DCHECK(!pending_directory_stack_.empty()); |
115 DCHECK_EQ(0, inflight_operations_); | 111 DCHECK_EQ(0, inflight_operations_); |
116 | 112 |
117 if (canceled_ || error != base::File::FILE_OK) { | 113 if (canceled_ || error != base::File::FILE_OK) { |
118 Done(error); | 114 Done(error); |
119 return; | 115 return; |
120 } | 116 } |
121 | 117 |
122 for (size_t i = 0; i < entries.size(); i++) { | 118 for (size_t i = 0; i < entries.size(); i++) { |
123 FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL( | 119 FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL( |
(...skipping 27 matching lines...) Expand all Loading... |
151 | 147 |
152 // Run ProcessFile in parallel (upto kMaxInflightOperations). | 148 // Run ProcessFile in parallel (upto kMaxInflightOperations). |
153 scoped_refptr<base::MessageLoopProxy> current_message_loop = | 149 scoped_refptr<base::MessageLoopProxy> current_message_loop = |
154 base::MessageLoopProxy::current(); | 150 base::MessageLoopProxy::current(); |
155 while (!pending_files_.empty() && | 151 while (!pending_files_.empty() && |
156 inflight_operations_ < kMaxInflightOperations) { | 152 inflight_operations_ < kMaxInflightOperations) { |
157 ++inflight_operations_; | 153 ++inflight_operations_; |
158 current_message_loop->PostTask( | 154 current_message_loop->PostTask( |
159 FROM_HERE, | 155 FROM_HERE, |
160 base::Bind(&RecursiveOperationDelegate::ProcessFile, | 156 base::Bind(&RecursiveOperationDelegate::ProcessFile, |
161 AsWeakPtr(), pending_files_.front(), | 157 AsWeakPtr(), |
| 158 pending_files_.front(), |
162 base::Bind(&RecursiveOperationDelegate::DidProcessFile, | 159 base::Bind(&RecursiveOperationDelegate::DidProcessFile, |
163 AsWeakPtr()))); | 160 AsWeakPtr()))); |
164 pending_files_.pop(); | 161 pending_files_.pop(); |
165 } | 162 } |
166 } | 163 } |
167 | 164 |
168 void RecursiveOperationDelegate::DidProcessFile( | 165 void RecursiveOperationDelegate::DidProcessFile(base::File::Error error) { |
169 base::File::Error error) { | |
170 --inflight_operations_; | 166 --inflight_operations_; |
171 if (error != base::File::FILE_OK) { | 167 if (error != base::File::FILE_OK) { |
172 // If an error occurs, invoke Done immediately (even if there remain | 168 // If an error occurs, invoke Done immediately (even if there remain |
173 // running operations). It is because in the callback, this instance is | 169 // running operations). It is because in the callback, this instance is |
174 // deleted. | 170 // deleted. |
175 Done(error); | 171 Done(error); |
176 return; | 172 return; |
177 } | 173 } |
178 | 174 |
179 ProcessPendingFiles(); | 175 ProcessPendingFiles(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 225 } |
230 | 226 |
231 void RecursiveOperationDelegate::Done(base::File::Error error) { | 227 void RecursiveOperationDelegate::Done(base::File::Error error) { |
232 if (canceled_ && error == base::File::FILE_OK) { | 228 if (canceled_ && error == base::File::FILE_OK) { |
233 callback_.Run(base::File::FILE_ERROR_ABORT); | 229 callback_.Run(base::File::FILE_ERROR_ABORT); |
234 } else { | 230 } else { |
235 callback_.Run(error); | 231 callback_.Run(error); |
236 } | 232 } |
237 } | 233 } |
238 | 234 |
239 } // namespace fileapi | 235 } // namespace storage |
OLD | NEW |