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

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

Issue 4821005: Make FileSystemOperation's lifetime more explicit. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased (upon codereview/4879001) Created 10 years, 1 month 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/file_system_operation.h" 5 #include "webkit/fileapi/file_system_operation.h"
6 6
7 #include "base/time.h" 7 #include "base/time.h"
8 #include "net/url_request/url_request_context.h" 8 #include "net/url_request/url_request_context.h"
9 #include "webkit/fileapi/file_system_callback_dispatcher.h" 9 #include "webkit/fileapi/file_system_callback_dispatcher.h"
10 #include "webkit/fileapi/file_writer_delegate.h" 10 #include "webkit/fileapi/file_writer_delegate.h"
11 11
12 namespace fileapi { 12 namespace fileapi {
13 13
14 FileSystemOperation::FileSystemOperation( 14 FileSystemOperation::FileSystemOperation(
15 FileSystemCallbackDispatcher* dispatcher, 15 FileSystemCallbackDispatcher* dispatcher,
16 scoped_refptr<base::MessageLoopProxy> proxy) 16 scoped_refptr<base::MessageLoopProxy> proxy)
17 : proxy_(proxy), 17 : proxy_(proxy),
18 dispatcher_(dispatcher), 18 dispatcher_(dispatcher),
19 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 19 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
20 cancel_operation_(NULL) {
21 DCHECK(dispatcher); 20 DCHECK(dispatcher);
22 #ifndef NDEBUG 21 #ifndef NDEBUG
23 pending_operation_ = kOperationNone; 22 pending_operation_ = kOperationNone;
24 #endif 23 #endif
25 } 24 }
26 25
27 FileSystemOperation::~FileSystemOperation() { 26 FileSystemOperation::~FileSystemOperation() {
28 if (file_writer_delegate_.get()) 27 if (file_writer_delegate_.get())
29 base::FileUtilProxy::Close(proxy_, file_writer_delegate_->file(), NULL); 28 base::FileUtilProxy::Close(proxy_, file_writer_delegate_->file(), NULL);
30 } 29 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 callback_factory_.NewCallback( 151 callback_factory_.NewCallback(
153 &FileSystemOperation::OnFileOpenedForWrite)); 152 &FileSystemOperation::OnFileOpenedForWrite));
154 } 153 }
155 154
156 void FileSystemOperation::OnFileOpenedForWrite( 155 void FileSystemOperation::OnFileOpenedForWrite(
157 base::PlatformFileError rv, 156 base::PlatformFileError rv,
158 base::PassPlatformFile file, 157 base::PassPlatformFile file,
159 bool created) { 158 bool created) {
160 if (base::PLATFORM_FILE_OK != rv) { 159 if (base::PLATFORM_FILE_OK != rv) {
161 dispatcher_->DidFail(rv); 160 dispatcher_->DidFail(rv);
161 delete this;
162 return; 162 return;
163 } 163 }
164 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); 164 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get());
165 } 165 }
166 166
167 void FileSystemOperation::Truncate(const FilePath& path, int64 length) { 167 void FileSystemOperation::Truncate(const FilePath& path, int64 length) {
168 #ifndef NDEBUG 168 #ifndef NDEBUG
169 DCHECK(kOperationNone == pending_operation_); 169 DCHECK(kOperationNone == pending_operation_);
170 pending_operation_ = kOperationTruncate; 170 pending_operation_ = kOperationTruncate;
171 #endif 171 #endif
(...skipping 10 matching lines...) Expand all
182 pending_operation_ = kOperationTouchFile; 182 pending_operation_ = kOperationTouchFile;
183 #endif 183 #endif
184 184
185 base::FileUtilProxy::Touch( 185 base::FileUtilProxy::Touch(
186 proxy_, path, last_access_time, last_modified_time, 186 proxy_, path, last_access_time, last_modified_time,
187 callback_factory_.NewCallback(&FileSystemOperation::DidTouchFile)); 187 callback_factory_.NewCallback(&FileSystemOperation::DidTouchFile));
188 } 188 }
189 189
190 // We can only get here on a write or truncate that's not yet completed. 190 // We can only get here on a write or truncate that's not yet completed.
191 // We don't support cancelling any other operation at this time. 191 // We don't support cancelling any other operation at this time.
192 void FileSystemOperation::Cancel(FileSystemOperation* cancel_operation) { 192 void FileSystemOperation::Cancel(FileSystemOperation* cancel_operation_ptr) {
193 scoped_ptr<FileSystemOperation> cancel_operation(cancel_operation_ptr);
193 if (file_writer_delegate_.get()) { 194 if (file_writer_delegate_.get()) {
194 #ifndef NDEBUG 195 #ifndef NDEBUG
195 DCHECK(kOperationWrite == pending_operation_); 196 DCHECK(kOperationWrite == pending_operation_);
196 #endif 197 #endif
197 // Writes are done without proxying through FileUtilProxy after the initial 198 // Writes are done without proxying through FileUtilProxy after the initial
198 // opening of the PlatformFile. All state changes are done on this thread, 199 // opening of the PlatformFile. All state changes are done on this thread,
199 // so we're guaranteed to be able to shut down atomically. We do need to 200 // so we're guaranteed to be able to shut down atomically. We do need to
200 // check that the file has been opened [which means the blob_request_ has 201 // check that the file has been opened [which means the blob_request_ has
201 // been created], so we know how much we need to do. 202 // been created], so we know how much we need to do.
202 if (blob_request_.get()) 203 if (blob_request_.get())
203 // This halts any calls to file_writer_delegate_ from blob_request_. 204 // This halts any calls to file_writer_delegate_ from blob_request_.
204 blob_request_->Cancel(); 205 blob_request_->Cancel();
205 206
206 // This deletes us, and by proxy deletes file_writer_delegate_ if any.
207 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); 207 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT);
208 cancel_operation->dispatcher_->DidSucceed(); 208 cancel_operation->dispatcher()->DidSucceed();
209 delete this;
209 } else { 210 } else {
210 #ifndef NDEBUG 211 #ifndef NDEBUG
211 DCHECK(kOperationTruncate == pending_operation_); 212 DCHECK(kOperationTruncate == pending_operation_);
212 #endif 213 #endif
213 // We're cancelling a truncate operation, but we can't actually stop it 214 // We're cancelling a truncate operation, but we can't actually stop it
214 // since it's been proxied to another thread. We need to save the 215 // since it's been proxied to another thread. We need to save the
215 // cancel_operation so that when the truncate returns, it can see that it's 216 // cancel_operation so that when the truncate returns, it can see that it's
216 // been cancelled, report it, and report that the cancel has succeeded. 217 // been cancelled, report it, and report that the cancel has succeeded.
217 cancel_operation_ = cancel_operation; 218 DCHECK(!cancel_operation_.get());
219 cancel_operation_.swap(cancel_operation);
218 } 220 }
219 } 221 }
220 222
221 void FileSystemOperation::DidEnsureFileExistsExclusive( 223 void FileSystemOperation::DidEnsureFileExistsExclusive(
222 base::PlatformFileError rv, bool created) { 224 base::PlatformFileError rv, bool created) {
223 if (rv == base::PLATFORM_FILE_OK && !created) 225 if (rv == base::PLATFORM_FILE_OK && !created) {
224 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); 226 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS);
225 else 227 delete this;
228 } else
226 DidFinishFileOperation(rv); 229 DidFinishFileOperation(rv);
227 } 230 }
228 231
229 void FileSystemOperation::DidEnsureFileExistsNonExclusive( 232 void FileSystemOperation::DidEnsureFileExistsNonExclusive(
230 base::PlatformFileError rv, bool /* created */) { 233 base::PlatformFileError rv, bool /* created */) {
231 DidFinishFileOperation(rv); 234 DidFinishFileOperation(rv);
232 } 235 }
233 236
234 void FileSystemOperation::DidFinishFileOperation( 237 void FileSystemOperation::DidFinishFileOperation(
235 base::PlatformFileError rv) { 238 base::PlatformFileError rv) {
236 if (cancel_operation_) { 239 if (cancel_operation_.get()) {
237 #ifndef NDEBUG 240 #ifndef NDEBUG
238 DCHECK(kOperationTruncate == pending_operation_); 241 DCHECK(kOperationTruncate == pending_operation_);
239 #endif 242 #endif
240 FileSystemOperation *cancel_op = cancel_operation_; 243
241 // This call deletes us, so we have to extract cancel_op first.
242 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); 244 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT);
243 cancel_op->dispatcher_->DidSucceed(); 245 cancel_operation_->dispatcher()->DidSucceed();
244 } else if (rv == base::PLATFORM_FILE_OK) { 246 } else if (rv == base::PLATFORM_FILE_OK) {
245 dispatcher_->DidSucceed(); 247 dispatcher_->DidSucceed();
246 } else { 248 } else {
247 dispatcher_->DidFail(rv); 249 dispatcher_->DidFail(rv);
248 } 250 }
251 delete this;
249 } 252 }
250 253
251 void FileSystemOperation::DidDirectoryExists( 254 void FileSystemOperation::DidDirectoryExists(
252 base::PlatformFileError rv, 255 base::PlatformFileError rv,
253 const base::PlatformFileInfo& file_info) { 256 const base::PlatformFileInfo& file_info) {
254 if (rv == base::PLATFORM_FILE_OK) { 257 if (rv == base::PLATFORM_FILE_OK) {
255 if (file_info.is_directory) 258 if (file_info.is_directory)
256 dispatcher_->DidSucceed(); 259 dispatcher_->DidSucceed();
257 else 260 else
258 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_FAILED); 261 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_FAILED);
259 } else { 262 } else {
260 dispatcher_->DidFail(rv); 263 dispatcher_->DidFail(rv);
261 } 264 }
265 delete this;
262 } 266 }
263 267
264 void FileSystemOperation::DidFileExists( 268 void FileSystemOperation::DidFileExists(
265 base::PlatformFileError rv, 269 base::PlatformFileError rv,
266 const base::PlatformFileInfo& file_info) { 270 const base::PlatformFileInfo& file_info) {
267 if (rv == base::PLATFORM_FILE_OK) { 271 if (rv == base::PLATFORM_FILE_OK) {
268 if (file_info.is_directory) 272 if (file_info.is_directory)
269 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_FAILED); 273 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_FAILED);
270 else 274 else
271 dispatcher_->DidSucceed(); 275 dispatcher_->DidSucceed();
272 } else { 276 } else {
273 dispatcher_->DidFail(rv); 277 dispatcher_->DidFail(rv);
274 } 278 }
279 delete this;
275 } 280 }
276 281
277 void FileSystemOperation::DidGetMetadata( 282 void FileSystemOperation::DidGetMetadata(
278 base::PlatformFileError rv, 283 base::PlatformFileError rv,
279 const base::PlatformFileInfo& file_info) { 284 const base::PlatformFileInfo& file_info) {
280 if (rv == base::PLATFORM_FILE_OK) 285 if (rv == base::PLATFORM_FILE_OK)
281 dispatcher_->DidReadMetadata(file_info); 286 dispatcher_->DidReadMetadata(file_info);
282 else 287 else
283 dispatcher_->DidFail(rv); 288 dispatcher_->DidFail(rv);
289 delete this;
284 } 290 }
285 291
286 void FileSystemOperation::DidReadDirectory( 292 void FileSystemOperation::DidReadDirectory(
287 base::PlatformFileError rv, 293 base::PlatformFileError rv,
288 const std::vector<base::FileUtilProxy::Entry>& entries) { 294 const std::vector<base::FileUtilProxy::Entry>& entries) {
289 if (rv == base::PLATFORM_FILE_OK) 295 if (rv == base::PLATFORM_FILE_OK)
290 dispatcher_->DidReadDirectory(entries, false /* has_more */); 296 dispatcher_->DidReadDirectory(entries, false /* has_more */);
291 else 297 else
292 dispatcher_->DidFail(rv); 298 dispatcher_->DidFail(rv);
299 delete this;
293 } 300 }
294 301
295 void FileSystemOperation::DidWrite( 302 void FileSystemOperation::DidWrite(
296 base::PlatformFileError rv, 303 base::PlatformFileError rv,
297 int64 bytes, 304 int64 bytes,
298 bool complete) { 305 bool complete) {
299 if (rv == base::PLATFORM_FILE_OK) 306 if (rv == base::PLATFORM_FILE_OK)
300 dispatcher_->DidWrite(bytes, complete); 307 dispatcher_->DidWrite(bytes, complete);
301 else 308 else
302 dispatcher_->DidFail(rv); 309 dispatcher_->DidFail(rv);
310 if (complete || rv != base::PLATFORM_FILE_OK)
311 delete this;
303 } 312 }
304 313
305 void FileSystemOperation::DidTouchFile(base::PlatformFileError rv) { 314 void FileSystemOperation::DidTouchFile(base::PlatformFileError rv) {
306 if (rv == base::PLATFORM_FILE_OK) 315 if (rv == base::PLATFORM_FILE_OK)
307 dispatcher_->DidSucceed(); 316 dispatcher_->DidSucceed();
308 else 317 else
309 dispatcher_->DidFail(rv); 318 dispatcher_->DidFail(rv);
319 delete this;
310 } 320 }
311 321
312 } // namespace fileapi 322 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698