Commit f913656f authored by Austin Sullivan's avatar Austin Sullivan Committed by Commit Bot

Implement Cancel() for MemoryFileStreamWriter

In preparation of shared unit tests between the various FileStreamWriter
implementations.

Merge this before https://crrev.com/c/2422682

Change-Id: I56e4a3f5973a13a2bb39108114be5462296ff8e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2425429Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
Commit-Queue: Austin Sullivan <asully@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810731}
parent 80cd20f2
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
namespace storage { namespace storage {
namespace {
void NeverCalled(int unused) {
ADD_FAILURE();
}
} // namespace
class LocalFileStreamWriterTest : public testing::Test { class LocalFileStreamWriterTest : public testing::Test {
public: public:
LocalFileStreamWriterTest() : file_thread_("TestFileThread") {} LocalFileStreamWriterTest() : file_thread_("TestFileThread") {}
...@@ -75,10 +81,6 @@ class LocalFileStreamWriterTest : public testing::Test { ...@@ -75,10 +81,6 @@ class LocalFileStreamWriterTest : public testing::Test {
base::ScopedTempDir temp_dir_; base::ScopedTempDir temp_dir_;
}; };
void NeverCalled(int unused) {
ADD_FAILURE();
}
TEST_F(LocalFileStreamWriterTest, Write) { TEST_F(LocalFileStreamWriterTest, Write) {
base::FilePath path = CreateFileWithContent("file_a", std::string()); base::FilePath path = CreateFileWithContent("file_a", std::string());
std::unique_ptr<LocalFileStreamWriter> writer(CreateWriter(path, 0)); std::unique_ptr<LocalFileStreamWriter> writer(CreateWriter(path, 0));
......
...@@ -34,6 +34,7 @@ MemoryFileStreamWriter::MemoryFileStreamWriter( ...@@ -34,6 +34,7 @@ MemoryFileStreamWriter::MemoryFileStreamWriter(
file_path_(file_path), file_path_(file_path),
offset_(initial_offset) { offset_(initial_offset) {
DCHECK(memory_file_util_.MaybeValid()); DCHECK(memory_file_util_.MaybeValid());
has_pending_operation_ = false;
} }
MemoryFileStreamWriter::~MemoryFileStreamWriter() = default; MemoryFileStreamWriter::~MemoryFileStreamWriter() = default;
...@@ -41,6 +42,11 @@ MemoryFileStreamWriter::~MemoryFileStreamWriter() = default; ...@@ -41,6 +42,11 @@ MemoryFileStreamWriter::~MemoryFileStreamWriter() = default;
int MemoryFileStreamWriter::Write(net::IOBuffer* buf, int MemoryFileStreamWriter::Write(net::IOBuffer* buf,
int buf_len, int buf_len,
net::CompletionOnceCallback callback) { net::CompletionOnceCallback callback) {
DCHECK(!has_pending_operation_);
DCHECK(cancel_callback_.is_null());
has_pending_operation_ = true;
task_runner_->PostTaskAndReplyWithResult( task_runner_->PostTaskAndReplyWithResult(
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(
...@@ -66,17 +72,43 @@ int MemoryFileStreamWriter::Write(net::IOBuffer* buf, ...@@ -66,17 +72,43 @@ int MemoryFileStreamWriter::Write(net::IOBuffer* buf,
void MemoryFileStreamWriter::OnWriteCompleted( void MemoryFileStreamWriter::OnWriteCompleted(
net::CompletionOnceCallback callback, net::CompletionOnceCallback callback,
int result) { int result) {
DCHECK(has_pending_operation_);
if (CancelIfRequested())
return;
has_pending_operation_ = false;
if (result > 0) if (result > 0)
offset_ += result; offset_ += result;
std::move(callback).Run(result); std::move(callback).Run(result);
} }
int MemoryFileStreamWriter::Cancel(net::CompletionOnceCallback /*callback*/) { int MemoryFileStreamWriter::Cancel(net::CompletionOnceCallback callback) {
return net::ERR_UNEXPECTED; if (!has_pending_operation_)
return net::ERR_UNEXPECTED;
DCHECK(!callback.is_null());
cancel_callback_ = std::move(callback);
return net::ERR_IO_PENDING;
} }
int MemoryFileStreamWriter::Flush(net::CompletionOnceCallback /*callback*/) { int MemoryFileStreamWriter::Flush(net::CompletionOnceCallback /*callback*/) {
DCHECK(!has_pending_operation_);
DCHECK(cancel_callback_.is_null());
return net::OK; return net::OK;
} }
bool MemoryFileStreamWriter::CancelIfRequested() {
DCHECK(has_pending_operation_);
if (cancel_callback_.is_null())
return false;
has_pending_operation_ = false;
std::move(cancel_callback_).Run(net::OK);
return true;
}
} // namespace storage } // namespace storage
...@@ -37,14 +37,20 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamWriter ...@@ -37,14 +37,20 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamWriter
void OnWriteCompleted(net::CompletionOnceCallback callback, int result); void OnWriteCompleted(net::CompletionOnceCallback callback, int result);
// Stops the in-flight operation and calls |cancel_callback_| if it has been
// set by Cancel() for the current operation.
bool CancelIfRequested();
base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_; base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_;
const scoped_refptr<base::TaskRunner> task_runner_; const scoped_refptr<base::TaskRunner> task_runner_;
const base::FilePath file_path_; const base::FilePath file_path_;
int64_t offset_; int64_t offset_;
base::WeakPtrFactory<MemoryFileStreamWriter> weak_factory_{this}; bool has_pending_operation_;
net::CompletionOnceCallback cancel_callback_;
base::WeakPtrFactory<MemoryFileStreamWriter> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(MemoryFileStreamWriter); DISALLOW_COPY_AND_ASSIGN(MemoryFileStreamWriter);
}; };
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "net/base/io_buffer.h" #include "net/base/io_buffer.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "storage/browser/file_system/file_stream_test_utils.h" #include "storage/browser/file_system/file_stream_test_utils.h"
#include "storage/browser/file_system/file_stream_writer.h" #include "storage/browser/file_system/file_stream_writer.h"
#include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h" #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h"
...@@ -23,6 +24,12 @@ ...@@ -23,6 +24,12 @@
namespace storage { namespace storage {
namespace {
void NeverCalled(int unused) {
ADD_FAILURE();
}
} // namespace
class MemoryFileStreamWriterTest : public testing::Test { class MemoryFileStreamWriterTest : public testing::Test {
public: public:
MemoryFileStreamWriterTest() {} MemoryFileStreamWriterTest() {}
...@@ -159,6 +166,25 @@ TEST_F(MemoryFileStreamWriterTest, CancelAfterFinishedOperation) { ...@@ -159,6 +166,25 @@ TEST_F(MemoryFileStreamWriterTest, CancelAfterFinishedOperation) {
EXPECT_EQ("foo", GetFileContent(path)); EXPECT_EQ("foo", GetFileContent(path));
} }
TEST_F(MemoryFileStreamWriterTest, CancelWrite) {
base::FilePath path = Path("file_a");
bool created;
EXPECT_EQ(base::File::FILE_OK, file_util()->EnsureFileExists(path, &created));
std::unique_ptr<FileStreamWriter> writer(CreateWriter(path, 0));
scoped_refptr<net::StringIOBuffer> buffer(
base::MakeRefCounted<net::StringIOBuffer>("xxx"));
int result =
writer->Write(buffer.get(), buffer->size(), base::BindOnce(&NeverCalled));
ASSERT_EQ(net::ERR_IO_PENDING, result);
net::TestCompletionCallback callback;
writer->Cancel(callback.callback());
int cancel_result = callback.WaitForResult();
EXPECT_EQ(net::OK, cancel_result);
}
TEST_F(MemoryFileStreamWriterTest, FlushBeforeWriting) { TEST_F(MemoryFileStreamWriterTest, FlushBeforeWriting) {
base::FilePath path = Path("file_a"); base::FilePath path = Path("file_a");
bool created; bool created;
......
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