diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-10 17:52:43 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-10 17:52:43 +0000 |
commit | 2c02c8d3eb2827b2d2c9b5e300a7cf49f5c2624a (patch) | |
tree | 3b74668cbd3f3d7e3f8725a949f92cf85c318e04 /webkit | |
parent | 312d44ffbf5671224e50754d690dfdc98aad0fc2 (diff) | |
download | chromium_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')
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_; |