summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-10 17:52:43 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-10 17:52:43 +0000
commit2c02c8d3eb2827b2d2c9b5e300a7cf49f5c2624a (patch)
tree3b74668cbd3f3d7e3f8725a949f92cf85c318e04 /webkit
parent312d44ffbf5671224e50754d690dfdc98aad0fc2 (diff)
downloadchromium_src-2c02c8d3eb2827b2d2c9b5e300a7cf49f5c2624a.zip
chromium_src-2c02c8d3eb2827b2d2c9b5e300a7cf49f5c2624a.tar.gz
chromium_src-2c02c8d3eb2827b2d2c9b5e300a7cf49f5c2624a.tar.bz2
Make FileSystemOperation NOT self-destruct
This architecture was found to bring lots of undesirable complexity in the codebase. This should become much simpler. BUG=176444 TEST=unit_tests:*File*, content_unittests:*File*, browser_tests:*File* NOTRY=true Review URL: https://chromiumcodereview.appspot.com/16413007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205243 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/browser/chromeos/fileapi/remote_file_system_operation.cc120
-rw-r--r--webkit/browser/chromeos/fileapi/remote_file_system_operation.h24
-rw-r--r--webkit/browser/fileapi/async_file_util.h32
-rw-r--r--webkit/browser/fileapi/async_file_util_adapter.cc95
-rw-r--r--webkit/browser/fileapi/async_file_util_adapter.h34
-rw-r--r--webkit/browser/fileapi/file_system_operation.h8
-rw-r--r--webkit/browser/fileapi/file_system_operation_context.h4
-rw-r--r--webkit/browser/fileapi/file_system_operation_runner.cc4
-rw-r--r--webkit/browser/fileapi/file_system_operation_runner.h5
-rw-r--r--webkit/browser/fileapi/file_writer_delegate.cc29
-rw-r--r--webkit/browser/fileapi/file_writer_delegate.h17
-rw-r--r--webkit/browser/fileapi/local_file_system_operation.cc229
-rw-r--r--webkit/browser/fileapi/local_file_system_operation.h48
-rw-r--r--webkit/browser/fileapi/syncable/syncable_file_system_operation.cc145
-rw-r--r--webkit/browser/fileapi/syncable/syncable_file_system_operation.h7
15 files changed, 299 insertions, 502 deletions
diff --git a/webkit/browser/chromeos/fileapi/remote_file_system_operation.cc b/webkit/browser/chromeos/fileapi/remote_file_system_operation.cc
index f508c2c..e69879b 100644
--- a/webkit/browser/chromeos/fileapi/remote_file_system_operation.cc
+++ b/webkit/browser/chromeos/fileapi/remote_file_system_operation.cc
@@ -30,9 +30,7 @@ RemoteFileSystemOperation::~RemoteFileSystemOperation() {
void RemoteFileSystemOperation::GetMetadata(const FileSystemURL& url,
const GetMetadataCallback& callback) {
DCHECK(SetPendingOperationType(kOperationGetMetadata));
- remote_proxy_->GetFileInfo(url,
- base::Bind(&RemoteFileSystemOperation::DidGetMetadata,
- base::Owned(this), callback));
+ remote_proxy_->GetFileInfo(url, callback);
}
void RemoteFileSystemOperation::DirectoryExists(const FileSystemURL& url,
@@ -40,7 +38,7 @@ void RemoteFileSystemOperation::DirectoryExists(const FileSystemURL& url,
DCHECK(SetPendingOperationType(kOperationDirectoryExists));
remote_proxy_->GetFileInfo(url,
base::Bind(&RemoteFileSystemOperation::DidDirectoryExists,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void RemoteFileSystemOperation::FileExists(const FileSystemURL& url,
@@ -48,15 +46,13 @@ void RemoteFileSystemOperation::FileExists(const FileSystemURL& url,
DCHECK(SetPendingOperationType(kOperationFileExists));
remote_proxy_->GetFileInfo(url,
base::Bind(base::Bind(&RemoteFileSystemOperation::DidFileExists,
- base::Owned(this), callback)));
+ AsWeakPtr(), callback)));
}
void RemoteFileSystemOperation::ReadDirectory(const FileSystemURL& url,
const ReadDirectoryCallback& callback) {
DCHECK(SetPendingOperationType(kOperationReadDirectory));
- remote_proxy_->ReadDirectory(url,
- base::Bind(&RemoteFileSystemOperation::DidReadDirectory,
- base::Owned(this), callback));
+ remote_proxy_->ReadDirectory(url, callback);
}
void RemoteFileSystemOperation::Remove(const FileSystemURL& url, bool recursive,
@@ -64,7 +60,7 @@ void RemoteFileSystemOperation::Remove(const FileSystemURL& url, bool recursive,
DCHECK(SetPendingOperationType(kOperationRemove));
remote_proxy_->Remove(url, recursive,
base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
@@ -74,7 +70,7 @@ void RemoteFileSystemOperation::CreateDirectory(
DCHECK(SetPendingOperationType(kOperationCreateDirectory));
remote_proxy_->CreateDirectory(url, exclusive, recursive,
base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void RemoteFileSystemOperation::CreateFile(const FileSystemURL& url,
@@ -83,7 +79,7 @@ void RemoteFileSystemOperation::CreateFile(const FileSystemURL& url,
DCHECK(SetPendingOperationType(kOperationCreateFile));
remote_proxy_->CreateFile(url, exclusive,
base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void RemoteFileSystemOperation::Copy(const FileSystemURL& src_url,
@@ -93,7 +89,7 @@ void RemoteFileSystemOperation::Copy(const FileSystemURL& src_url,
remote_proxy_->Copy(src_url, dest_url,
base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void RemoteFileSystemOperation::Move(const FileSystemURL& src_url,
@@ -103,7 +99,7 @@ void RemoteFileSystemOperation::Move(const FileSystemURL& src_url,
remote_proxy_->Move(src_url, dest_url,
base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void RemoteFileSystemOperation::Write(
@@ -113,14 +109,10 @@ void RemoteFileSystemOperation::Write(
int64 offset,
const WriteCallback& callback) {
DCHECK(SetPendingOperationType(kOperationWrite));
- DCHECK(write_callback_.is_null());
-
- write_callback_ = callback;
file_writer_delegate_.reset(
new fileapi::FileWriterDelegate(
base::Bind(&RemoteFileSystemOperation::DidWrite,
- // FileWriterDelegate is owned by |this|. So Unretained.
- base::Unretained(this)),
+ AsWeakPtr(), callback),
scoped_ptr<fileapi::FileStreamWriter>(
new fileapi::RemoteFileStreamWriter(remote_proxy_,
url,
@@ -139,37 +131,21 @@ void RemoteFileSystemOperation::Truncate(const FileSystemURL& url,
remote_proxy_->Truncate(url, length,
base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void RemoteFileSystemOperation::Cancel(const StatusCallback& cancel_callback) {
+ DCHECK(cancel_callback_.is_null());
+ cancel_callback_ = cancel_callback;
+
if (file_writer_delegate_) {
DCHECK_EQ(kOperationWrite, pending_operation_);
-
- // Writes are done without proxying through FileUtilProxy after the initial
- // opening of the PlatformFile. All state changes are done on this thread,
- // so we're guaranteed to be able to shut down atomically.
- const bool delete_now = file_writer_delegate_->Cancel();
-
- if (!write_callback_.is_null()) {
- // Notify the failure status to the ongoing operation's callback.
- write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false);
- }
- cancel_callback.Run(base::PLATFORM_FILE_OK);
- write_callback_.Reset();
-
- if (delete_now) {
- delete this;
- return;
- }
+ // This will call DidWrite() with ABORT status code.
+ file_writer_delegate_->Cancel();
} else {
+ // For truncate we have no way to cancel the inflight operation (for now).
+ // Let it just run and dispatch cancel callback later.
DCHECK_EQ(kOperationTruncate, pending_operation_);
- // We're cancelling a truncate operation, but we can't actually stop it
- // since it's been proxied to another thread. We need to save the
- // cancel_callback so that when the truncate returns, it can see that it's
- // been cancelled, report it, and report that the cancel has succeeded.
- DCHECK(cancel_callback_.is_null());
- cancel_callback_ = cancel_callback;
}
}
@@ -183,7 +159,7 @@ void RemoteFileSystemOperation::TouchFile(const FileSystemURL& url,
last_access_time,
last_modified_time,
base::Bind(&RemoteFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void RemoteFileSystemOperation::OpenFile(const FileSystemURL& url,
@@ -196,7 +172,7 @@ void RemoteFileSystemOperation::OpenFile(const FileSystemURL& url,
file_flags,
peer_handle,
base::Bind(&RemoteFileSystemOperation::DidOpenFile,
- base::Owned(this), url, callback));
+ AsWeakPtr(), url, callback));
}
fileapi::LocalFileSystemOperation*
@@ -209,10 +185,7 @@ void RemoteFileSystemOperation::CreateSnapshotFile(
const FileSystemURL& url,
const SnapshotFileCallback& callback) {
DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile));
- remote_proxy_->CreateSnapshotFile(
- url,
- base::Bind(&RemoteFileSystemOperation::DidCreateSnapshotFile,
- base::Owned(this), callback));
+ remote_proxy_->CreateSnapshotFile(url, callback);
}
bool RemoteFileSystemOperation::SetPendingOperationType(OperationType type) {
@@ -242,44 +215,16 @@ void RemoteFileSystemOperation::DidFileExists(
callback.Run(rv);
}
-void RemoteFileSystemOperation::DidGetMetadata(
- const GetMetadataCallback& callback,
- base::PlatformFileError rv,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path) {
- callback.Run(rv, file_info, platform_path);
-}
-
-void RemoteFileSystemOperation::DidReadDirectory(
- const ReadDirectoryCallback& callback,
- base::PlatformFileError rv,
- const std::vector<fileapi::DirectoryEntry>& entries,
- bool has_more) {
- callback.Run(rv, entries, has_more /* has_more */);
-}
-
void RemoteFileSystemOperation::DidWrite(
+ const WriteCallback& write_callback,
base::PlatformFileError rv,
int64 bytes,
FileWriterDelegate::WriteProgressStatus write_status) {
- if (write_callback_.is_null()) {
- // If cancelled, callback is already invoked and set to null in Cancel().
- // We must not call it twice. Just shut down this operation object.
- delete this;
- return;
- }
-
bool complete = (write_status != FileWriterDelegate::SUCCESS_IO_PENDING);
- write_callback_.Run(rv, bytes, complete);
- if (rv != base::PLATFORM_FILE_OK || complete) {
- // Other Did*'s doesn't have "delete this", because it is automatic since
- // they are base::Owned by the caller of the callback. For DidWrite, the
- // owner is file_writer_delegate_ which itself is owned by this Operation
- // object. Hence we need manual life time management here.
- // TODO(kinaba): think about refactoring FileWriterDelegate to be self
- // destructing, for avoiding the manual management.
- delete this;
- }
+ StatusCallback cancel_callback = cancel_callback_;
+ write_callback.Run(rv, bytes, complete);
+ if (!cancel_callback.is_null())
+ cancel_callback.Run(base::PLATFORM_FILE_OK);
}
void RemoteFileSystemOperation::DidFinishFileOperation(
@@ -288,23 +233,14 @@ void RemoteFileSystemOperation::DidFinishFileOperation(
if (!cancel_callback_.is_null()) {
DCHECK_EQ(kOperationTruncate, pending_operation_);
+ StatusCallback cancel_callback = cancel_callback_;
callback.Run(base::PLATFORM_FILE_ERROR_ABORT);
- cancel_callback_.Run(base::PLATFORM_FILE_OK);
- cancel_callback_.Reset();
+ cancel_callback.Run(base::PLATFORM_FILE_OK);
} else {
callback.Run(rv);
}
}
-void RemoteFileSystemOperation::DidCreateSnapshotFile(
- const SnapshotFileCallback& callback,
- base::PlatformFileError result,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
- callback.Run(result, file_info, platform_path, file_ref);
-}
-
void RemoteFileSystemOperation::DidOpenFile(
const fileapi::FileSystemURL& url,
const OpenFileCallback& callback,
diff --git a/webkit/browser/chromeos/fileapi/remote_file_system_operation.h b/webkit/browser/chromeos/fileapi/remote_file_system_operation.h
index e89fb71..5d8d93b 100644
--- a/webkit/browser/chromeos/fileapi/remote_file_system_operation.h
+++ b/webkit/browser/chromeos/fileapi/remote_file_system_operation.h
@@ -5,6 +5,7 @@
#ifndef WEBKIT_BROWSER_CHROMEOS_FILEAPI_REMOTE_FILE_SYSTEM_OPERATION_H_
#define WEBKIT_BROWSER_CHROMEOS_FILEAPI_REMOTE_FILE_SYSTEM_OPERATION_H_
+#include "base/memory/weak_ptr.h"
#include "webkit/browser/fileapi/file_system_operation.h"
#include "webkit/browser/fileapi/file_writer_delegate.h"
#include "webkit/browser/fileapi/remote_file_system_proxy.h"
@@ -21,7 +22,9 @@ class LocalFileSystemOperation;
namespace chromeos {
// FileSystemOperation implementation for local file systems.
-class RemoteFileSystemOperation : public fileapi::FileSystemOperation {
+class RemoteFileSystemOperation
+ : public fileapi::FileSystemOperation,
+ public base::SupportsWeakPtr<RemoteFileSystemOperation> {
public:
typedef fileapi::FileWriterDelegate FileWriterDelegate;
virtual ~RemoteFileSystemOperation();
@@ -92,25 +95,12 @@ class RemoteFileSystemOperation : public fileapi::FileSystemOperation {
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
const base::FilePath& unused);
- void DidGetMetadata(const GetMetadataCallback& callback,
- base::PlatformFileError rv,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path);
- void DidReadDirectory(const ReadDirectoryCallback& callback,
- base::PlatformFileError rv,
- const std::vector<fileapi::DirectoryEntry>& entries,
- bool has_more);
- void DidWrite(base::PlatformFileError result,
+ void DidWrite(const WriteCallback& write_callback,
+ base::PlatformFileError result,
int64 bytes,
FileWriterDelegate::WriteProgressStatus write_status);
void DidFinishFileOperation(const StatusCallback& callback,
base::PlatformFileError rv);
- void DidCreateSnapshotFile(
- const SnapshotFileCallback& callback,
- base::PlatformFileError result,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref);
void DidOpenFile(
const fileapi::FileSystemURL& url,
const OpenFileCallback& callback,
@@ -118,13 +108,11 @@ class RemoteFileSystemOperation : public fileapi::FileSystemOperation {
base::PlatformFile file,
base::ProcessHandle peer_handle);
-
scoped_refptr<fileapi::RemoteFileSystemProxyInterface> remote_proxy_;
// A flag to make sure we call operation only once per instance.
OperationType pending_operation_;
scoped_ptr<fileapi::FileWriterDelegate> file_writer_delegate_;
- WriteCallback write_callback_;
StatusCallback cancel_callback_;
DISALLOW_COPY_AND_ASSIGN(RemoteFileSystemOperation);
diff --git a/webkit/browser/fileapi/async_file_util.h b/webkit/browser/fileapi/async_file_util.h
index 0b61194..847adcff 100644
--- a/webkit/browser/fileapi/async_file_util.h
+++ b/webkit/browser/fileapi/async_file_util.h
@@ -8,6 +8,7 @@
#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/files/file_util_proxy.h"
+#include "base/memory/scoped_ptr.h"
#include "base/platform_file.h"
#include "webkit/common/fileapi/directory_entry.h"
#include "webkit/storage/webkit_storage_export.h"
@@ -32,6 +33,11 @@ class FileSystemURL;
// must implement this interface or a synchronous version of interface:
// FileSystemFileUtil.
//
+// As far as an instance of this class is owned by a MountPointProvider
+// (which is owned by FileSystemContext), it's guaranteed that this instance's
+// alive while FileSystemOperationContext given to each operation is kept
+// alive. (Note that this instance might be freed on different thread
+// from the thread it is created.)
class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
public:
typedef base::Callback<
@@ -75,7 +81,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// This returns false if it fails to post an async task.
//
virtual bool CreateOrOpen(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
int file_flags,
const CreateOrOpenCallback& callback) = 0;
@@ -95,7 +101,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// and there was an error while creating a new file.
//
virtual bool EnsureFileExists(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const EnsureFileExistsCallback& callback) = 0;
@@ -115,7 +121,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// - Other error code if it failed to create a directory.
//
virtual bool CreateDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
bool exclusive,
bool recursive,
@@ -132,7 +138,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// - Other error code if there was an error while retrieving the file info.
//
virtual bool GetFileInfo(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const GetFileInfoCallback& callback) = 0;
@@ -157,7 +163,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// is a file (not a directory).
//
virtual bool ReadDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const ReadDirectoryCallback& callback) = 0;
@@ -170,7 +176,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
//
// This returns false if it fails to post an async task.
virtual bool Touch(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const base::Time& last_access_time,
const base::Time& last_modified_time,
@@ -188,7 +194,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// - PLATFORM_FILE_ERROR_NOT_FOUND if the file doesn't exist.
//
virtual bool Truncate(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
int64 length,
const StatusCallback& callback) = 0;
@@ -211,7 +217,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// its parent path is a file.
//
virtual bool CopyFileLocal(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) = 0;
@@ -234,7 +240,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// its parent path is a file.
//
virtual bool MoveFileLocal(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) = 0;
@@ -255,7 +261,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// its parent path is a file.
//
virtual bool CopyInForeignFile(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const base::FilePath& src_file_path,
const FileSystemURL& dest_url,
const StatusCallback& callback) = 0;
@@ -271,7 +277,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// - PLATFORM_FILE_ERROR_NOT_A_FILE if |url| is not a file.
//
virtual bool DeleteFile(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const StatusCallback& callback) = 0;
@@ -287,7 +293,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// - PLATFORM_FILE_ERROR_NOT_EMPTY if |url| is not empty.
//
virtual bool DeleteDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const StatusCallback& callback) = 0;
@@ -325,7 +331,7 @@ class WEBKIT_STORAGE_EXPORT AsyncFileUtil {
// dependent) in error cases, and the caller should always
// check the return code.
virtual bool CreateSnapshotFile(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const CreateSnapshotFileCallback& callback) = 0;
diff --git a/webkit/browser/fileapi/async_file_util_adapter.cc b/webkit/browser/fileapi/async_file_util_adapter.cc
index 8fa1ba7..1664a0b 100644
--- a/webkit/browser/fileapi/async_file_util_adapter.cc
+++ b/webkit/browser/fileapi/async_file_util_adapter.cc
@@ -142,165 +142,180 @@ AsyncFileUtilAdapter::~AsyncFileUtilAdapter() {
}
bool AsyncFileUtilAdapter::CreateOrOpen(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
int file_flags,
const CreateOrOpenCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::FileUtilProxy::RelayCreateOrOpen(
- context->task_runner(),
+ context_ptr->task_runner(),
Bind(&FileSystemFileUtil::CreateOrOpen, Unretained(sync_file_util_.get()),
- context, url, file_flags),
+ context_ptr, url, file_flags),
Bind(&FileSystemFileUtil::Close, Unretained(sync_file_util_.get()),
- context),
+ base::Owned(context_ptr)),
callback);
}
bool AsyncFileUtilAdapter::EnsureFileExists(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const EnsureFileExistsCallback& callback) {
EnsureFileExistsHelper* helper = new EnsureFileExistsHelper;
- return context->task_runner()->PostTaskAndReply(
+ FileSystemOperationContext* context_ptr = context.release();
+ return context_ptr->task_runner()->PostTaskAndReply(
FROM_HERE,
Bind(&EnsureFileExistsHelper::RunWork, Unretained(helper),
- sync_file_util_.get(), context, url),
+ sync_file_util_.get(), base::Owned(context_ptr), url),
Bind(&EnsureFileExistsHelper::Reply, Owned(helper), callback));
}
bool AsyncFileUtilAdapter::CreateDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
bool exclusive,
bool recursive,
const StatusCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::PostTaskAndReplyWithResult(
- context->task_runner(), FROM_HERE,
+ context_ptr->task_runner(), FROM_HERE,
Bind(&FileSystemFileUtil::CreateDirectory,
Unretained(sync_file_util_.get()),
- context, url, exclusive, recursive),
+ base::Owned(context_ptr), url, exclusive, recursive),
callback);
}
bool AsyncFileUtilAdapter::GetFileInfo(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const GetFileInfoCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
GetFileInfoHelper* helper = new GetFileInfoHelper;
- return context->task_runner()->PostTaskAndReply(
+ return context_ptr->task_runner()->PostTaskAndReply(
FROM_HERE,
Bind(&GetFileInfoHelper::GetFileInfo, Unretained(helper),
- sync_file_util_.get(), context, url),
+ sync_file_util_.get(), base::Owned(context_ptr), url),
Bind(&GetFileInfoHelper::ReplyFileInfo, Owned(helper), callback));
}
bool AsyncFileUtilAdapter::ReadDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const ReadDirectoryCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
ReadDirectoryHelper* helper = new ReadDirectoryHelper;
- return context->task_runner()->PostTaskAndReply(
+ return context_ptr->task_runner()->PostTaskAndReply(
FROM_HERE,
Bind(&ReadDirectoryHelper::RunWork, Unretained(helper),
- sync_file_util_.get(), context, url),
+ sync_file_util_.get(), base::Owned(context_ptr), url),
Bind(&ReadDirectoryHelper::Reply, Owned(helper), callback));
}
bool AsyncFileUtilAdapter::Touch(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const base::Time& last_access_time,
const base::Time& last_modified_time,
const StatusCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::PostTaskAndReplyWithResult(
- context->task_runner(), FROM_HERE,
+ context_ptr->task_runner(), FROM_HERE,
Bind(&FileSystemFileUtil::Touch, Unretained(sync_file_util_.get()),
- context, url, last_access_time, last_modified_time),
+ base::Owned(context_ptr), url,
+ last_access_time, last_modified_time),
callback);
}
bool AsyncFileUtilAdapter::Truncate(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
int64 length,
const StatusCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::PostTaskAndReplyWithResult(
- context->task_runner(), FROM_HERE,
+ context_ptr->task_runner(), FROM_HERE,
Bind(&FileSystemFileUtil::Truncate, Unretained(sync_file_util_.get()),
- context, url, length),
+ base::Owned(context_ptr), url, length),
callback);
}
bool AsyncFileUtilAdapter::CopyFileLocal(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::PostTaskAndReplyWithResult(
- context->task_runner(), FROM_HERE,
+ context_ptr->task_runner(), FROM_HERE,
Bind(&FileSystemFileUtil::CopyOrMoveFile,
Unretained(sync_file_util_.get()),
- context, src_url, dest_url, true /* copy */),
+ base::Owned(context_ptr), src_url, dest_url, true /* copy */),
callback);
}
bool AsyncFileUtilAdapter::MoveFileLocal(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::PostTaskAndReplyWithResult(
- context->task_runner(), FROM_HERE,
+ context_ptr->task_runner(), FROM_HERE,
Bind(&FileSystemFileUtil::CopyOrMoveFile,
Unretained(sync_file_util_.get()),
- context, src_url, dest_url, false /* copy */),
+ base::Owned(context_ptr), src_url, dest_url, false /* copy */),
callback);
}
bool AsyncFileUtilAdapter::CopyInForeignFile(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const base::FilePath& src_file_path,
const FileSystemURL& dest_url,
const StatusCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::PostTaskAndReplyWithResult(
- context->task_runner(), FROM_HERE,
+ context_ptr->task_runner(), FROM_HERE,
Bind(&FileSystemFileUtil::CopyInForeignFile,
Unretained(sync_file_util_.get()),
- context, src_file_path, dest_url),
+ base::Owned(context_ptr), src_file_path, dest_url),
callback);
}
bool AsyncFileUtilAdapter::DeleteFile(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const StatusCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::PostTaskAndReplyWithResult(
- context->task_runner(), FROM_HERE,
+ context_ptr->task_runner(), FROM_HERE,
Bind(&FileSystemFileUtil::DeleteFile,
- Unretained(sync_file_util_.get()), context, url),
+ Unretained(sync_file_util_.get()),
+ base::Owned(context_ptr), url),
callback);
}
bool AsyncFileUtilAdapter::DeleteDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const StatusCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
return base::PostTaskAndReplyWithResult(
- context->task_runner(), FROM_HERE,
+ context_ptr->task_runner(), FROM_HERE,
Bind(&FileSystemFileUtil::DeleteDirectory,
Unretained(sync_file_util_.get()),
- context, url),
+ base::Owned(context_ptr), url),
callback);
}
bool AsyncFileUtilAdapter::CreateSnapshotFile(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const CreateSnapshotFileCallback& callback) {
+ FileSystemOperationContext* context_ptr = context.release();
GetFileInfoHelper* helper = new GetFileInfoHelper;
- return context->task_runner()->PostTaskAndReply(
+ return context_ptr->task_runner()->PostTaskAndReply(
FROM_HERE,
Bind(&GetFileInfoHelper::CreateSnapshotFile, Unretained(helper),
- sync_file_util_.get(), context, url),
+ sync_file_util_.get(), base::Owned(context_ptr), url),
Bind(&GetFileInfoHelper::ReplySnapshotFile, Owned(helper), callback));
}
diff --git a/webkit/browser/fileapi/async_file_util_adapter.h b/webkit/browser/fileapi/async_file_util_adapter.h
index 3a85028..0c6fcbd 100644
--- a/webkit/browser/fileapi/async_file_util_adapter.h
+++ b/webkit/browser/fileapi/async_file_util_adapter.h
@@ -20,6 +20,8 @@ class FileSystemFileUtil;
// FileSystemFileUtil and atach it to this adapter, or
// - directly implement AsyncFileUtil.
//
+// This instance (as thus this->sync_file_util_) is guaranteed to be alive
+// as far as FileSystemOperationContext given to each operation is kept alive.
class WEBKIT_STORAGE_EXPORT_PRIVATE AsyncFileUtilAdapter
: public AsyncFileUtil {
public:
@@ -37,64 +39,64 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE AsyncFileUtilAdapter
// AsyncFileUtil overrides.
virtual bool CreateOrOpen(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
int file_flags,
const CreateOrOpenCallback& callback) OVERRIDE;
virtual bool EnsureFileExists(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const EnsureFileExistsCallback& callback) OVERRIDE;
virtual bool CreateDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
bool exclusive,
bool recursive,
const StatusCallback& callback) OVERRIDE;
virtual bool GetFileInfo(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const GetFileInfoCallback& callback) OVERRIDE;
virtual bool ReadDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const ReadDirectoryCallback& callback) OVERRIDE;
virtual bool Touch(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const base::Time& last_access_time,
const base::Time& last_modified_time,
const StatusCallback& callback) OVERRIDE;
virtual bool Truncate(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
int64 length,
const StatusCallback& callback) OVERRIDE;
virtual bool CopyFileLocal(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) OVERRIDE;
virtual bool MoveFileLocal(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) OVERRIDE;
virtual bool CopyInForeignFile(
- FileSystemOperationContext* context,
- const base::FilePath& src_file_path,
- const FileSystemURL& dest_url,
- const StatusCallback& callback) OVERRIDE;
+ scoped_ptr<FileSystemOperationContext> context,
+ const base::FilePath& src_file_path,
+ const FileSystemURL& dest_url,
+ const StatusCallback& callback) OVERRIDE;
virtual bool DeleteFile(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const StatusCallback& callback) OVERRIDE;
virtual bool DeleteDirectory(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const StatusCallback& callback) OVERRIDE;
virtual bool CreateSnapshotFile(
- FileSystemOperationContext* context,
+ scoped_ptr<FileSystemOperationContext> context,
const FileSystemURL& url,
const CreateSnapshotFileCallback& callback) OVERRIDE;
diff --git a/webkit/browser/fileapi/file_system_operation.h b/webkit/browser/fileapi/file_system_operation.h
index b901f1e..8cc015e 100644
--- a/webkit/browser/fileapi/file_system_operation.h
+++ b/webkit/browser/fileapi/file_system_operation.h
@@ -47,12 +47,12 @@ class LocalFileSystemOperation;
// GetMetadata, ReadDirectory and Remove) may be called during the
// lifetime of this object and it should be called no more than once.
//
-// 2) Be self-destructed, or get deleted via base::Owned() after the
-// operation finishes and completion callback is called.
-//
-// 3) Deliver the results of operations to the client via the callback function
+// 2) Deliver the results of operations to the client via the callback function
// passed as the last parameter of the method.
//
+// Note that it is valid to delete an operation while it is running.
+// The callback will NOT be fired if the operation is deleted before
+// it gets called.
class FileSystemOperation {
public:
virtual ~FileSystemOperation() {}
diff --git a/webkit/browser/fileapi/file_system_operation_context.h b/webkit/browser/fileapi/file_system_operation_context.h
index 7d751d3..baee852 100644
--- a/webkit/browser/fileapi/file_system_operation_context.h
+++ b/webkit/browser/fileapi/file_system_operation_context.h
@@ -38,7 +38,7 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE FileSystemOperationContext
virtual ~FileSystemOperationContext();
FileSystemContext* file_system_context() const {
- return file_system_context_;
+ return file_system_context_.get();
}
// Updates the current remaining quota.
@@ -100,7 +100,7 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE FileSystemOperationContext
DISALLOW_COPY_AND_ASSIGN(ValueAdapter);
};
- FileSystemContext* file_system_context_;
+ scoped_refptr<FileSystemContext> file_system_context_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// The current remaining quota, used by ObfuscatedFileUtil.
diff --git a/webkit/browser/fileapi/file_system_operation_runner.cc b/webkit/browser/fileapi/file_system_operation_runner.cc
index e5d141b..f1abba5 100644
--- a/webkit/browser/fileapi/file_system_operation_runner.cc
+++ b/webkit/browser/fileapi/file_system_operation_runner.cc
@@ -19,6 +19,10 @@ const OperationID FileSystemOperationRunner::kErrorOperationID = -1;
FileSystemOperationRunner::~FileSystemOperationRunner() {
}
+void FileSystemOperationRunner::Shutdown() {
+ operations_.Clear();
+}
+
OperationID FileSystemOperationRunner::CreateFile(
const FileSystemURL& url,
bool exclusive,
diff --git a/webkit/browser/fileapi/file_system_operation_runner.h b/webkit/browser/fileapi/file_system_operation_runner.h
index 9c2dd85..41e3300 100644
--- a/webkit/browser/fileapi/file_system_operation_runner.h
+++ b/webkit/browser/fileapi/file_system_operation_runner.h
@@ -49,6 +49,9 @@ class WEBKIT_STORAGE_EXPORT FileSystemOperationRunner
virtual ~FileSystemOperationRunner();
+ // Cancels all inflight operations.
+ void Shutdown();
+
// Creates a file at |url|. If |exclusive| is true, an error is raised
// in case a file is already present at the URL.
OperationID CreateFile(const FileSystemURL& url,
@@ -276,7 +279,7 @@ class WEBKIT_STORAGE_EXPORT FileSystemOperationRunner
FileSystemContext* file_system_context_;
// IDMap<FileSystemOperation, IDMapOwnPointer> operations_;
- IDMap<FileSystemOperation> operations_;
+ IDMap<FileSystemOperation, IDMapOwnPointer> operations_;
// We keep track of the file to be modified by each operation so that
// we can notify observers when we're done.
diff --git a/webkit/browser/fileapi/file_writer_delegate.cc b/webkit/browser/fileapi/file_writer_delegate.cc
index 3c7b781..1d307e0 100644
--- a/webkit/browser/fileapi/file_writer_delegate.cc
+++ b/webkit/browser/fileapi/file_writer_delegate.cc
@@ -48,8 +48,7 @@ FileWriterDelegate::FileWriterDelegate(
bytes_written_backlog_(0),
bytes_written_(0),
bytes_read_(0),
- io_buffer_(new net::IOBufferWithSize(kReadBufSize)),
- weak_factory_(this) {
+ io_buffer_(new net::IOBufferWithSize(kReadBufSize)) {
}
FileWriterDelegate::~FileWriterDelegate() {
@@ -60,7 +59,7 @@ void FileWriterDelegate::Start(scoped_ptr<net::URLRequest> request) {
request_->Start();
}
-bool FileWriterDelegate::Cancel() {
+void FileWriterDelegate::Cancel() {
if (request_) {
// This halts any callbacks on this delegate.
request_->set_delegate(NULL);
@@ -68,11 +67,13 @@ bool FileWriterDelegate::Cancel() {
}
const int status = file_stream_writer_->Cancel(
- base::Bind(&FileWriterDelegate::OnWriteCancelled,
- weak_factory_.GetWeakPtr()));
+ base::Bind(&FileWriterDelegate::OnWriteCancelled, AsWeakPtr()));
// Return true to finish immediately if we have no pending writes.
// Otherwise we'll do the final cleanup in the Cancel callback.
- return (status != net::ERR_IO_PENDING);
+ if (status != net::ERR_IO_PENDING) {
+ write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0,
+ GetCompletionStatusOnError());
+ }
}
void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request,
@@ -128,8 +129,7 @@ void FileWriterDelegate::Read() {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&FileWriterDelegate::OnDataReceived,
- weak_factory_.GetWeakPtr(),
- bytes_read_));
+ AsWeakPtr(), bytes_read_));
} else if (!request_->status().is_io_pending()) {
OnError(base::PLATFORM_FILE_ERROR_FAILED);
}
@@ -155,15 +155,15 @@ void FileWriterDelegate::Write() {
file_stream_writer_->Write(cursor_.get(),
static_cast<int>(bytes_to_write),
base::Bind(&FileWriterDelegate::OnDataWritten,
- weak_factory_.GetWeakPtr()));
- if (write_response > 0)
+ AsWeakPtr()));
+ if (write_response > 0) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&FileWriterDelegate::OnDataWritten,
- weak_factory_.GetWeakPtr(),
- write_response));
- else if (net::ERR_IO_PENDING != write_response)
+ AsWeakPtr(), write_response));
+ } else if (net::ERR_IO_PENDING != write_response) {
OnError(NetErrorToPlatformFileError(write_response));
+ }
}
void FileWriterDelegate::OnDataWritten(int write_response) {
@@ -230,8 +230,7 @@ void FileWriterDelegate::FlushForCompletion(
int bytes_written,
WriteProgressStatus progress_status) {
int flush_error = file_stream_writer_->Flush(
- base::Bind(&FileWriterDelegate::OnFlushed,
- weak_factory_.GetWeakPtr(),
+ base::Bind(&FileWriterDelegate::OnFlushed, AsWeakPtr(),
error, bytes_written, progress_status));
if (flush_error != net::ERR_IO_PENDING)
OnFlushed(error, bytes_written, progress_status, flush_error);
diff --git a/webkit/browser/fileapi/file_writer_delegate.h b/webkit/browser/fileapi/file_writer_delegate.h
index 6fd8fab..8e4b028 100644
--- a/webkit/browser/fileapi/file_writer_delegate.h
+++ b/webkit/browser/fileapi/file_writer_delegate.h
@@ -13,17 +13,15 @@
#include "net/base/file_stream.h"
#include "net/base/io_buffer.h"
#include "net/url_request/url_request.h"
-#include "webkit/browser/fileapi/file_system_operation.h"
#include "webkit/storage/webkit_storage_export.h"
namespace fileapi {
class FileStreamWriter;
-class FileSystemOperationContext;
-class FileSystemQuotaUtil;
class WEBKIT_STORAGE_EXPORT_PRIVATE FileWriterDelegate
- : public net::URLRequest::Delegate {
+ : public net::URLRequest::Delegate,
+ public base::SupportsWeakPtr<FileWriterDelegate> {
public:
enum WriteProgressStatus {
SUCCESS_IO_PENDING,
@@ -44,11 +42,10 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE FileWriterDelegate
void Start(scoped_ptr<net::URLRequest> request);
- // Cancels the current write operation. Returns true if it is ok to
- // delete this instance immediately. Otherwise this will call
- // |write_operation|->DidWrite() with complete=true to let the operation
- // perform the final cleanup.
- bool Cancel();
+ // Cancels the current write operation. This will synchronously or
+ // asynchronously call the given write callback (which may result in
+ // deleting this).
+ void Cancel();
virtual void OnReceivedRedirect(net::URLRequest* request,
const GURL& new_url,
@@ -85,7 +82,6 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE FileWriterDelegate
WriteProgressStatus progress_status,
int flush_error);
- FileSystemQuotaUtil* quota_util() const;
WriteProgressStatus GetCompletionStatusOnError() const;
DelegateWriteCallback write_callback_;
@@ -98,7 +94,6 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE FileWriterDelegate
scoped_refptr<net::IOBufferWithSize> io_buffer_;
scoped_refptr<net::DrainableIOBuffer> cursor_;
scoped_ptr<net::URLRequest> request_;
- base::WeakPtrFactory<FileWriterDelegate> weak_factory_;
};
} // namespace fileapi
diff --git a/webkit/browser/fileapi/local_file_system_operation.cc b/webkit/browser/fileapi/local_file_system_operation.cc
index c14a3e4d..a79b479 100644
--- a/webkit/browser/fileapi/local_file_system_operation.cc
+++ b/webkit/browser/fileapi/local_file_system_operation.cc
@@ -45,8 +45,7 @@ LocalFileSystemOperation::LocalFileSystemOperation(
operation_context_(operation_context.Pass()),
async_file_util_(NULL),
peer_handle_(base::kNullProcessHandle),
- pending_operation_(kOperationNone),
- weak_factory_(this) {
+ pending_operation_(kOperationNone) {
DCHECK(operation_context_.get());
operation_context_->DetachUserDataThread();
async_file_util_ = file_system_context_->GetAsyncFileUtil(url.type());
@@ -63,7 +62,7 @@ void LocalFileSystemOperation::CreateFile(const FileSystemURL& url,
GetUsageAndQuotaThenRunTask(
url,
base::Bind(&LocalFileSystemOperation::DoCreateFile,
- base::Unretained(this), url, callback, exclusive),
+ AsWeakPtr(), url, callback, exclusive),
base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}
@@ -75,7 +74,7 @@ void LocalFileSystemOperation::CreateDirectory(const FileSystemURL& url,
GetUsageAndQuotaThenRunTask(
url,
base::Bind(&LocalFileSystemOperation::DoCreateDirectory,
- base::Unretained(this), url, callback, exclusive, recursive),
+ AsWeakPtr(), url, callback, exclusive, recursive),
base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}
@@ -89,8 +88,8 @@ void LocalFileSystemOperation::Copy(const FileSystemURL& src_url,
file_system_context(),
src_url, dest_url,
CopyOrMoveOperationDelegate::OPERATION_COPY,
- base::Bind(&LocalFileSystemOperation::DidFinishDelegatedOperation,
- base::Unretained(this), callback)));
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback)));
recursive_operation_delegate_->RunRecursively();
}
@@ -104,8 +103,8 @@ void LocalFileSystemOperation::Move(const FileSystemURL& src_url,
file_system_context(),
src_url, dest_url,
CopyOrMoveOperationDelegate::OPERATION_MOVE,
- base::Bind(&LocalFileSystemOperation::DidFinishDelegatedOperation,
- base::Unretained(this), callback)));
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback)));
recursive_operation_delegate_->RunRecursively();
}
@@ -113,36 +112,31 @@ void LocalFileSystemOperation::DirectoryExists(const FileSystemURL& url,
const StatusCallback& callback) {
DCHECK(SetPendingOperationType(kOperationDirectoryExists));
async_file_util_->GetFileInfo(
- operation_context(), url,
+ operation_context_.Pass(), url,
base::Bind(&LocalFileSystemOperation::DidDirectoryExists,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::FileExists(const FileSystemURL& url,
const StatusCallback& callback) {
DCHECK(SetPendingOperationType(kOperationFileExists));
async_file_util_->GetFileInfo(
- operation_context(), url,
+ operation_context_.Pass(), url,
base::Bind(&LocalFileSystemOperation::DidFileExists,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::GetMetadata(
const FileSystemURL& url, const GetMetadataCallback& callback) {
DCHECK(SetPendingOperationType(kOperationGetMetadata));
- async_file_util_->GetFileInfo(
- operation_context(), url,
- base::Bind(&LocalFileSystemOperation::DidGetMetadata,
- base::Owned(this), callback));
+ async_file_util_->GetFileInfo(operation_context_.Pass(), url, callback);
}
void LocalFileSystemOperation::ReadDirectory(
const FileSystemURL& url, const ReadDirectoryCallback& callback) {
DCHECK(SetPendingOperationType(kOperationReadDirectory));
async_file_util_->ReadDirectory(
- operation_context(), url,
- base::Bind(&LocalFileSystemOperation::DidReadDirectory,
- base::Owned(this), callback));
+ operation_context_.Pass(), url, callback);
}
void LocalFileSystemOperation::Remove(const FileSystemURL& url,
@@ -153,8 +147,8 @@ void LocalFileSystemOperation::Remove(const FileSystemURL& url,
recursive_operation_delegate_.reset(
new RemoveOperationDelegate(
file_system_context(), url,
- base::Bind(&LocalFileSystemOperation::DidFinishDelegatedOperation,
- base::Unretained(this), callback)));
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback)));
if (recursive)
recursive_operation_delegate_->RunRecursively();
else
@@ -176,7 +170,7 @@ void LocalFileSystemOperation::Truncate(const FileSystemURL& url, int64 length,
GetUsageAndQuotaThenRunTask(
url,
base::Bind(&LocalFileSystemOperation::DoTruncate,
- base::Unretained(this), url, callback, length),
+ AsWeakPtr(), url, callback, length),
base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}
@@ -186,10 +180,10 @@ void LocalFileSystemOperation::TouchFile(const FileSystemURL& url,
const StatusCallback& callback) {
DCHECK(SetPendingOperationType(kOperationTouchFile));
async_file_util_->Touch(
- operation_context(), url,
+ operation_context_.Pass(), url,
last_access_time, last_modified_time,
- base::Bind(&LocalFileSystemOperation::DidTouchFile,
- base::Owned(this), callback));
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::OpenFile(const FileSystemURL& url,
@@ -197,8 +191,6 @@ void LocalFileSystemOperation::OpenFile(const FileSystemURL& url,
base::ProcessHandle peer_handle,
const OpenFileCallback& callback) {
DCHECK(SetPendingOperationType(kOperationOpenFile));
- scoped_ptr<LocalFileSystemOperation> deleter(this);
-
peer_handle_ = peer_handle;
if (file_flags & (
@@ -213,7 +205,7 @@ void LocalFileSystemOperation::OpenFile(const FileSystemURL& url,
GetUsageAndQuotaThenRunTask(
url,
base::Bind(&LocalFileSystemOperation::DoOpenFile,
- base::Unretained(deleter.release()),
+ AsWeakPtr(),
url, callback, file_flags),
base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED,
base::kInvalidPlatformFileValue,
@@ -224,33 +216,17 @@ void LocalFileSystemOperation::OpenFile(const FileSystemURL& url,
// We can only get here on a write or truncate that's not yet completed.
// We don't support cancelling any other operation at this time.
void LocalFileSystemOperation::Cancel(const StatusCallback& cancel_callback) {
- if (file_writer_delegate_) {
- DCHECK_EQ(kOperationWrite, pending_operation_);
-
- // Writes are done without proxying through FileUtilProxy after the initial
- // opening of the PlatformFile. All state changes are done on this thread,
- // so we're guaranteed to be able to shut down atomically.
- const bool delete_now = file_writer_delegate_->Cancel();
+ DCHECK(cancel_callback_.is_null());
+ cancel_callback_ = cancel_callback;
- if (!write_callback_.is_null()) {
- // Notify the failure status to the ongoing operation's callback.
- write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false);
- }
- cancel_callback.Run(base::PLATFORM_FILE_OK);
- write_callback_.Reset();
-
- if (delete_now) {
- delete this;
- return;
- }
+ if (file_writer_delegate_.get()) {
+ DCHECK_EQ(kOperationWrite, pending_operation_);
+ // This will call DidWrite() with ABORT status code.
+ file_writer_delegate_->Cancel();
} else {
+ // For truncate we have no way to cancel the inflight operation (for now).
+ // Let it just run and dispatch cancel callback later.
DCHECK_EQ(kOperationTruncate, pending_operation_);
- // We're cancelling a truncate operation, but we can't actually stop it
- // since it's been proxied to another thread. We need to save the
- // cancel_callback so that when the truncate returns, it can see that it's
- // been cancelled, report it, and report that the cancel has succeeded.
- DCHECK(cancel_callback_.is_null());
- cancel_callback_ = cancel_callback;
}
}
@@ -259,15 +235,14 @@ LocalFileSystemOperation::AsLocalFileSystemOperation() {
return this;
}
-void LocalFileSystemOperation::SyncGetPlatformPath(const FileSystemURL& url,
- base::FilePath* platform_path) {
+void LocalFileSystemOperation::SyncGetPlatformPath(
+ const FileSystemURL& url,
+ base::FilePath* platform_path) {
DCHECK(SetPendingOperationType(kOperationGetLocalPath));
FileSystemFileUtil* file_util = file_system_context()->GetFileUtil(
url.type());
DCHECK(file_util);
- file_util->GetLocalFilePath(operation_context(), url, platform_path);
-
- delete this;
+ file_util->GetLocalFilePath(operation_context_.get(), url, platform_path);
}
void LocalFileSystemOperation::CreateSnapshotFile(
@@ -275,9 +250,7 @@ void LocalFileSystemOperation::CreateSnapshotFile(
const SnapshotFileCallback& callback) {
DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile));
async_file_util_->CreateSnapshotFile(
- operation_context(), url,
- base::Bind(&LocalFileSystemOperation::DidCreateSnapshotFile,
- base::Owned(this), callback));
+ operation_context_.Pass(), url, callback);
}
void LocalFileSystemOperation::CopyInForeignFile(
@@ -288,7 +261,7 @@ void LocalFileSystemOperation::CopyInForeignFile(
GetUsageAndQuotaThenRunTask(
dest_url,
base::Bind(&LocalFileSystemOperation::DoCopyInForeignFile,
- base::Unretained(this), src_local_disk_file_path, dest_url,
+ AsWeakPtr(), src_local_disk_file_path, dest_url,
callback),
base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}
@@ -298,9 +271,9 @@ void LocalFileSystemOperation::RemoveFile(
const StatusCallback& callback) {
DCHECK(SetPendingOperationType(kOperationRemove));
async_file_util_->DeleteFile(
- operation_context(), url,
- base::Bind(&LocalFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ operation_context_.Pass(), url,
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::RemoveDirectory(
@@ -308,9 +281,9 @@ void LocalFileSystemOperation::RemoveDirectory(
const StatusCallback& callback) {
DCHECK(SetPendingOperationType(kOperationRemove));
async_file_util_->DeleteDirectory(
- operation_context(), url,
- base::Bind(&LocalFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ operation_context_.Pass(), url,
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::CopyFileLocal(
@@ -322,7 +295,7 @@ void LocalFileSystemOperation::CopyFileLocal(
GetUsageAndQuotaThenRunTask(
dest_url,
base::Bind(&LocalFileSystemOperation::DoCopyFileLocal,
- base::Unretained(this), src_url, dest_url, callback),
+ AsWeakPtr(), src_url, dest_url, callback),
base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}
@@ -335,7 +308,7 @@ void LocalFileSystemOperation::MoveFileLocal(
GetUsageAndQuotaThenRunTask(
dest_url,
base::Bind(&LocalFileSystemOperation::DoMoveFileLocal,
- base::Unretained(this), src_url, dest_url, callback),
+ AsWeakPtr(), src_url, dest_url, callback),
base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}
@@ -349,7 +322,7 @@ void LocalFileSystemOperation::GetUsageAndQuotaThenRunTask(
!file_system_context()->GetQuotaUtil(url.type())) {
// If we don't have the quota manager or the requested filesystem type
// does not support quota, we should be able to let it go.
- operation_context()->set_allowed_bytes_growth(kint64max);
+ operation_context_->set_allowed_bytes_growth(kint64max);
task.Run();
return;
}
@@ -360,7 +333,7 @@ void LocalFileSystemOperation::GetUsageAndQuotaThenRunTask(
url.origin(),
FileSystemTypeToQuotaStorageType(url.type()),
base::Bind(&LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask,
- weak_factory_.GetWeakPtr(), task, error_callback));
+ AsWeakPtr(), task, error_callback));
}
void LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask(
@@ -374,7 +347,7 @@ void LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask(
return;
}
- operation_context()->set_allowed_bytes_growth(quota - usage);
+ operation_context_->set_allowed_bytes_growth(quota - usage);
task.Run();
}
@@ -391,17 +364,16 @@ base::Closure LocalFileSystemOperation::GetWriteClosure(
if (!writer) {
// Write is not supported.
return base::Bind(&LocalFileSystemOperation::DidFailWrite,
- base::Owned(this), callback,
+ AsWeakPtr(), callback,
base::PLATFORM_FILE_ERROR_SECURITY);
}
DCHECK(blob_url.is_valid());
file_writer_delegate_.reset(new FileWriterDelegate(
- base::Bind(&LocalFileSystemOperation::DidWrite,
- weak_factory_.GetWeakPtr(), url),
+ base::Bind(&LocalFileSystemOperation::DidWrite, AsWeakPtr(),
+ url, callback),
writer.Pass()));
- write_callback_ = callback;
scoped_ptr<net::URLRequest> blob_request(url_request_context->CreateRequest(
blob_url, file_writer_delegate_.get()));
@@ -421,12 +393,12 @@ void LocalFileSystemOperation::DoCreateFile(
const StatusCallback& callback,
bool exclusive) {
async_file_util_->EnsureFileExists(
- operation_context(), url,
+ operation_context_.Pass(), url,
base::Bind(
exclusive ?
&LocalFileSystemOperation::DidEnsureFileExistsExclusive :
&LocalFileSystemOperation::DidEnsureFileExistsNonExclusive,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::DoCreateDirectory(
@@ -434,10 +406,10 @@ void LocalFileSystemOperation::DoCreateDirectory(
const StatusCallback& callback,
bool exclusive, bool recursive) {
async_file_util_->CreateDirectory(
- operation_context(),
+ operation_context_.Pass(),
url, exclusive, recursive,
- base::Bind(&LocalFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::DoCopyFileLocal(
@@ -445,9 +417,9 @@ void LocalFileSystemOperation::DoCopyFileLocal(
const FileSystemURL& dest_url,
const StatusCallback& callback) {
async_file_util_->CopyFileLocal(
- operation_context(), src_url, dest_url,
- base::Bind(&LocalFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ operation_context_.Pass(), src_url, dest_url,
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::DoMoveFileLocal(
@@ -455,9 +427,9 @@ void LocalFileSystemOperation::DoMoveFileLocal(
const FileSystemURL& dest_url,
const StatusCallback& callback) {
async_file_util_->MoveFileLocal(
- operation_context(), src_url, dest_url,
- base::Bind(&LocalFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ operation_context_.Pass(), src_url, dest_url,
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::DoCopyInForeignFile(
@@ -465,28 +437,28 @@ void LocalFileSystemOperation::DoCopyInForeignFile(
const FileSystemURL& dest_url,
const StatusCallback& callback) {
async_file_util_->CopyInForeignFile(
- operation_context(),
+ operation_context_.Pass(),
src_local_disk_file_path, dest_url,
- base::Bind(&LocalFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::DoTruncate(const FileSystemURL& url,
const StatusCallback& callback,
int64 length) {
async_file_util_->Truncate(
- operation_context(), url, length,
- base::Bind(&LocalFileSystemOperation::DidFinishFileOperation,
- base::Owned(this), callback));
+ operation_context_.Pass(), url, length,
+ base::Bind(&LocalFileSystemOperation::DidFinishOperation,
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::DoOpenFile(const FileSystemURL& url,
const OpenFileCallback& callback,
int file_flags) {
async_file_util_->CreateOrOpen(
- operation_context(), url, file_flags,
+ operation_context_.Pass(), url, file_flags,
base::Bind(&LocalFileSystemOperation::DidOpenFile,
- base::Owned(this), callback));
+ AsWeakPtr(), callback));
}
void LocalFileSystemOperation::DidEnsureFileExistsExclusive(
@@ -495,39 +467,30 @@ void LocalFileSystemOperation::DidEnsureFileExistsExclusive(
if (rv == base::PLATFORM_FILE_OK && !created) {
callback.Run(base::PLATFORM_FILE_ERROR_EXISTS);
} else {
- DidFinishFileOperation(callback, rv);
+ DidFinishOperation(callback, rv);
}
}
void LocalFileSystemOperation::DidEnsureFileExistsNonExclusive(
const StatusCallback& callback,
base::PlatformFileError rv, bool /* created */) {
- DidFinishFileOperation(callback, rv);
+ DidFinishOperation(callback, rv);
}
-void LocalFileSystemOperation::DidFinishFileOperation(
+void LocalFileSystemOperation::DidFinishOperation(
const StatusCallback& callback,
base::PlatformFileError rv) {
if (!cancel_callback_.is_null()) {
DCHECK_EQ(kOperationTruncate, pending_operation_);
+ StatusCallback cancel_callback = cancel_callback_;
callback.Run(base::PLATFORM_FILE_ERROR_ABORT);
- cancel_callback_.Run(base::PLATFORM_FILE_OK);
- cancel_callback_.Reset();
+ cancel_callback.Run(base::PLATFORM_FILE_OK);
} else {
callback.Run(rv);
}
}
-void LocalFileSystemOperation::DidFinishDelegatedOperation(
- const StatusCallback& callback,
- base::PlatformFileError rv) {
- // The callback might be held by the delegate and Owned() may not work,
- // so just explicitly delete this now.
- callback.Run(rv);
- delete this;
-}
-
void LocalFileSystemOperation::DidDirectoryExists(
const StatusCallback& callback,
base::PlatformFileError rv,
@@ -548,49 +511,24 @@ void LocalFileSystemOperation::DidFileExists(
callback.Run(rv);
}
-void LocalFileSystemOperation::DidGetMetadata(
- const GetMetadataCallback& callback,
- base::PlatformFileError rv,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path) {
- callback.Run(rv, file_info, platform_path);
-}
-
-void LocalFileSystemOperation::DidReadDirectory(
- const ReadDirectoryCallback& callback,
- base::PlatformFileError rv,
- const std::vector<DirectoryEntry>& entries,
- bool has_more) {
- callback.Run(rv, entries, has_more);
-}
-
void LocalFileSystemOperation::DidWrite(
const FileSystemURL& url,
+ const WriteCallback& write_callback,
base::PlatformFileError rv,
int64 bytes,
FileWriterDelegate::WriteProgressStatus write_status) {
- if (write_callback_.is_null()) {
- // If cancelled, callback is already invoked and set to null in Cancel().
- // We must not call it twice. Just shut down this operation object.
- delete this;
- return;
- }
-
const bool complete = (
write_status != FileWriterDelegate::SUCCESS_IO_PENDING);
if (complete && write_status != FileWriterDelegate::ERROR_WRITE_NOT_STARTED) {
- operation_context()->change_observers()->Notify(
+ DCHECK(operation_context_);
+ operation_context_->change_observers()->Notify(
&FileChangeObserver::OnModifyFile, MakeTuple(url));
}
- write_callback_.Run(rv, bytes, complete);
- if (complete || rv != base::PLATFORM_FILE_OK)
- delete this;
-}
-
-void LocalFileSystemOperation::DidTouchFile(const StatusCallback& callback,
- base::PlatformFileError rv) {
- callback.Run(rv);
+ StatusCallback cancel_callback = cancel_callback_;
+ write_callback.Run(rv, bytes, complete);
+ if (!cancel_callback.is_null())
+ cancel_callback.Run(base::PLATFORM_FILE_OK);
}
void LocalFileSystemOperation::DidOpenFile(
@@ -605,15 +543,6 @@ void LocalFileSystemOperation::DidOpenFile(
peer_handle_);
}
-void LocalFileSystemOperation::DidCreateSnapshotFile(
- const SnapshotFileCallback& callback,
- base::PlatformFileError result,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path,
- const scoped_refptr<ShareableFileReference>& file_ref) {
- callback.Run(result, file_info, platform_path, file_ref);
-}
-
bool LocalFileSystemOperation::SetPendingOperationType(OperationType type) {
if (pending_operation_ != kOperationNone)
return false;
diff --git a/webkit/browser/fileapi/local_file_system_operation.h b/webkit/browser/fileapi/local_file_system_operation.h
index 35ab32b..afb96b3 100644
--- a/webkit/browser/fileapi/local_file_system_operation.h
+++ b/webkit/browser/fileapi/local_file_system_operation.h
@@ -9,7 +9,9 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "webkit/browser/fileapi/file_system_operation.h"
+#include "webkit/browser/fileapi/file_system_operation_context.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/browser/fileapi/file_writer_delegate.h"
#include "webkit/common/blob/scoped_file.h"
@@ -32,7 +34,8 @@ class RecursiveOperationDelegate;
// FileSystemOperation implementation for local file systems.
class WEBKIT_STORAGE_EXPORT LocalFileSystemOperation
- : public NON_EXPORTED_BASE(FileSystemOperation) {
+ : public NON_EXPORTED_BASE(FileSystemOperation),
+ public base::SupportsWeakPtr<LocalFileSystemOperation> {
public:
// NOTE: This constructor should not be called outside MountPointProviders;
// instead please consider using
@@ -165,10 +168,6 @@ class WEBKIT_STORAGE_EXPORT LocalFileSystemOperation
return file_system_context_.get();
}
- FileSystemOperationContext* operation_context() const {
- return operation_context_.get();
- }
-
private:
friend class sync_file_system::SyncableFileSystemOperation;
@@ -233,14 +232,8 @@ class WEBKIT_STORAGE_EXPORT LocalFileSystemOperation
base::PlatformFileError rv,
bool created);
- // Generic callback that translates platform errors to WebKit error codes.
- void DidFinishFileOperation(const StatusCallback& callback,
- base::PlatformFileError rv);
-
- // Generic callback when we delegated the operation.
- void DidFinishDelegatedOperation(const StatusCallback& callback,
- base::PlatformFileError rv);
-
+ void DidFinishOperation(const StatusCallback& callback,
+ base::PlatformFileError rv);
void DidDirectoryExists(const StatusCallback& callback,
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
@@ -249,30 +242,15 @@ class WEBKIT_STORAGE_EXPORT LocalFileSystemOperation
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
const base::FilePath& unused);
- void DidGetMetadata(const GetMetadataCallback& callback,
- base::PlatformFileError rv,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path);
- void DidReadDirectory(const ReadDirectoryCallback& callback,
- base::PlatformFileError rv,
- const std::vector<DirectoryEntry>& entries,
- bool has_more);
void DidWrite(const FileSystemURL& url,
+ const WriteCallback& callback,
base::PlatformFileError rv,
int64 bytes,
FileWriterDelegate::WriteProgressStatus write_status);
- void DidTouchFile(const StatusCallback& callback,
- base::PlatformFileError rv);
void DidOpenFile(const OpenFileCallback& callback,
base::PlatformFileError rv,
base::PassPlatformFile file,
bool created);
- void DidCreateSnapshotFile(
- const SnapshotFileCallback& callback,
- base::PlatformFileError result,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref);
// Used only for internal assertions.
// Returns false if there's another inflight pending operation.
@@ -283,17 +261,9 @@ class WEBKIT_STORAGE_EXPORT LocalFileSystemOperation
scoped_ptr<FileSystemOperationContext> operation_context_;
AsyncFileUtil* async_file_util_; // Not owned.
- // These are all used only by Write().
- friend class FileWriterDelegate;
scoped_ptr<FileWriterDelegate> file_writer_delegate_;
-
scoped_ptr<RecursiveOperationDelegate> recursive_operation_delegate_;
- // write_callback is kept in this class for so that we can dispatch it when
- // the operation is cancelled. calcel_callback is kept for canceling a
- // Truncate() operation. We can't actually stop Truncate in another thread;
- // after it resumed from the working thread, cancellation takes place.
- WriteCallback write_callback_;
StatusCallback cancel_callback_;
// Used only by OpenFile, in order to clone the file handle back to the
@@ -303,10 +273,6 @@ class WEBKIT_STORAGE_EXPORT LocalFileSystemOperation
// A flag to make sure we call operation only once per instance.
OperationType pending_operation_;
- // LocalFileSystemOperation instance is usually deleted upon completion but
- // could be deleted while it has inflight callbacks when Cancel is called.
- base::WeakPtrFactory<LocalFileSystemOperation> weak_factory_;
-
DISALLOW_COPY_AND_ASSIGN(LocalFileSystemOperation);
};
diff --git a/webkit/browser/fileapi/syncable/syncable_file_system_operation.cc b/webkit/browser/fileapi/syncable/syncable_file_system_operation.cc
index 0a91777..4aee609 100644
--- a/webkit/browser/fileapi/syncable/syncable_file_system_operation.cc
+++ b/webkit/browser/fileapi/syncable/syncable_file_system_operation.cc
@@ -8,6 +8,7 @@
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_operation_context.h"
#include "webkit/browser/fileapi/file_system_url.h"
+#include "webkit/browser/fileapi/local_file_system_operation.h"
#include "webkit/browser/fileapi/sandbox_mount_point_provider.h"
#include "webkit/browser/fileapi/syncable/local_file_sync_context.h"
#include "webkit/browser/fileapi/syncable/syncable_file_operation_runner.h"
@@ -33,9 +34,11 @@ void WriteCallbackAdapter(
class SyncableFileSystemOperation::QueueableTask
: public SyncableFileOperationRunner::Task {
public:
- QueueableTask(SyncableFileSystemOperation* operation,
+ QueueableTask(base::WeakPtr<SyncableFileSystemOperation> operation,
const base::Closure& task)
- : operation_(operation), task_(task) {}
+ : operation_(operation),
+ task_(task),
+ target_paths_(operation->target_paths_) {}
virtual ~QueueableTask() {
DCHECK(!operation_);
@@ -44,25 +47,25 @@ class SyncableFileSystemOperation::QueueableTask
virtual void Run() OVERRIDE {
DCHECK(!task_.is_null());
task_.Run();
- operation_ = NULL;
+ operation_.reset();
}
virtual void Cancel() OVERRIDE {
DCHECK(!task_.is_null());
- DCHECK(operation_);
- operation_->OnCancelled();
- task_.Reset(); // This will delete operation_.
- operation_ = NULL;
+ if (operation_)
+ operation_->OnCancelled();
+ task_.Reset();
+ operation_.reset();
}
- virtual std::vector<FileSystemURL>& target_paths() const OVERRIDE {
- DCHECK(operation_);
- return operation_->target_paths_;
+ virtual const std::vector<FileSystemURL>& target_paths() const OVERRIDE {
+ return target_paths_;
}
private:
- SyncableFileSystemOperation* operation_;
+ base::WeakPtr<SyncableFileSystemOperation> operation_;
base::Closure task_;
+ std::vector<FileSystemURL> target_paths_;
DISALLOW_COPY_AND_ASSIGN(QueueableTask);
};
@@ -74,18 +77,18 @@ void SyncableFileSystemOperation::CreateFile(
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
+ callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
return;
}
DCHECK(operation_runner_.get());
target_paths_.push_back(url);
completion_callback_ = callback;
scoped_ptr<SyncableFileOperationRunner::Task> task(new QueueableTask(
- this,
+ AsWeakPtr(),
base::Bind(&FileSystemOperation::CreateFile,
- base::Unretained(NewOperation()),
+ NewOperation()->AsWeakPtr(),
url, exclusive,
- base::Bind(&self::DidFinish, base::Owned(this)))));
+ base::Bind(&self::DidFinish, AsWeakPtr()))));
operation_runner_->PostOperationTask(task.Pass());
}
@@ -96,22 +99,22 @@ void SyncableFileSystemOperation::CreateDirectory(
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
+ callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
return;
}
if (!is_directory_operation_enabled_) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
+ callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
return;
}
DCHECK(operation_runner_.get());
target_paths_.push_back(url);
completion_callback_ = callback;
scoped_ptr<SyncableFileOperationRunner::Task> task(new QueueableTask(
- this,
+ AsWeakPtr(),
base::Bind(&FileSystemOperation::CreateDirectory,
- base::Unretained(NewOperation()),
+ NewOperation()->AsWeakPtr(),
url, exclusive, recursive,
- base::Bind(&self::DidFinish, base::Owned(this)))));
+ base::Bind(&self::DidFinish, AsWeakPtr()))));
operation_runner_->PostOperationTask(task.Pass());
}
@@ -121,18 +124,18 @@ void SyncableFileSystemOperation::Copy(
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
+ callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
return;
}
DCHECK(operation_runner_.get());
target_paths_.push_back(dest_url);
completion_callback_ = callback;
scoped_ptr<SyncableFileOperationRunner::Task> task(new QueueableTask(
- this,
+ AsWeakPtr(),
base::Bind(&FileSystemOperation::Copy,
- base::Unretained(NewOperation()),
+ NewOperation()->AsWeakPtr(),
src_url, dest_url,
- base::Bind(&self::DidFinish, base::Owned(this)))));
+ base::Bind(&self::DidFinish, AsWeakPtr()))));
operation_runner_->PostOperationTask(task.Pass());
}
@@ -142,7 +145,7 @@ void SyncableFileSystemOperation::Move(
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
+ callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
return;
}
DCHECK(operation_runner_.get());
@@ -150,11 +153,11 @@ void SyncableFileSystemOperation::Move(
target_paths_.push_back(dest_url);
completion_callback_ = callback;
scoped_ptr<SyncableFileOperationRunner::Task> task(new QueueableTask(
- this,
+ AsWeakPtr(),
base::Bind(&FileSystemOperation::Move,
- base::Unretained(NewOperation()),
+ NewOperation()->AsWeakPtr(),
src_url, dest_url,
- base::Bind(&self::DidFinish, base::Owned(this)))));
+ base::Bind(&self::DidFinish, AsWeakPtr()))));
operation_runner_->PostOperationTask(task.Pass());
}
@@ -162,55 +165,31 @@ void SyncableFileSystemOperation::DirectoryExists(
const FileSystemURL& url,
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
- if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
- return;
- }
NewOperation()->DirectoryExists(url, callback);
- delete this;
}
void SyncableFileSystemOperation::FileExists(
const FileSystemURL& url,
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
- if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
- return;
- }
NewOperation()->FileExists(url, callback);
- delete this;
}
void SyncableFileSystemOperation::GetMetadata(
const FileSystemURL& url,
const GetMetadataCallback& callback) {
DCHECK(CalledOnValidThread());
- if (!operation_runner_.get()) {
- callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND,
- base::PlatformFileInfo(),
- base::FilePath());
- delete this;
- return;
- }
NewOperation()->GetMetadata(url, callback);
- delete this;
}
void SyncableFileSystemOperation::ReadDirectory(
const FileSystemURL& url,
const ReadDirectoryCallback& callback) {
DCHECK(CalledOnValidThread());
- if (!operation_runner_.get()) {
- callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND, FileEntryList(), false);
- delete this;
- return;
- }
// This is a read operation and there'd be no hard to let it go even if
// directory operation is disabled. (And we should allow this if it's made
// on the root directory)
NewOperation()->ReadDirectory(url, callback);
- delete this;
}
void SyncableFileSystemOperation::Remove(
@@ -218,18 +197,18 @@ void SyncableFileSystemOperation::Remove(
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
+ callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
return;
}
DCHECK(operation_runner_.get());
target_paths_.push_back(url);
completion_callback_ = callback;
scoped_ptr<SyncableFileOperationRunner::Task> task(new QueueableTask(
- this,
+ AsWeakPtr(),
base::Bind(&FileSystemOperation::Remove,
- base::Unretained(NewOperation()),
+ NewOperation()->AsWeakPtr(),
url, recursive,
- base::Bind(&self::DidFinish, base::Owned(this)))));
+ base::Bind(&self::DidFinish, AsWeakPtr()))));
operation_runner_->PostOperationTask(task.Pass());
}
@@ -242,17 +221,16 @@ void SyncableFileSystemOperation::Write(
DCHECK(CalledOnValidThread());
if (!operation_runner_.get()) {
callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND, 0, true);
- delete this;
return;
}
DCHECK(operation_runner_.get());
target_paths_.push_back(url);
completion_callback_ = base::Bind(&WriteCallbackAdapter, callback);
scoped_ptr<SyncableFileOperationRunner::Task> task(new QueueableTask(
- this,
+ AsWeakPtr(),
NewOperation()->GetWriteClosure(
url_request_context, url, blob_url, offset,
- base::Bind(&self::DidWrite, base::Owned(this), callback))));
+ base::Bind(&self::DidWrite, AsWeakPtr(), callback))));
operation_runner_->PostOperationTask(task.Pass());
}
@@ -261,18 +239,18 @@ void SyncableFileSystemOperation::Truncate(
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
+ callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
return;
}
DCHECK(operation_runner_.get());
target_paths_.push_back(url);
completion_callback_ = callback;
scoped_ptr<SyncableFileOperationRunner::Task> task(new QueueableTask(
- this,
+ AsWeakPtr(),
base::Bind(&FileSystemOperation::Truncate,
- base::Unretained(NewOperation()),
+ NewOperation()->AsWeakPtr(),
url, length,
- base::Bind(&self::DidFinish, base::Owned(this)))));
+ base::Bind(&self::DidFinish, AsWeakPtr()))));
operation_runner_->PostOperationTask(task.Pass());
}
@@ -282,13 +260,8 @@ void SyncableFileSystemOperation::TouchFile(
const base::Time& last_modified_time,
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
- if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
- return;
- }
NewOperation()->TouchFile(url, last_access_time,
last_modified_time, callback);
- delete this;
}
void SyncableFileSystemOperation::OpenFile(
@@ -297,7 +270,6 @@ void SyncableFileSystemOperation::OpenFile(
base::ProcessHandle peer_handle,
const OpenFileCallback& callback) {
NOTREACHED();
- delete this;
}
void SyncableFileSystemOperation::Cancel(
@@ -311,16 +283,7 @@ void SyncableFileSystemOperation::CreateSnapshotFile(
const FileSystemURL& path,
const SnapshotFileCallback& callback) {
DCHECK(CalledOnValidThread());
- if (!operation_runner_.get()) {
- callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND,
- base::PlatformFileInfo(),
- base::FilePath(),
- NULL);
- delete this;
- return;
- }
NewOperation()->CreateSnapshotFile(path, callback);
- delete this;
}
void SyncableFileSystemOperation::CopyInForeignFile(
@@ -329,18 +292,18 @@ void SyncableFileSystemOperation::CopyInForeignFile(
const StatusCallback& callback) {
DCHECK(CalledOnValidThread());
if (!operation_runner_.get()) {
- AbortOperation(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
+ callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
return;
}
DCHECK(operation_runner_.get());
target_paths_.push_back(dest_url);
completion_callback_ = callback;
scoped_ptr<SyncableFileOperationRunner::Task> task(new QueueableTask(
- this,
+ AsWeakPtr(),
base::Bind(&LocalFileSystemOperation::CopyInForeignFile,
- base::Unretained(NewOperation()),
+ NewOperation()->AsWeakPtr(),
src_local_disk_path, dest_url,
- base::Bind(&self::DidFinish, base::Owned(this)))));
+ base::Bind(&self::DidFinish, AsWeakPtr()))));
operation_runner_->PostOperationTask(task.Pass());
}
@@ -350,8 +313,7 @@ SyncableFileSystemOperation::SyncableFileSystemOperation(
scoped_ptr<FileSystemOperationContext> operation_context)
: LocalFileSystemOperation(url, file_system_context,
operation_context.Pass()),
- url_(url),
- inflight_operation_(NULL) {
+ url_(url) {
DCHECK(file_system_context);
if (!file_system_context->sync_context()) {
// Syncable FileSystem is opened in a file system context which doesn't
@@ -365,10 +327,10 @@ SyncableFileSystemOperation::SyncableFileSystemOperation(
LocalFileSystemOperation* SyncableFileSystemOperation::NewOperation() {
DCHECK(operation_context_);
- inflight_operation_ = new LocalFileSystemOperation(
- url_, file_system_context(), operation_context_.Pass());
+ inflight_operation_.reset(new LocalFileSystemOperation(
+ url_, file_system_context(), operation_context_.Pass()));
DCHECK(inflight_operation_);
- return inflight_operation_;
+ return inflight_operation_.get();
}
void SyncableFileSystemOperation::DidFinish(base::PlatformFileError status) {
@@ -397,15 +359,6 @@ void SyncableFileSystemOperation::DidWrite(
void SyncableFileSystemOperation::OnCancelled() {
DCHECK(!completion_callback_.is_null());
completion_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT);
- delete inflight_operation_;
-}
-
-void SyncableFileSystemOperation::AbortOperation(
- const StatusCallback& callback,
- base::PlatformFileError error) {
- callback.Run(error);
- delete inflight_operation_;
- delete this;
}
} // namespace sync_file_system
diff --git a/webkit/browser/fileapi/syncable/syncable_file_system_operation.h b/webkit/browser/fileapi/syncable/syncable_file_system_operation.h
index f808347..90b68b2d 100644
--- a/webkit/browser/fileapi/syncable/syncable_file_system_operation.h
+++ b/webkit/browser/fileapi/syncable/syncable_file_system_operation.h
@@ -28,6 +28,7 @@ class SyncableFileOperationRunner;
// A wrapper class of LocalFileSystemOperation for syncable file system.
class WEBKIT_STORAGE_EXPORT SyncableFileSystemOperation
: public fileapi::LocalFileSystemOperation,
+ public base::SupportsWeakPtr<SyncableFileSystemOperation>,
public base::NonThreadSafe {
public:
virtual ~SyncableFileSystemOperation();
@@ -81,6 +82,8 @@ class WEBKIT_STORAGE_EXPORT SyncableFileSystemOperation
const fileapi::FileSystemURL& dest_url,
const StatusCallback& callback) OVERRIDE;
+ using base::SupportsWeakPtr<SyncableFileSystemOperation>::AsWeakPtr;
+
private:
typedef SyncableFileSystemOperation self;
class QueueableTask;
@@ -101,13 +104,11 @@ class WEBKIT_STORAGE_EXPORT SyncableFileSystemOperation
bool complete);
void OnCancelled();
- void AbortOperation(const StatusCallback& callback,
- base::PlatformFileError error);
const fileapi::FileSystemURL url_;
base::WeakPtr<SyncableFileOperationRunner> operation_runner_;
- fileapi::LocalFileSystemOperation* inflight_operation_;
+ scoped_ptr<fileapi::LocalFileSystemOperation> inflight_operation_;
std::vector<fileapi::FileSystemURL> target_paths_;
StatusCallback completion_callback_;