Commit d3c0d246 authored by Wez's avatar Wez Committed by Commit Bot

Simplify implementation of FileSystemOperationRunner.

- Use a base::AutoReset instance to manage a single integer tracking
  whether the completion callback for an operation is invoked before
  we have actually returned to the caller.
- Remove the now-unused OperationHandle and BeginOperationScoper.
- Replace SupportsWeakPtr with an internal WeakPtrFactory.
- Replace potentially unsafe use of GetWeakPtr() with a |weak_ptr_|
  member.
- Temporarily disables the recently-added FileSystemURLLoaderFactoryTest
  tests, which have incorrect threading, causing WeakPtr checks to
  fire.

Bug: 846985, 860547
Change-Id: Ia059b1b87ef11f3218aeb6c65d7b8dd62be6c393
Reviewed-on: https://chromium-review.googlesource.com/1074427
Commit-Queue: Wez <wez@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@chromium.org>
Reviewed-by: default avatarTaiju Tsuiki <tzik@chromium.org>
Reviewed-by: default avatarChris Mumford <cmumford@chromium.org>
Reviewed-by: default avatarAlexander Alekseev <alemate@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574220}
parent 34a5e243
......@@ -406,6 +406,25 @@ class ConvertSelectedFileInfoListToFileChooserFileInfoListImpl {
ConvertSelectedFileInfoListToFileChooserFileInfoListImpl);
};
void CheckIfDirectoryExistsOnIoThread(
scoped_refptr<storage::FileSystemContext> file_system_context,
const storage::FileSystemURL& internal_url,
storage::FileSystemOperationRunner::StatusCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
file_system_context->operation_runner()->DirectoryExists(internal_url,
std::move(callback));
}
void GetMetadataForPathOnIoThread(
scoped_refptr<storage::FileSystemContext> file_system_context,
const storage::FileSystemURL& internal_url,
int fields,
storage::FileSystemOperationRunner::GetMetadataCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
file_system_context->operation_runner()->GetMetadata(internal_url, fields,
callback);
}
} // namespace
EntryDefinition::EntryDefinition() = default;
......@@ -548,9 +567,7 @@ void CheckIfDirectoryExists(
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(base::IgnoreResult(
&storage::FileSystemOperationRunner::DirectoryExists),
file_system_context->operation_runner()->AsWeakPtr(),
base::BindOnce(&CheckIfDirectoryExistsOnIoThread, file_system_context,
internal_url, google_apis::CreateRelayCallback(callback)));
}
......@@ -569,10 +586,9 @@ void GetMetadataForPath(
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
base::IgnoreResult(&storage::FileSystemOperationRunner::GetMetadata),
file_system_context->operation_runner()->AsWeakPtr(), internal_url,
fields, google_apis::CreateRelayCallback(callback)));
base::BindOnce(&GetMetadataForPathOnIoThread, file_system_context,
internal_url, fields,
google_apis::CreateRelayCallback(callback)));
}
storage::FileSystemURL CreateIsolatedURLFromVirtualPath(
......
......@@ -732,7 +732,10 @@ test("content_browsertests") {
"../browser/download/mhtml_generation_browsertest.cc",
"../browser/download/save_package_browsertest.cc",
"../browser/fileapi/file_system_browsertest.cc",
"../browser/fileapi/file_system_url_loader_factory_browsertest.cc",
# These tests have incorrect threading (https://crbug.com/860547).
#"../browser/fileapi/file_system_url_loader_factory_browsertest.cc",
"../browser/fileapi/fileapi_browsertest.cc",
"../browser/find_request_manager_browsertest.cc",
"../browser/frame_host/blocked_scheme_navigation_browsertest.cc",
......
......@@ -824,12 +824,14 @@ ExtensionFunction::ResponseAction FileSystemRetainEntryFunction::Run() {
->CreateVirtualRootPath(filesystem_id)
.Append(base::FilePath::FromUTF8Unsafe(filesystem_path)));
// It is safe to use base::Unretained() for operation_runner(), since it
// is owned by |context| which will delete it on the IO thread.
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::BindOnce(
base::IgnoreResult(
&storage::FileSystemOperationRunner::GetMetadata),
context->operation_runner()->AsWeakPtr(), url,
base::Unretained(context->operation_runner()), url,
storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY,
base::Bind(
&PassFileInfoToUIThread,
......
......@@ -380,6 +380,8 @@ FileSystemOperationImpl::FileSystemOperationImpl(
async_file_util_(NULL),
pending_operation_(kOperationNone),
weak_factory_(this) {
weak_ptr_ = weak_factory_.GetWeakPtr();
DCHECK(operation_context_.get());
operation_context_->DetachFromSequence();
async_file_util_ = file_system_context_->GetAsyncFileUtil(url.type());
......@@ -407,7 +409,7 @@ void FileSystemOperationImpl::GetUsageAndQuotaThenRunTask(
quota_manager_proxy->quota_manager()->GetUsageAndQuota(
url.origin(), FileSystemTypeToQuotaStorageType(url.type()),
base::BindOnce(&FileSystemOperationImpl::DidGetUsageAndQuotaAndRunTask,
weak_factory_.GetWeakPtr(), task, error_callback));
weak_ptr_, task, error_callback));
}
void FileSystemOperationImpl::DidGetUsageAndQuotaAndRunTask(
......@@ -435,7 +437,7 @@ void FileSystemOperationImpl::DoCreateFile(
base::BindOnce(
exclusive ? &FileSystemOperationImpl::DidEnsureFileExistsExclusive
: &FileSystemOperationImpl::DidEnsureFileExistsNonExclusive,
weak_factory_.GetWeakPtr(), callback));
weak_ptr_, callback));
}
void FileSystemOperationImpl::DoCreateDirectory(
......@@ -444,8 +446,8 @@ void FileSystemOperationImpl::DoCreateDirectory(
bool exclusive, bool recursive) {
async_file_util_->CreateDirectory(
std::move(operation_context_), url, exclusive, recursive,
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation,
weak_factory_.GetWeakPtr(), callback));
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, weak_ptr_,
callback));
}
void FileSystemOperationImpl::DoCopyFileLocal(
......@@ -457,8 +459,8 @@ void FileSystemOperationImpl::DoCopyFileLocal(
async_file_util_->CopyFileLocal(
std::move(operation_context_), src_url, dest_url, option,
progress_callback,
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation,
weak_factory_.GetWeakPtr(), callback));
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, weak_ptr_,
callback));
}
void FileSystemOperationImpl::DoMoveFileLocal(
......@@ -468,8 +470,8 @@ void FileSystemOperationImpl::DoMoveFileLocal(
const StatusCallback& callback) {
async_file_util_->MoveFileLocal(
std::move(operation_context_), src_url, dest_url, option,
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation,
weak_factory_.GetWeakPtr(), callback));
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, weak_ptr_,
callback));
}
void FileSystemOperationImpl::DoCopyInForeignFile(
......@@ -478,8 +480,8 @@ void FileSystemOperationImpl::DoCopyInForeignFile(
const StatusCallback& callback) {
async_file_util_->CopyInForeignFile(
std::move(operation_context_), src_local_disk_file_path, dest_url,
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation,
weak_factory_.GetWeakPtr(), callback));
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, weak_ptr_,
callback));
}
void FileSystemOperationImpl::DoTruncate(const FileSystemURL& url,
......@@ -487,8 +489,8 @@ void FileSystemOperationImpl::DoTruncate(const FileSystemURL& url,
int64_t length) {
async_file_util_->Truncate(
std::move(operation_context_), url, length,
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation,
weak_factory_.GetWeakPtr(), callback));
base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, weak_ptr_,
callback));
}
void FileSystemOperationImpl::DoOpenFile(const FileSystemURL& url,
......@@ -496,8 +498,7 @@ void FileSystemOperationImpl::DoOpenFile(const FileSystemURL& url,
int file_flags) {
async_file_util_->CreateOrOpen(
std::move(operation_context_), url, file_flags,
base::BindOnce(&DidOpenFile, file_system_context_,
weak_factory_.GetWeakPtr(), callback));
base::BindOnce(&DidOpenFile, file_system_context_, weak_ptr_, callback));
}
void FileSystemOperationImpl::DidEnsureFileExistsExclusive(
......@@ -557,11 +558,10 @@ void FileSystemOperationImpl::DidDeleteRecursively(
if (rv == base::File::FILE_ERROR_INVALID_OPERATION) {
// Recursive removal is not supported on this platform.
DCHECK(!recursive_operation_delegate_);
recursive_operation_delegate_.reset(
new RemoveOperationDelegate(
recursive_operation_delegate_.reset(new RemoveOperationDelegate(
file_system_context(), url,
base::Bind(&FileSystemOperationImpl::DidFinishOperation,
weak_factory_.GetWeakPtr(), callback)));
base::Bind(&FileSystemOperationImpl::DidFinishOperation, weak_ptr_,
callback)));
recursive_operation_delegate_->RunRecursively();
return;
}
......
......@@ -198,6 +198,7 @@ class STORAGE_EXPORT FileSystemOperationImpl : public FileSystemOperation {
// A flag to make sure we call operation only once per instance.
OperationType pending_operation_;
base::WeakPtr<FileSystemOperationImpl> weak_ptr_;
base::WeakPtrFactory<FileSystemOperationImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImpl);
......
......@@ -10,6 +10,7 @@
#include <tuple>
#include <utility>
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
......@@ -27,21 +28,6 @@ namespace storage {
using OperationID = FileSystemOperationRunner::OperationID;
class FileSystemOperationRunner::BeginOperationScoper
: public base::SupportsWeakPtr<
FileSystemOperationRunner::BeginOperationScoper> {
public:
BeginOperationScoper() = default;
private:
DISALLOW_COPY_AND_ASSIGN(BeginOperationScoper);
};
FileSystemOperationRunner::OperationHandle::OperationHandle() = default;
FileSystemOperationRunner::OperationHandle::OperationHandle(
const OperationHandle& other) = default;
FileSystemOperationRunner::OperationHandle::~OperationHandle() = default;
FileSystemOperationRunner::~FileSystemOperationRunner() = default;
void FileSystemOperationRunner::Shutdown() {
......@@ -58,19 +44,17 @@ OperationID FileSystemOperationRunner::CreateFile(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, url);
operation_raw->CreateFile(
url, exclusive,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
PrepareForWrite(id, url);
operation_raw->CreateFile(url, exclusive,
base::Bind(&FileSystemOperationRunner::DidFinish,
weak_ptr_, id, callback));
return id;
}
OperationID FileSystemOperationRunner::CreateDirectory(
......@@ -82,19 +66,18 @@ OperationID FileSystemOperationRunner::CreateDirectory(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, url);
PrepareForWrite(id, url);
operation_raw->CreateDirectory(
url, exclusive, recursive,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
base::Bind(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
callback));
return id;
}
OperationID FileSystemOperationRunner::Copy(
......@@ -108,23 +91,23 @@ OperationID FileSystemOperationRunner::Copy(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(dest_url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, dest_url);
PrepareForRead(handle.id, src_url);
operation_raw->Copy(src_url, dest_url, option, error_behavior,
PrepareForWrite(id, dest_url);
PrepareForRead(id, src_url);
operation_raw->Copy(
src_url, dest_url, option, error_behavior,
progress_callback.is_null()
? CopyProgressCallback()
: base::Bind(&FileSystemOperationRunner::OnCopyProgress,
AsWeakPtr(), handle, progress_callback),
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
: base::Bind(&FileSystemOperationRunner::OnCopyProgress, weak_ptr_,
id, progress_callback),
base::Bind(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
callback));
return id;
}
OperationID FileSystemOperationRunner::Move(
......@@ -136,20 +119,18 @@ OperationID FileSystemOperationRunner::Move(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(dest_url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, dest_url);
PrepareForWrite(handle.id, src_url);
operation_raw->Move(
src_url, dest_url, option,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
PrepareForWrite(id, dest_url);
PrepareForWrite(id, src_url);
operation_raw->Move(src_url, dest_url, option,
base::Bind(&FileSystemOperationRunner::DidFinish,
weak_ptr_, id, callback));
return id;
}
OperationID FileSystemOperationRunner::DirectoryExists(
......@@ -159,19 +140,17 @@ OperationID FileSystemOperationRunner::DirectoryExists(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForRead(handle.id, url);
PrepareForRead(id, url);
operation_raw->DirectoryExists(
url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
url, base::Bind(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
callback));
return id;
}
OperationID FileSystemOperationRunner::FileExists(
......@@ -181,19 +160,17 @@ OperationID FileSystemOperationRunner::FileExists(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForRead(handle.id, url);
PrepareForRead(id, url);
operation_raw->FileExists(
url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
url, base::Bind(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
callback));
return id;
}
OperationID FileSystemOperationRunner::GetMetadata(
......@@ -204,18 +181,18 @@ OperationID FileSystemOperationRunner::GetMetadata(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidGetMetadata(handle, callback, error, base::File::Info());
return handle.id;
DidGetMetadata(id, callback, error, base::File::Info());
return id;
}
PrepareForRead(handle.id, url);
operation_raw->GetMetadata(url, fields,
base::Bind(&FileSystemOperationRunner::DidGetMetadata,
AsWeakPtr(), handle, callback));
return handle.id;
PrepareForRead(id, url);
operation_raw->GetMetadata(
url, fields,
base::Bind(&FileSystemOperationRunner::DidGetMetadata, weak_ptr_, id,
callback));
return id;
}
OperationID FileSystemOperationRunner::ReadDirectory(
......@@ -225,19 +202,18 @@ OperationID FileSystemOperationRunner::ReadDirectory(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidReadDirectory(handle, std::move(callback), error,
DidReadDirectory(id, std::move(callback), error,
std::vector<filesystem::mojom::DirectoryEntry>(), false);
return handle.id;
return id;
}
PrepareForRead(handle.id, url);
PrepareForRead(id, url);
operation_raw->ReadDirectory(
url, base::BindRepeating(&FileSystemOperationRunner::DidReadDirectory,
AsWeakPtr(), handle, callback));
return handle.id;
weak_ptr_, id, callback));
return id;
}
OperationID FileSystemOperationRunner::Remove(
......@@ -247,19 +223,17 @@ OperationID FileSystemOperationRunner::Remove(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, url);
operation_raw->Remove(
url, recursive,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
PrepareForWrite(id, url);
operation_raw->Remove(url, recursive,
base::Bind(&FileSystemOperationRunner::DidFinish,
weak_ptr_, id, callback));
return id;
}
OperationID FileSystemOperationRunner::Write(
......@@ -272,20 +246,19 @@ OperationID FileSystemOperationRunner::Write(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidWrite(handle, callback, error, 0, true);
return handle.id;
DidWrite(id, callback, error, 0, true);
return id;
}
std::unique_ptr<FileStreamWriter> writer(
file_system_context_->CreateFileStreamWriter(url, offset));
if (!writer) {
// Write is not supported.
DidWrite(handle, callback, base::File::FILE_ERROR_SECURITY, 0, true);
return handle.id;
DidWrite(id, callback, base::File::FILE_ERROR_SECURITY, 0, true);
return id;
}
std::unique_ptr<FileWriterDelegate> writer_delegate(new FileWriterDelegate(
......@@ -295,11 +268,11 @@ OperationID FileSystemOperationRunner::Write(
storage::BlobProtocolHandler::CreateBlobRequest(
std::move(blob), url_request_context, writer_delegate.get()));
PrepareForWrite(handle.id, url);
PrepareForWrite(id, url);
operation_raw->Write(url, std::move(writer_delegate), std::move(blob_request),
base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
handle, callback));
return handle.id;
base::Bind(&FileSystemOperationRunner::DidWrite,
weak_ptr_, id, callback));
return id;
}
OperationID FileSystemOperationRunner::Truncate(
......@@ -310,19 +283,17 @@ OperationID FileSystemOperationRunner::Truncate(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, url);
operation_raw->Truncate(
url, length,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
PrepareForWrite(id, url);
operation_raw->Truncate(url, length,
base::Bind(&FileSystemOperationRunner::DidFinish,
weak_ptr_, id, callback));
return id;
}
void FileSystemOperationRunner::Cancel(
......@@ -352,19 +323,17 @@ OperationID FileSystemOperationRunner::TouchFile(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, url);
operation_raw->TouchFile(
url, last_access_time, last_modified_time,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
PrepareForWrite(id, url);
operation_raw->TouchFile(url, last_access_time, last_modified_time,
base::Bind(&FileSystemOperationRunner::DidFinish,
weak_ptr_, id, callback));
return id;
}
OperationID FileSystemOperationRunner::OpenFile(
......@@ -375,12 +344,11 @@ OperationID FileSystemOperationRunner::OpenFile(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidOpenFile(handle, callback, base::File(error), base::Closure());
return handle.id;
DidOpenFile(id, callback, base::File(error), base::Closure());
return id;
}
if (file_flags &
(base::File::FLAG_CREATE | base::File::FLAG_OPEN_ALWAYS |
......@@ -388,15 +356,14 @@ OperationID FileSystemOperationRunner::OpenFile(
base::File::FLAG_WRITE | base::File::FLAG_EXCLUSIVE_WRITE |
base::File::FLAG_DELETE_ON_CLOSE |
base::File::FLAG_WRITE_ATTRIBUTES)) {
PrepareForWrite(handle.id, url);
PrepareForWrite(id, url);
} else {
PrepareForRead(handle.id, url);
PrepareForRead(id, url);
}
operation_raw->OpenFile(
url, file_flags,
base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(),
handle, callback));
return handle.id;
operation_raw->OpenFile(url, file_flags,
base::Bind(&FileSystemOperationRunner::DidOpenFile,
weak_ptr_, id, callback));
return id;
}
OperationID FileSystemOperationRunner::CreateSnapshotFile(
......@@ -406,20 +373,18 @@ OperationID FileSystemOperationRunner::CreateSnapshotFile(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidCreateSnapshot(handle, callback, error, base::File::Info(),
base::FilePath(), NULL);
return handle.id;
DidCreateSnapshot(id, callback, error, base::File::Info(), base::FilePath(),
NULL);
return id;
}
PrepareForRead(handle.id, url);
PrepareForRead(id, url);
operation_raw->CreateSnapshotFile(
url,
base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(),
handle, callback));
return handle.id;
url, base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, weak_ptr_,
id, callback));
return id;
}
OperationID FileSystemOperationRunner::CopyInForeignFile(
......@@ -430,19 +395,18 @@ OperationID FileSystemOperationRunner::CopyInForeignFile(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(dest_url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, dest_url);
PrepareForWrite(id, dest_url);
operation_raw->CopyInForeignFile(
src_local_disk_path, dest_url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
base::Bind(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
callback));
return id;
}
OperationID FileSystemOperationRunner::RemoveFile(
......@@ -452,19 +416,17 @@ OperationID FileSystemOperationRunner::RemoveFile(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, url);
PrepareForWrite(id, url);
operation_raw->RemoveFile(
url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
url, base::Bind(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
callback));
return id;
}
OperationID FileSystemOperationRunner::RemoveDirectory(
......@@ -474,19 +436,17 @@ OperationID FileSystemOperationRunner::RemoveDirectory(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, url);
PrepareForWrite(id, url);
operation_raw->RemoveDirectory(
url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
url, base::Bind(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
callback));
return id;
}
OperationID FileSystemOperationRunner::CopyFileLocal(
......@@ -499,20 +459,18 @@ OperationID FileSystemOperationRunner::CopyFileLocal(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(src_url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForRead(handle.id, src_url);
PrepareForWrite(handle.id, dest_url);
operation_raw->CopyFileLocal(
src_url, dest_url, option, progress_callback,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
PrepareForRead(id, src_url);
PrepareForWrite(id, dest_url);
operation_raw->CopyFileLocal(src_url, dest_url, option, progress_callback,
base::Bind(&FileSystemOperationRunner::DidFinish,
weak_ptr_, id, callback));
return id;
}
OperationID FileSystemOperationRunner::MoveFileLocal(
......@@ -524,20 +482,18 @@ OperationID FileSystemOperationRunner::MoveFileLocal(
std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
file_system_context_->CreateFileSystemOperation(src_url, &error));
FileSystemOperation* operation_raw = operation.get();
BeginOperationScoper scope;
OperationHandle handle =
BeginOperation(std::move(operation), scope.AsWeakPtr());
OperationID id = BeginOperation(std::move(operation));
base::AutoReset<bool> beginning(&is_beginning_operation_, true);
if (!operation_raw) {
DidFinish(handle, callback, error);
return handle.id;
DidFinish(id, callback, error);
return id;
}
PrepareForWrite(handle.id, src_url);
PrepareForWrite(handle.id, dest_url);
operation_raw->MoveFileLocal(
src_url, dest_url, option,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
handle, callback));
return handle.id;
PrepareForWrite(id, src_url);
PrepareForWrite(id, dest_url);
operation_raw->MoveFileLocal(src_url, dest_url, option,
base::Bind(&FileSystemOperationRunner::DidFinish,
weak_ptr_, id, callback));
return id;
}
base::File::Error FileSystemOperationRunner::SyncGetPlatformPath(
......@@ -553,126 +509,125 @@ base::File::Error FileSystemOperationRunner::SyncGetPlatformPath(
FileSystemOperationRunner::FileSystemOperationRunner(
FileSystemContext* file_system_context)
: file_system_context_(file_system_context) {}
: file_system_context_(file_system_context), weak_factory_(this) {
weak_ptr_ = weak_factory_.GetWeakPtr();
}
void FileSystemOperationRunner::DidFinish(
const OperationHandle& handle,
void FileSystemOperationRunner::DidFinish(const OperationID id,
const StatusCallback& callback,
base::File::Error rv) {
if (handle.scope) {
finished_operations_.insert(handle.id);
if (is_beginning_operation_) {
finished_operations_.insert(id);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&FileSystemOperationRunner::DidFinish,
AsWeakPtr(), handle, callback, rv));
weak_ptr_, id, callback, rv));
return;
}
callback.Run(rv);
FinishOperation(handle.id);
FinishOperation(id);
}
void FileSystemOperationRunner::DidGetMetadata(
const OperationHandle& handle,
const OperationID id,
const GetMetadataCallback& callback,
base::File::Error rv,
const base::File::Info& file_info) {
if (handle.scope) {
finished_operations_.insert(handle.id);
if (is_beginning_operation_) {
finished_operations_.insert(id);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(),
handle, callback, rv, file_info));
FROM_HERE, base::BindOnce(&FileSystemOperationRunner::DidGetMetadata,
weak_ptr_, id, callback, rv, file_info));
return;
}
callback.Run(rv, file_info);
FinishOperation(handle.id);
FinishOperation(id);
}
void FileSystemOperationRunner::DidReadDirectory(
const OperationHandle& handle,
const OperationID id,
const ReadDirectoryCallback& callback,
base::File::Error rv,
std::vector<filesystem::mojom::DirectoryEntry> entries,
bool has_more) {
if (handle.scope) {
finished_operations_.insert(handle.id);
if (is_beginning_operation_) {
finished_operations_.insert(id);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&FileSystemOperationRunner::DidReadDirectory,
AsWeakPtr(), handle, callback, rv,
std::move(entries), has_more));
FROM_HERE,
base::BindOnce(&FileSystemOperationRunner::DidReadDirectory, weak_ptr_,
id, callback, rv, std::move(entries), has_more));
return;
}
callback.Run(rv, std::move(entries), has_more);
if (rv != base::File::FILE_OK || !has_more)
FinishOperation(handle.id);
FinishOperation(id);
}
void FileSystemOperationRunner::DidWrite(const OperationHandle& handle,
void FileSystemOperationRunner::DidWrite(const OperationID id,
const WriteCallback& callback,
base::File::Error rv,
int64_t bytes,
bool complete) {
if (handle.scope) {
finished_operations_.insert(handle.id);
if (is_beginning_operation_) {
finished_operations_.insert(id);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
handle, callback, rv, bytes, complete));
base::BindOnce(&FileSystemOperationRunner::DidWrite, weak_ptr_, id,
callback, rv, bytes, complete));
return;
}
callback.Run(rv, bytes, complete);
if (rv != base::File::FILE_OK || complete)
FinishOperation(handle.id);
FinishOperation(id);
}
void FileSystemOperationRunner::DidOpenFile(
const OperationHandle& handle,
const OperationID id,
const OpenFileCallback& callback,
base::File file,
base::OnceClosure on_close_callback) {
if (handle.scope) {
finished_operations_.insert(handle.id);
if (is_beginning_operation_) {
finished_operations_.insert(id);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(),
handle, callback, std::move(file),
FROM_HERE, base::BindOnce(&FileSystemOperationRunner::DidOpenFile,
weak_ptr_, id, callback, std::move(file),
std::move(on_close_callback)));
return;
}
callback.Run(std::move(file), std::move(on_close_callback));
FinishOperation(handle.id);
FinishOperation(id);
}
void FileSystemOperationRunner::DidCreateSnapshot(
const OperationHandle& handle,
const OperationID id,
const SnapshotFileCallback& callback,
base::File::Error rv,
const base::File::Info& file_info,
const base::FilePath& platform_path,
scoped_refptr<storage::ShareableFileReference> file_ref) {
if (handle.scope) {
finished_operations_.insert(handle.id);
if (is_beginning_operation_) {
finished_operations_.insert(id);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&FileSystemOperationRunner::DidCreateSnapshot,
AsWeakPtr(), handle, callback, rv, file_info,
weak_ptr_, id, callback, rv, file_info,
platform_path, std::move(file_ref)));
return;
}
callback.Run(rv, file_info, platform_path, std::move(file_ref));
FinishOperation(handle.id);
FinishOperation(id);
}
void FileSystemOperationRunner::OnCopyProgress(
const OperationHandle& handle,
const OperationID id,
const CopyProgressCallback& callback,
FileSystemOperation::CopyProgressType type,
const FileSystemURL& source_url,
const FileSystemURL& dest_url,
int64_t size) {
if (handle.scope) {
if (is_beginning_operation_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FileSystemOperationRunner::OnCopyProgress, AsWeakPtr(),
handle, callback, type, source_url, dest_url, size));
base::BindOnce(&FileSystemOperationRunner::OnCopyProgress, weak_ptr_,
id, callback, type, source_url, dest_url, size));
return;
}
callback.Run(type, source_url, dest_url, size);
......@@ -695,15 +650,11 @@ void FileSystemOperationRunner::PrepareForRead(OperationID id,
}
}
FileSystemOperationRunner::OperationHandle
FileSystemOperationRunner::BeginOperation(
std::unique_ptr<FileSystemOperation> operation,
base::WeakPtr<BeginOperationScoper> scope) {
OperationHandle handle;
handle.id = next_operation_id_++;
operations_.emplace(handle.id, std::move(operation));
handle.scope = scope;
return handle;
OperationID FileSystemOperationRunner::BeginOperation(
std::unique_ptr<FileSystemOperation> operation) {
OperationID id = next_operation_id_++;
operations_.emplace(id, std::move(operation));
return id;
}
void FileSystemOperationRunner::FinishOperation(OperationID id) {
......
......@@ -37,8 +37,7 @@ class FileSystemContext;
// operation fails, in addition to dispatching the callback with an error
// code (therefore in most cases the caller does not need to check the
// returned operation ID).
class STORAGE_EXPORT FileSystemOperationRunner
: public base::SupportsWeakPtr<FileSystemOperationRunner> {
class STORAGE_EXPORT FileSystemOperationRunner {
public:
using GetMetadataCallback = FileSystemOperation::GetMetadataCallback;
using ReadDirectoryCallback = FileSystemOperation::ReadDirectoryCallback;
......@@ -246,50 +245,39 @@ class STORAGE_EXPORT FileSystemOperationRunner
base::FilePath* platform_path);
private:
class BeginOperationScoper;
struct OperationHandle {
OperationID id;
base::WeakPtr<BeginOperationScoper> scope;
OperationHandle();
OperationHandle(const OperationHandle& other);
~OperationHandle();
};
friend class FileSystemContext;
explicit FileSystemOperationRunner(FileSystemContext* file_system_context);
void DidFinish(const OperationHandle& handle,
void DidFinish(const OperationID id,
const StatusCallback& callback,
base::File::Error rv);
void DidGetMetadata(const OperationHandle& handle,
void DidGetMetadata(const OperationID id,
const GetMetadataCallback& callback,
base::File::Error rv,
const base::File::Info& file_info);
void DidReadDirectory(const OperationHandle& handle,
void DidReadDirectory(const OperationID id,
const ReadDirectoryCallback& callback,
base::File::Error rv,
std::vector<filesystem::mojom::DirectoryEntry> entries,
bool has_more);
void DidWrite(const OperationHandle& handle,
void DidWrite(const OperationID id,
const WriteCallback& callback,
base::File::Error rv,
int64_t bytes,
bool complete);
void DidOpenFile(const OperationHandle& handle,
void DidOpenFile(const OperationID id,
const OpenFileCallback& callback,
base::File file,
base::OnceClosure on_close_callback);
void DidCreateSnapshot(
const OperationHandle& handle,
const OperationID id,
const SnapshotFileCallback& callback,
base::File::Error rv,
const base::File::Info& file_info,
const base::FilePath& platform_path,
scoped_refptr<storage::ShareableFileReference> file_ref);
void OnCopyProgress(const OperationHandle& handle,
void OnCopyProgress(const OperationID id,
const CopyProgressCallback& callback,
FileSystemOperation::CopyProgressType type,
const FileSystemURL& source_url,
......@@ -300,8 +288,7 @@ class STORAGE_EXPORT FileSystemOperationRunner
void PrepareForRead(OperationID id, const FileSystemURL& url);
// These must be called at the beginning and end of any async operations.
OperationHandle BeginOperation(std::unique_ptr<FileSystemOperation> operation,
base::WeakPtr<BeginOperationScoper> scope);
OperationID BeginOperation(std::unique_ptr<FileSystemOperation> operation);
// Cleans up the FileSystemOperation for |id|, which may result in the
// FileSystemContext, and |this| being deleted, by the time the call returns.
void FinishOperation(OperationID id);
......@@ -314,6 +301,12 @@ class STORAGE_EXPORT FileSystemOperationRunner
OperationID next_operation_id_ = 1;
Operations operations_;
// Used to detect synchronous invocation of completion callbacks by the
// back-end, to re-post them to be notified asynchronously. Note that some
// operations are recursive, so this may already be true when BeginOperation
// is called.
bool is_beginning_operation_ = false;
// We keep track of the file to be modified by each operation so that
// we can notify observers when we're done.
using OperationToURLSet = std::map<OperationID, FileSystemURLSet>;
......@@ -325,6 +318,9 @@ class STORAGE_EXPORT FileSystemOperationRunner
// Callbacks for stray cancels whose target operation is already finished.
std::map<OperationID, StatusCallback> stray_cancel_callbacks_;
base::WeakPtr<FileSystemOperationRunner> weak_ptr_;
base::WeakPtrFactory<FileSystemOperationRunner> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunner);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment