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

Side by Side Diff: webkit/browser/fileapi/file_system_operation_runner.cc

Issue 23898002: Dispatch FileSystemOperationRunner callbacks always synchronously (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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/file_system_operation_runner.h" 5 #include "webkit/browser/fileapi/file_system_operation_runner.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/stl_util.h"
8 #include "net/url_request/url_request_context.h" 10 #include "net/url_request/url_request_context.h"
9 #include "webkit/browser/fileapi/file_observers.h" 11 #include "webkit/browser/fileapi/file_observers.h"
10 #include "webkit/browser/fileapi/file_stream_writer.h" 12 #include "webkit/browser/fileapi/file_stream_writer.h"
11 #include "webkit/browser/fileapi/file_system_context.h" 13 #include "webkit/browser/fileapi/file_system_context.h"
12 #include "webkit/browser/fileapi/file_system_operation_impl.h" 14 #include "webkit/browser/fileapi/file_system_operation_impl.h"
13 #include "webkit/browser/fileapi/file_writer_delegate.h" 15 #include "webkit/browser/fileapi/file_writer_delegate.h"
14 #include "webkit/common/blob/shareable_file_reference.h" 16 #include "webkit/common/blob/shareable_file_reference.h"
15 17
16 namespace fileapi { 18 namespace fileapi {
17 19
18 typedef FileSystemOperationRunner::OperationID OperationID; 20 typedef FileSystemOperationRunner::OperationID OperationID;
19 21
20 const OperationID FileSystemOperationRunner::kErrorOperationID = -1; 22 class FileSystemOperationRunner::BeginOperationScoper
23 : public base::SupportsWeakPtr<
24 FileSystemOperationRunner::BeginOperationScoper> {
25 public:
26 BeginOperationScoper() {}
27 private:
28 DISALLOW_COPY_AND_ASSIGN(BeginOperationScoper);
29 };
30
31 FileSystemOperationRunner::OperationHandle::OperationHandle() {}
32 FileSystemOperationRunner::OperationHandle::~OperationHandle() {}
21 33
22 FileSystemOperationRunner::~FileSystemOperationRunner() { 34 FileSystemOperationRunner::~FileSystemOperationRunner() {
23 } 35 }
24 36
25 void FileSystemOperationRunner::Shutdown() { 37 void FileSystemOperationRunner::Shutdown() {
26 operations_.Clear(); 38 operations_.Clear();
27 } 39 }
28 40
29 OperationID FileSystemOperationRunner::CreateFile( 41 OperationID FileSystemOperationRunner::CreateFile(
30 const FileSystemURL& url, 42 const FileSystemURL& url,
31 bool exclusive, 43 bool exclusive,
32 const StatusCallback& callback) { 44 const StatusCallback& callback) {
33 base::PlatformFileError error = base::PLATFORM_FILE_OK; 45 base::PlatformFileError error = base::PLATFORM_FILE_OK;
34 FileSystemOperation* operation = 46 FileSystemOperation* operation =
35 file_system_context_->CreateFileSystemOperation(url, &error); 47 file_system_context_->CreateFileSystemOperation(url, &error);
48
49 BeginOperationScoper scope;
50 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
36 if (!operation) { 51 if (!operation) {
37 callback.Run(error); 52 DidFinish(handle, callback, error);
38 return kErrorOperationID; 53 return handle.id;
39 } 54 }
40 OperationID id = operations_.Add(operation); 55 PrepareForWrite(handle.id, url);
41 PrepareForWrite(id, url);
42 operation->CreateFile( 56 operation->CreateFile(
43 url, exclusive, 57 url, exclusive,
44 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 58 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
45 id, callback)); 59 handle, callback));
46 return id; 60 return handle.id;
47 } 61 }
48 62
49 OperationID FileSystemOperationRunner::CreateDirectory( 63 OperationID FileSystemOperationRunner::CreateDirectory(
50 const FileSystemURL& url, 64 const FileSystemURL& url,
51 bool exclusive, 65 bool exclusive,
52 bool recursive, 66 bool recursive,
53 const StatusCallback& callback) { 67 const StatusCallback& callback) {
54 base::PlatformFileError error = base::PLATFORM_FILE_OK; 68 base::PlatformFileError error = base::PLATFORM_FILE_OK;
55 FileSystemOperation* operation = 69 FileSystemOperation* operation =
56 file_system_context_->CreateFileSystemOperation(url, &error); 70 file_system_context_->CreateFileSystemOperation(url, &error);
71 BeginOperationScoper scope;
72 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
57 if (!operation) { 73 if (!operation) {
58 callback.Run(error); 74 DidFinish(handle, callback, error);
59 return kErrorOperationID; 75 return handle.id;
60 } 76 }
61 OperationID id = operations_.Add(operation); 77 PrepareForWrite(handle.id, url);
62 PrepareForWrite(id, url);
63 operation->CreateDirectory( 78 operation->CreateDirectory(
64 url, exclusive, recursive, 79 url, exclusive, recursive,
65 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 80 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
66 id, callback)); 81 handle, callback));
67 return id; 82 return handle.id;
68 } 83 }
69 84
70 OperationID FileSystemOperationRunner::Copy( 85 OperationID FileSystemOperationRunner::Copy(
71 const FileSystemURL& src_url, 86 const FileSystemURL& src_url,
72 const FileSystemURL& dest_url, 87 const FileSystemURL& dest_url,
73 const StatusCallback& callback) { 88 const StatusCallback& callback) {
74 base::PlatformFileError error = base::PLATFORM_FILE_OK; 89 base::PlatformFileError error = base::PLATFORM_FILE_OK;
75 FileSystemOperation* operation = 90 FileSystemOperation* operation =
76 file_system_context_->CreateFileSystemOperation(dest_url, &error); 91 file_system_context_->CreateFileSystemOperation(dest_url, &error);
92 BeginOperationScoper scope;
93 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
77 if (!operation) { 94 if (!operation) {
78 callback.Run(error); 95 DidFinish(handle, callback, error);
79 return kErrorOperationID; 96 return handle.id;
80 } 97 }
81 OperationID id = operations_.Add(operation); 98 PrepareForWrite(handle.id, dest_url);
82 PrepareForWrite(id, dest_url); 99 PrepareForRead(handle.id, src_url);
83 PrepareForRead(id, src_url);
84 operation->Copy( 100 operation->Copy(
85 src_url, dest_url, 101 src_url, dest_url,
86 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 102 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
87 id, callback)); 103 handle, callback));
88 return id; 104 return handle.id;
89 } 105 }
90 106
91 OperationID FileSystemOperationRunner::Move( 107 OperationID FileSystemOperationRunner::Move(
92 const FileSystemURL& src_url, 108 const FileSystemURL& src_url,
93 const FileSystemURL& dest_url, 109 const FileSystemURL& dest_url,
94 const StatusCallback& callback) { 110 const StatusCallback& callback) {
95 base::PlatformFileError error = base::PLATFORM_FILE_OK; 111 base::PlatformFileError error = base::PLATFORM_FILE_OK;
96 FileSystemOperation* operation = 112 FileSystemOperation* operation =
97 file_system_context_->CreateFileSystemOperation(dest_url, &error); 113 file_system_context_->CreateFileSystemOperation(dest_url, &error);
114 BeginOperationScoper scope;
115 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
98 if (!operation) { 116 if (!operation) {
99 callback.Run(error); 117 DidFinish(handle, callback, error);
100 return kErrorOperationID; 118 return handle.id;
101 } 119 }
102 OperationID id = operations_.Add(operation); 120 PrepareForWrite(handle.id, dest_url);
103 PrepareForWrite(id, dest_url); 121 PrepareForWrite(handle.id, src_url);
104 PrepareForWrite(id, src_url);
105 operation->Move( 122 operation->Move(
106 src_url, dest_url, 123 src_url, dest_url,
107 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 124 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
108 id, callback)); 125 handle, callback));
109 return id; 126 return handle.id;
110 } 127 }
111 128
112 OperationID FileSystemOperationRunner::DirectoryExists( 129 OperationID FileSystemOperationRunner::DirectoryExists(
113 const FileSystemURL& url, 130 const FileSystemURL& url,
114 const StatusCallback& callback) { 131 const StatusCallback& callback) {
115 base::PlatformFileError error = base::PLATFORM_FILE_OK; 132 base::PlatformFileError error = base::PLATFORM_FILE_OK;
116 FileSystemOperation* operation = 133 FileSystemOperation* operation =
117 file_system_context_->CreateFileSystemOperation(url, &error); 134 file_system_context_->CreateFileSystemOperation(url, &error);
135 BeginOperationScoper scope;
136 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
118 if (!operation) { 137 if (!operation) {
119 callback.Run(error); 138 DidFinish(handle, callback, error);
120 return kErrorOperationID; 139 return handle.id;
121 } 140 }
122 OperationID id = operations_.Add(operation); 141 PrepareForRead(handle.id, url);
123 PrepareForRead(id, url);
124 operation->DirectoryExists( 142 operation->DirectoryExists(
125 url, 143 url,
126 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 144 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
127 id, callback)); 145 handle, callback));
128 return id; 146 return handle.id;
129 } 147 }
130 148
131 OperationID FileSystemOperationRunner::FileExists( 149 OperationID FileSystemOperationRunner::FileExists(
132 const FileSystemURL& url, 150 const FileSystemURL& url,
133 const StatusCallback& callback) { 151 const StatusCallback& callback) {
134 base::PlatformFileError error = base::PLATFORM_FILE_OK; 152 base::PlatformFileError error = base::PLATFORM_FILE_OK;
135 FileSystemOperation* operation = 153 FileSystemOperation* operation =
136 file_system_context_->CreateFileSystemOperation(url, &error); 154 file_system_context_->CreateFileSystemOperation(url, &error);
155 BeginOperationScoper scope;
156 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
137 if (!operation) { 157 if (!operation) {
138 callback.Run(error); 158 DidFinish(handle, callback, error);
139 return kErrorOperationID; 159 return handle.id;
140 } 160 }
141 OperationID id = operations_.Add(operation); 161 PrepareForRead(handle.id, url);
142 PrepareForRead(id, url);
143 operation->FileExists( 162 operation->FileExists(
144 url, 163 url,
145 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 164 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
146 id, callback)); 165 handle, callback));
147 return id; 166 return handle.id;
148 } 167 }
149 168
150 OperationID FileSystemOperationRunner::GetMetadata( 169 OperationID FileSystemOperationRunner::GetMetadata(
151 const FileSystemURL& url, 170 const FileSystemURL& url,
152 const GetMetadataCallback& callback) { 171 const GetMetadataCallback& callback) {
153 base::PlatformFileError error = base::PLATFORM_FILE_OK; 172 base::PlatformFileError error = base::PLATFORM_FILE_OK;
154 FileSystemOperation* operation = 173 FileSystemOperation* operation =
155 file_system_context_->CreateFileSystemOperation(url, &error); 174 file_system_context_->CreateFileSystemOperation(url, &error);
175 BeginOperationScoper scope;
176 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
156 if (!operation) { 177 if (!operation) {
157 callback.Run(error, base::PlatformFileInfo()); 178 DidGetMetadata(handle, callback, error, base::PlatformFileInfo());
158 return kErrorOperationID; 179 return handle.id;
159 } 180 }
160 OperationID id = operations_.Add(operation); 181 PrepareForRead(handle.id, url);
161 PrepareForRead(id, url);
162 operation->GetMetadata( 182 operation->GetMetadata(
163 url, 183 url,
164 base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(), 184 base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(),
165 id, callback)); 185 handle, callback));
166 return id; 186 return handle.id;
167 } 187 }
168 188
169 OperationID FileSystemOperationRunner::ReadDirectory( 189 OperationID FileSystemOperationRunner::ReadDirectory(
170 const FileSystemURL& url, 190 const FileSystemURL& url,
171 const ReadDirectoryCallback& callback) { 191 const ReadDirectoryCallback& callback) {
172 base::PlatformFileError error = base::PLATFORM_FILE_OK; 192 base::PlatformFileError error = base::PLATFORM_FILE_OK;
173 FileSystemOperation* operation = 193 FileSystemOperation* operation =
174 file_system_context_->CreateFileSystemOperation(url, &error); 194 file_system_context_->CreateFileSystemOperation(url, &error);
195 BeginOperationScoper scope;
196 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
175 if (!operation) { 197 if (!operation) {
176 callback.Run(error, std::vector<DirectoryEntry>(), false); 198 DidReadDirectory(handle, callback, error, std::vector<DirectoryEntry>(),
177 return kErrorOperationID; 199 false);
200 return handle.id;
178 } 201 }
179 OperationID id = operations_.Add(operation); 202 PrepareForRead(handle.id, url);
180 PrepareForRead(id, url);
181 operation->ReadDirectory( 203 operation->ReadDirectory(
182 url, 204 url,
183 base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(), 205 base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(),
184 id, callback)); 206 handle, callback));
185 return id; 207 return handle.id;
186 } 208 }
187 209
188 OperationID FileSystemOperationRunner::Remove( 210 OperationID FileSystemOperationRunner::Remove(
189 const FileSystemURL& url, bool recursive, 211 const FileSystemURL& url, bool recursive,
190 const StatusCallback& callback) { 212 const StatusCallback& callback) {
191 base::PlatformFileError error = base::PLATFORM_FILE_OK; 213 base::PlatformFileError error = base::PLATFORM_FILE_OK;
192 FileSystemOperation* operation = 214 FileSystemOperation* operation =
193 file_system_context_->CreateFileSystemOperation(url, &error); 215 file_system_context_->CreateFileSystemOperation(url, &error);
216 BeginOperationScoper scope;
217 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
194 if (!operation) { 218 if (!operation) {
195 callback.Run(error); 219 DidFinish(handle, callback, error);
196 return kErrorOperationID; 220 return handle.id;
197 } 221 }
198 OperationID id = operations_.Add(operation); 222 PrepareForWrite(handle.id, url);
199 PrepareForWrite(id, url);
200 operation->Remove( 223 operation->Remove(
201 url, recursive, 224 url, recursive,
202 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 225 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
203 id, callback)); 226 handle, callback));
204 return id; 227 return handle.id;
205 } 228 }
206 229
207 OperationID FileSystemOperationRunner::Write( 230 OperationID FileSystemOperationRunner::Write(
208 const net::URLRequestContext* url_request_context, 231 const net::URLRequestContext* url_request_context,
209 const FileSystemURL& url, 232 const FileSystemURL& url,
210 const GURL& blob_url, 233 const GURL& blob_url,
211 int64 offset, 234 int64 offset,
212 const WriteCallback& callback) { 235 const WriteCallback& callback) {
213 base::PlatformFileError error = base::PLATFORM_FILE_OK; 236 base::PlatformFileError error = base::PLATFORM_FILE_OK;
214 FileSystemOperation* operation = 237 FileSystemOperation* operation =
215 file_system_context_->CreateFileSystemOperation(url, &error); 238 file_system_context_->CreateFileSystemOperation(url, &error);
239
240 BeginOperationScoper scope;
241 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
216 if (!operation) { 242 if (!operation) {
217 callback.Run(error, 0, true); 243 DidWrite(handle, callback, error, 0, true);
218 return kErrorOperationID; 244 return handle.id;
219 } 245 }
220 246
221 scoped_ptr<FileStreamWriter> writer( 247 scoped_ptr<FileStreamWriter> writer(
222 file_system_context_->CreateFileStreamWriter(url, offset)); 248 file_system_context_->CreateFileStreamWriter(url, offset));
223 if (!writer) { 249 if (!writer) {
224 // Write is not supported. 250 // Write is not supported.
225 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, 0, true); 251 DidWrite(handle, callback, base::PLATFORM_FILE_ERROR_SECURITY, 0, true);
226 return kErrorOperationID; 252 return handle.id;
227 } 253 }
228 254
229 DCHECK(blob_url.is_valid()); 255 DCHECK(blob_url.is_valid());
230 scoped_ptr<FileWriterDelegate> writer_delegate( 256 scoped_ptr<FileWriterDelegate> writer_delegate(
231 new FileWriterDelegate(writer.Pass())); 257 new FileWriterDelegate(writer.Pass()));
232 scoped_ptr<net::URLRequest> blob_request(url_request_context->CreateRequest( 258 scoped_ptr<net::URLRequest> blob_request(url_request_context->CreateRequest(
233 blob_url, writer_delegate.get())); 259 blob_url, writer_delegate.get()));
234 260
235 OperationID id = operations_.Add(operation); 261 PrepareForWrite(handle.id, url);
236 PrepareForWrite(id, url);
237 operation->Write( 262 operation->Write(
238 url, writer_delegate.Pass(), blob_request.Pass(), 263 url, writer_delegate.Pass(), blob_request.Pass(),
239 base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), 264 base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
240 id, callback)); 265 handle, callback));
241 return id; 266 return handle.id;
242 } 267 }
243 268
244 OperationID FileSystemOperationRunner::Truncate( 269 OperationID FileSystemOperationRunner::Truncate(
245 const FileSystemURL& url, int64 length, 270 const FileSystemURL& url, int64 length,
246 const StatusCallback& callback) { 271 const StatusCallback& callback) {
247 base::PlatformFileError error = base::PLATFORM_FILE_OK; 272 base::PlatformFileError error = base::PLATFORM_FILE_OK;
248 FileSystemOperation* operation = 273 FileSystemOperation* operation =
249 file_system_context_->CreateFileSystemOperation(url, &error); 274 file_system_context_->CreateFileSystemOperation(url, &error);
275 BeginOperationScoper scope;
276 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
250 if (!operation) { 277 if (!operation) {
251 callback.Run(error); 278 DidFinish(handle, callback, error);
252 return kErrorOperationID; 279 return handle.id;
253 } 280 }
254 OperationID id = operations_.Add(operation); 281 PrepareForWrite(handle.id, url);
255 PrepareForWrite(id, url);
256 operation->Truncate( 282 operation->Truncate(
257 url, length, 283 url, length,
258 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 284 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
259 id, callback)); 285 handle, callback));
260 return id; 286 return handle.id;
261 } 287 }
262 288
263 void FileSystemOperationRunner::Cancel( 289 void FileSystemOperationRunner::Cancel(
264 OperationID id, 290 OperationID id,
265 const StatusCallback& callback) { 291 const StatusCallback& callback) {
266 FileSystemOperation* operation = operations_.Lookup(id); 292 if (ContainsKey(finished_operations_, id)) {
267 if (!operation) { 293 DCHECK(!ContainsKey(stray_cancel_callbacks_, id));
268 // The operation is already finished; report that we failed to stop it. 294 stray_cancel_callbacks_[id] = callback;
269 callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
270 return; 295 return;
271 } 296 }
297 FileSystemOperation* operation = operations_.Lookup(id);
298 DCHECK(operation);
272 operation->Cancel(callback); 299 operation->Cancel(callback);
273 } 300 }
274 301
275 OperationID FileSystemOperationRunner::TouchFile( 302 OperationID FileSystemOperationRunner::TouchFile(
276 const FileSystemURL& url, 303 const FileSystemURL& url,
277 const base::Time& last_access_time, 304 const base::Time& last_access_time,
278 const base::Time& last_modified_time, 305 const base::Time& last_modified_time,
279 const StatusCallback& callback) { 306 const StatusCallback& callback) {
280 base::PlatformFileError error = base::PLATFORM_FILE_OK; 307 base::PlatformFileError error = base::PLATFORM_FILE_OK;
281 FileSystemOperation* operation = 308 FileSystemOperation* operation =
282 file_system_context_->CreateFileSystemOperation(url, &error); 309 file_system_context_->CreateFileSystemOperation(url, &error);
310 BeginOperationScoper scope;
311 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
283 if (!operation) { 312 if (!operation) {
284 callback.Run(error); 313 DidFinish(handle, callback, error);
285 return kErrorOperationID; 314 return handle.id;
286 } 315 }
287 OperationID id = operations_.Add(operation); 316 PrepareForWrite(handle.id, url);
288 PrepareForWrite(id, url);
289 operation->TouchFile( 317 operation->TouchFile(
290 url, last_access_time, last_modified_time, 318 url, last_access_time, last_modified_time,
291 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 319 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
292 id, callback)); 320 handle, callback));
293 return id; 321 return handle.id;
294 } 322 }
295 323
296 OperationID FileSystemOperationRunner::OpenFile( 324 OperationID FileSystemOperationRunner::OpenFile(
297 const FileSystemURL& url, 325 const FileSystemURL& url,
298 int file_flags, 326 int file_flags,
299 base::ProcessHandle peer_handle, 327 base::ProcessHandle peer_handle,
300 const OpenFileCallback& callback) { 328 const OpenFileCallback& callback) {
301 base::PlatformFileError error = base::PLATFORM_FILE_OK; 329 base::PlatformFileError error = base::PLATFORM_FILE_OK;
302 FileSystemOperation* operation = 330 FileSystemOperation* operation =
303 file_system_context_->CreateFileSystemOperation(url, &error); 331 file_system_context_->CreateFileSystemOperation(url, &error);
332 BeginOperationScoper scope;
333 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
304 if (!operation) { 334 if (!operation) {
305 callback.Run(error, base::kInvalidPlatformFileValue, 335 DidOpenFile(handle, callback, error, base::kInvalidPlatformFileValue,
306 base::Closure(), base::ProcessHandle()); 336 base::Closure(), base::ProcessHandle());
307 return kErrorOperationID; 337 return handle.id;
308 } 338 }
309 OperationID id = operations_.Add(operation);
310 if (file_flags & 339 if (file_flags &
311 (base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_OPEN_ALWAYS | 340 (base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_OPEN_ALWAYS |
312 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_TRUNCATED | 341 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_TRUNCATED |
313 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_WRITE | 342 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_WRITE |
314 base::PLATFORM_FILE_DELETE_ON_CLOSE | 343 base::PLATFORM_FILE_DELETE_ON_CLOSE |
315 base::PLATFORM_FILE_WRITE_ATTRIBUTES)) { 344 base::PLATFORM_FILE_WRITE_ATTRIBUTES)) {
316 PrepareForWrite(id, url); 345 PrepareForWrite(handle.id, url);
317 } else { 346 } else {
318 PrepareForRead(id, url); 347 PrepareForRead(handle.id, url);
319 } 348 }
320 operation->OpenFile( 349 operation->OpenFile(
321 url, file_flags, peer_handle, 350 url, file_flags, peer_handle,
322 base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(), 351 base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(),
323 id, callback)); 352 handle, callback));
324 return id; 353 return handle.id;
325 } 354 }
326 355
327 OperationID FileSystemOperationRunner::CreateSnapshotFile( 356 OperationID FileSystemOperationRunner::CreateSnapshotFile(
328 const FileSystemURL& url, 357 const FileSystemURL& url,
329 const SnapshotFileCallback& callback) { 358 const SnapshotFileCallback& callback) {
330 base::PlatformFileError error = base::PLATFORM_FILE_OK; 359 base::PlatformFileError error = base::PLATFORM_FILE_OK;
331 FileSystemOperation* operation = 360 FileSystemOperation* operation =
332 file_system_context_->CreateFileSystemOperation(url, &error); 361 file_system_context_->CreateFileSystemOperation(url, &error);
362 BeginOperationScoper scope;
363 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
333 if (!operation) { 364 if (!operation) {
334 callback.Run(error, base::PlatformFileInfo(), base::FilePath(), NULL); 365 DidCreateSnapshot(handle, callback, error, base::PlatformFileInfo(),
335 return kErrorOperationID; 366 base::FilePath(), NULL);
367 return handle.id;
336 } 368 }
337 OperationID id = operations_.Add(operation); 369 PrepareForRead(handle.id, url);
338 PrepareForRead(id, url);
339 operation->CreateSnapshotFile( 370 operation->CreateSnapshotFile(
340 url, 371 url,
341 base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(), 372 base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(),
342 id, callback)); 373 handle, callback));
343 return id; 374 return handle.id;
344 } 375 }
345 376
346 OperationID FileSystemOperationRunner::CopyInForeignFile( 377 OperationID FileSystemOperationRunner::CopyInForeignFile(
347 const base::FilePath& src_local_disk_path, 378 const base::FilePath& src_local_disk_path,
348 const FileSystemURL& dest_url, 379 const FileSystemURL& dest_url,
349 const StatusCallback& callback) { 380 const StatusCallback& callback) {
350 base::PlatformFileError error = base::PLATFORM_FILE_OK; 381 base::PlatformFileError error = base::PLATFORM_FILE_OK;
351 FileSystemOperation* operation = 382 FileSystemOperation* operation =
352 file_system_context_->CreateFileSystemOperation(dest_url, &error); 383 file_system_context_->CreateFileSystemOperation(dest_url, &error);
384 BeginOperationScoper scope;
385 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
353 if (!operation) { 386 if (!operation) {
354 callback.Run(error); 387 DidFinish(handle, callback, error);
355 return kErrorOperationID; 388 return handle.id;
356 } 389 }
357 OperationID id = operations_.Add(operation);
358 operation->CopyInForeignFile( 390 operation->CopyInForeignFile(
359 src_local_disk_path, dest_url, 391 src_local_disk_path, dest_url,
360 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 392 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
361 id, callback)); 393 handle, callback));
362 return id; 394 return handle.id;
363 } 395 }
364 396
365 OperationID FileSystemOperationRunner::RemoveFile( 397 OperationID FileSystemOperationRunner::RemoveFile(
366 const FileSystemURL& url, 398 const FileSystemURL& url,
367 const StatusCallback& callback) { 399 const StatusCallback& callback) {
368 base::PlatformFileError error = base::PLATFORM_FILE_OK; 400 base::PlatformFileError error = base::PLATFORM_FILE_OK;
369 FileSystemOperation* operation = 401 FileSystemOperation* operation =
370 file_system_context_->CreateFileSystemOperation(url, &error); 402 file_system_context_->CreateFileSystemOperation(url, &error);
403 BeginOperationScoper scope;
404 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
371 if (!operation) { 405 if (!operation) {
372 callback.Run(error); 406 DidFinish(handle, callback, error);
373 return kErrorOperationID; 407 return handle.id;
374 } 408 }
375 OperationID id = operations_.Add(operation);
376 operation->RemoveFile( 409 operation->RemoveFile(
377 url, 410 url,
378 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 411 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
379 id, callback)); 412 handle, callback));
380 return id; 413 return handle.id;
381 } 414 }
382 415
383 OperationID FileSystemOperationRunner::RemoveDirectory( 416 OperationID FileSystemOperationRunner::RemoveDirectory(
384 const FileSystemURL& url, 417 const FileSystemURL& url,
385 const StatusCallback& callback) { 418 const StatusCallback& callback) {
386 base::PlatformFileError error = base::PLATFORM_FILE_OK; 419 base::PlatformFileError error = base::PLATFORM_FILE_OK;
387 FileSystemOperation* operation = 420 FileSystemOperation* operation =
388 file_system_context_->CreateFileSystemOperation(url, &error); 421 file_system_context_->CreateFileSystemOperation(url, &error);
422 BeginOperationScoper scope;
423 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
389 if (!operation) { 424 if (!operation) {
390 callback.Run(error); 425 DidFinish(handle, callback, error);
391 return kErrorOperationID; 426 return handle.id;
392 } 427 }
393 OperationID id = operations_.Add(operation);
394 operation->RemoveDirectory( 428 operation->RemoveDirectory(
395 url, 429 url,
396 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 430 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
397 id, callback)); 431 handle, callback));
398 return id; 432 return handle.id;
399 } 433 }
400 434
401 OperationID FileSystemOperationRunner::CopyFileLocal( 435 OperationID FileSystemOperationRunner::CopyFileLocal(
402 const FileSystemURL& src_url, 436 const FileSystemURL& src_url,
403 const FileSystemURL& dest_url, 437 const FileSystemURL& dest_url,
404 const StatusCallback& callback) { 438 const StatusCallback& callback) {
405 base::PlatformFileError error = base::PLATFORM_FILE_OK; 439 base::PlatformFileError error = base::PLATFORM_FILE_OK;
406 FileSystemOperation* operation = 440 FileSystemOperation* operation =
407 file_system_context_->CreateFileSystemOperation(src_url, &error); 441 file_system_context_->CreateFileSystemOperation(src_url, &error);
442 BeginOperationScoper scope;
443 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
408 if (!operation) { 444 if (!operation) {
409 callback.Run(error); 445 DidFinish(handle, callback, error);
410 return kErrorOperationID; 446 return handle.id;
411 } 447 }
412 OperationID id = operations_.Add(operation);
413 operation->CopyFileLocal( 448 operation->CopyFileLocal(
414 src_url, dest_url, 449 src_url, dest_url,
415 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 450 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
416 id, callback)); 451 handle, callback));
417 return id; 452 return handle.id;
418 } 453 }
419 454
420 OperationID FileSystemOperationRunner::MoveFileLocal( 455 OperationID FileSystemOperationRunner::MoveFileLocal(
421 const FileSystemURL& src_url, 456 const FileSystemURL& src_url,
422 const FileSystemURL& dest_url, 457 const FileSystemURL& dest_url,
423 const StatusCallback& callback) { 458 const StatusCallback& callback) {
424 base::PlatformFileError error = base::PLATFORM_FILE_OK; 459 base::PlatformFileError error = base::PLATFORM_FILE_OK;
425 FileSystemOperation* operation = 460 FileSystemOperation* operation =
426 file_system_context_->CreateFileSystemOperation(src_url, &error); 461 file_system_context_->CreateFileSystemOperation(src_url, &error);
462 BeginOperationScoper scope;
463 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
427 if (!operation) { 464 if (!operation) {
428 callback.Run(error); 465 DidFinish(handle, callback, error);
429 return kErrorOperationID; 466 return handle.id;
430 } 467 }
431 OperationID id = operations_.Add(operation);
432 operation->MoveFileLocal( 468 operation->MoveFileLocal(
433 src_url, dest_url, 469 src_url, dest_url,
434 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), 470 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
435 id, callback)); 471 handle, callback));
436 return id; 472 return handle.id;
437 } 473 }
438 474
439 base::PlatformFileError FileSystemOperationRunner::SyncGetPlatformPath( 475 base::PlatformFileError FileSystemOperationRunner::SyncGetPlatformPath(
440 const FileSystemURL& url, 476 const FileSystemURL& url,
441 base::FilePath* platform_path) { 477 base::FilePath* platform_path) {
442 base::PlatformFileError error = base::PLATFORM_FILE_OK; 478 base::PlatformFileError error = base::PLATFORM_FILE_OK;
443 FileSystemOperation* operation = 479 FileSystemOperation* operation =
444 file_system_context_->CreateFileSystemOperation(url, &error); 480 file_system_context_->CreateFileSystemOperation(url, &error);
445 if (!operation) 481 if (!operation)
446 return error; 482 return error;
447 return operation->SyncGetPlatformPath(url, platform_path); 483 return operation->SyncGetPlatformPath(url, platform_path);
448 } 484 }
449 485
450 FileSystemOperationRunner::FileSystemOperationRunner( 486 FileSystemOperationRunner::FileSystemOperationRunner(
451 FileSystemContext* file_system_context) 487 FileSystemContext* file_system_context)
452 : file_system_context_(file_system_context) {} 488 : file_system_context_(file_system_context) {}
453 489
454 void FileSystemOperationRunner::DidFinish( 490 void FileSystemOperationRunner::DidFinish(
455 OperationID id, 491 OperationHandle handle,
456 const StatusCallback& callback, 492 const StatusCallback& callback,
457 base::PlatformFileError rv) { 493 base::PlatformFileError rv) {
494 if (handle.scope) {
495 finished_operations_.insert(handle.id);
496 base::MessageLoopProxy::current()->PostTask(
497 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidFinish,
498 AsWeakPtr(), handle, callback, rv));
499 return;
500 }
458 callback.Run(rv); 501 callback.Run(rv);
459 FinishOperation(id); 502 FinishOperation(handle.id);
460 } 503 }
461 504
462 void FileSystemOperationRunner::DidGetMetadata( 505 void FileSystemOperationRunner::DidGetMetadata(
463 OperationID id, 506 OperationHandle handle,
464 const GetMetadataCallback& callback, 507 const GetMetadataCallback& callback,
465 base::PlatformFileError rv, 508 base::PlatformFileError rv,
466 const base::PlatformFileInfo& file_info) { 509 const base::PlatformFileInfo& file_info) {
510 if (handle.scope) {
511 finished_operations_.insert(handle.id);
512 base::MessageLoopProxy::current()->PostTask(
513 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidGetMetadata,
514 AsWeakPtr(), handle, callback, rv, file_info));
515 return;
516 }
467 callback.Run(rv, file_info); 517 callback.Run(rv, file_info);
468 FinishOperation(id); 518 FinishOperation(handle.id);
469 } 519 }
470 520
471 void FileSystemOperationRunner::DidReadDirectory( 521 void FileSystemOperationRunner::DidReadDirectory(
472 OperationID id, 522 OperationHandle handle,
473 const ReadDirectoryCallback& callback, 523 const ReadDirectoryCallback& callback,
474 base::PlatformFileError rv, 524 base::PlatformFileError rv,
475 const std::vector<DirectoryEntry>& entries, 525 const std::vector<DirectoryEntry>& entries,
476 bool has_more) { 526 bool has_more) {
527 if (handle.scope) {
528 finished_operations_.insert(handle.id);
529 base::MessageLoopProxy::current()->PostTask(
530 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidReadDirectory,
531 AsWeakPtr(), handle, callback, rv,
532 entries, has_more));
533 return;
534 }
477 callback.Run(rv, entries, has_more); 535 callback.Run(rv, entries, has_more);
478 if (rv != base::PLATFORM_FILE_OK || !has_more) 536 if (rv != base::PLATFORM_FILE_OK || !has_more)
479 FinishOperation(id); 537 FinishOperation(handle.id);
480 } 538 }
481 539
482 void FileSystemOperationRunner::DidWrite( 540 void FileSystemOperationRunner::DidWrite(
483 OperationID id, 541 OperationHandle handle,
484 const WriteCallback& callback, 542 const WriteCallback& callback,
485 base::PlatformFileError rv, 543 base::PlatformFileError rv,
486 int64 bytes, 544 int64 bytes,
487 bool complete) { 545 bool complete) {
546 if (handle.scope) {
547 finished_operations_.insert(handle.id);
548 base::MessageLoopProxy::current()->PostTask(
549 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
550 handle, callback, rv, bytes, complete));
551 return;
552 }
488 callback.Run(rv, bytes, complete); 553 callback.Run(rv, bytes, complete);
489 if (rv != base::PLATFORM_FILE_OK || complete) 554 if (rv != base::PLATFORM_FILE_OK || complete)
490 FinishOperation(id); 555 FinishOperation(handle.id);
491 } 556 }
492 557
493 void FileSystemOperationRunner::DidOpenFile( 558 void FileSystemOperationRunner::DidOpenFile(
494 OperationID id, 559 OperationHandle handle,
495 const OpenFileCallback& callback, 560 const OpenFileCallback& callback,
496 base::PlatformFileError rv, 561 base::PlatformFileError rv,
497 base::PlatformFile file, 562 base::PlatformFile file,
498 const base::Closure& on_close_callback, 563 const base::Closure& on_close_callback,
499 base::ProcessHandle peer_handle) { 564 base::ProcessHandle peer_handle) {
565 if (handle.scope) {
566 finished_operations_.insert(handle.id);
567 base::MessageLoopProxy::current()->PostTask(
568 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidOpenFile,
569 AsWeakPtr(), handle, callback, rv, file,
570 on_close_callback, peer_handle));
571 return;
572 }
500 callback.Run(rv, file, on_close_callback, peer_handle); 573 callback.Run(rv, file, on_close_callback, peer_handle);
501 FinishOperation(id); 574 FinishOperation(handle.id);
502 } 575 }
503 576
504 void FileSystemOperationRunner::DidCreateSnapshot( 577 void FileSystemOperationRunner::DidCreateSnapshot(
505 OperationID id, 578 OperationHandle handle,
506 const SnapshotFileCallback& callback, 579 const SnapshotFileCallback& callback,
507 base::PlatformFileError rv, 580 base::PlatformFileError rv,
508 const base::PlatformFileInfo& file_info, 581 const base::PlatformFileInfo& file_info,
509 const base::FilePath& platform_path, 582 const base::FilePath& platform_path,
510 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { 583 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
584 if (handle.scope) {
585 finished_operations_.insert(handle.id);
586 base::MessageLoopProxy::current()->PostTask(
587 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidCreateSnapshot,
588 AsWeakPtr(), handle, callback, rv, file_info,
589 platform_path, file_ref));
590 return;
591 }
511 callback.Run(rv, file_info, platform_path, file_ref); 592 callback.Run(rv, file_info, platform_path, file_ref);
512 FinishOperation(id); 593 FinishOperation(handle.id);
513 } 594 }
514 595
515 void FileSystemOperationRunner::PrepareForWrite(OperationID id, 596 void FileSystemOperationRunner::PrepareForWrite(OperationID id,
516 const FileSystemURL& url) { 597 const FileSystemURL& url) {
517 if (file_system_context_->GetUpdateObservers(url.type())) { 598 if (file_system_context_->GetUpdateObservers(url.type())) {
518 file_system_context_->GetUpdateObservers(url.type())->Notify( 599 file_system_context_->GetUpdateObservers(url.type())->Notify(
519 &FileUpdateObserver::OnStartUpdate, MakeTuple(url)); 600 &FileUpdateObserver::OnStartUpdate, MakeTuple(url));
520 } 601 }
521 write_target_urls_[id].insert(url); 602 write_target_urls_[id].insert(url);
522 } 603 }
523 604
524 void FileSystemOperationRunner::PrepareForRead(OperationID id, 605 void FileSystemOperationRunner::PrepareForRead(OperationID id,
525 const FileSystemURL& url) { 606 const FileSystemURL& url) {
526 if (file_system_context_->GetAccessObservers(url.type())) { 607 if (file_system_context_->GetAccessObservers(url.type())) {
527 file_system_context_->GetAccessObservers(url.type())->Notify( 608 file_system_context_->GetAccessObservers(url.type())->Notify(
528 &FileAccessObserver::OnAccess, MakeTuple(url)); 609 &FileAccessObserver::OnAccess, MakeTuple(url));
529 } 610 }
530 } 611 }
531 612
613 FileSystemOperationRunner::OperationHandle
614 FileSystemOperationRunner::BeginOperation(
615 FileSystemOperation* operation,
616 base::WeakPtr<BeginOperationScoper> scope) {
617 OperationHandle handle;
618 handle.id = operations_.Add(operation);
619 handle.scope = scope;
620 return handle;
621 }
622
532 void FileSystemOperationRunner::FinishOperation(OperationID id) { 623 void FileSystemOperationRunner::FinishOperation(OperationID id) {
533 OperationToURLSet::iterator found = write_target_urls_.find(id); 624 OperationToURLSet::iterator found = write_target_urls_.find(id);
534 if (found != write_target_urls_.end()) { 625 if (found != write_target_urls_.end()) {
535 const FileSystemURLSet& urls = found->second; 626 const FileSystemURLSet& urls = found->second;
536 for (FileSystemURLSet::const_iterator iter = urls.begin(); 627 for (FileSystemURLSet::const_iterator iter = urls.begin();
537 iter != urls.end(); ++iter) { 628 iter != urls.end(); ++iter) {
538 if (file_system_context_->GetUpdateObservers(iter->type())) { 629 if (file_system_context_->GetUpdateObservers(iter->type())) {
539 file_system_context_->GetUpdateObservers(iter->type())->Notify( 630 file_system_context_->GetUpdateObservers(iter->type())->Notify(
540 &FileUpdateObserver::OnEndUpdate, MakeTuple(*iter)); 631 &FileUpdateObserver::OnEndUpdate, MakeTuple(*iter));
541 } 632 }
542 } 633 }
543 write_target_urls_.erase(found); 634 write_target_urls_.erase(found);
544 } 635 }
545 DCHECK(operations_.Lookup(id)); 636 DCHECK(operations_.Lookup(id));
546 operations_.Remove(id); 637 operations_.Remove(id);
638 finished_operations_.erase(id);
639
640 // Dispatch stray cancel callback if exists.
641 std::map<OperationID, StatusCallback>::iterator found_cancel =
642 stray_cancel_callbacks_.find(id);
643 if (found_cancel != stray_cancel_callbacks_.end()) {
644 // This cancel has been requested after the operation has finished,
645 // so report that we failed to stop it.
646 found_cancel->second.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
647 stray_cancel_callbacks_.erase(found_cancel);
648 }
547 } 649 }
548 650
549 } // namespace fileapi 651 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698