| Index: base/files/important_file_writer.cc
|
| diff --git a/base/files/important_file_writer.cc b/base/files/important_file_writer.cc
|
| index 9cbbd736e5baa5b53c2577909ffad724f30e89d4..de42c0ec0034fb6d6a4974f73314aaea7bd7fd41 100644
|
| --- a/base/files/important_file_writer.cc
|
| +++ b/base/files/important_file_writer.cc
|
| @@ -23,6 +23,7 @@
|
| #include "base/metrics/histogram.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/task_runner.h"
|
| +#include "base/task_runner_util.h"
|
| #include "base/threading/thread.h"
|
| #include "base/time/time.h"
|
|
|
| @@ -93,13 +94,13 @@ bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
|
| return true;
|
| }
|
|
|
| -ImportantFileWriter::ImportantFileWriter(
|
| - const FilePath& path, base::SequencedTaskRunner* task_runner)
|
| - : path_(path),
|
| - task_runner_(task_runner),
|
| - serializer_(NULL),
|
| - commit_interval_(TimeDelta::FromMilliseconds(
|
| - kDefaultCommitIntervalMs)) {
|
| +ImportantFileWriter::ImportantFileWriter(const FilePath& path,
|
| + base::SequencedTaskRunner* task_runner)
|
| + : path_(path),
|
| + task_runner_(task_runner),
|
| + serializer_(NULL),
|
| + commit_interval_(TimeDelta::FromMilliseconds(kDefaultCommitIntervalMs)),
|
| + weak_factory_(this) {
|
| DCHECK(CalledOnValidThread());
|
| DCHECK(task_runner_.get());
|
| }
|
| @@ -126,11 +127,7 @@ void ImportantFileWriter::WriteNow(const std::string& data) {
|
| if (HasPendingWrite())
|
| timer_.Stop();
|
|
|
| - if (!task_runner_->PostTask(
|
| - FROM_HERE,
|
| - MakeCriticalClosure(
|
| - Bind(IgnoreResult(&ImportantFileWriter::WriteFileAtomically),
|
| - path_, data)))) {
|
| + if (!PostWriteTask(data)) {
|
| // Posting the task to background message loop is not expected
|
| // to fail, but if it does, avoid losing data and just hit the disk
|
| // on the current thread.
|
| @@ -164,4 +161,40 @@ void ImportantFileWriter::DoScheduledWrite() {
|
| serializer_ = NULL;
|
| }
|
|
|
| +void ImportantFileWriter::RegisterOnNextSuccessfulWriteCallback(
|
| + const base::Closure& on_next_successful_write) {
|
| + DCHECK(on_next_successful_write_.is_null());
|
| + on_next_successful_write_ = on_next_successful_write;
|
| +}
|
| +
|
| +bool ImportantFileWriter::PostWriteTask(const std::string& data) {
|
| + // TODO(gab): This code could always use PostTaskAndReplyWithResult and let
|
| + // ForwardSuccessfulWrite() no-op if |on_next_successful_write_| is null, but
|
| + // PostTaskAndReply causes memory leaks in tests (crbug.com/371974) and
|
| + // suppressing all of those is unrealistic hence we avoid most of them by
|
| + // using PostTask() in the typical scenario below.
|
| + if (!on_next_successful_write_.is_null()) {
|
| + return base::PostTaskAndReplyWithResult(
|
| + task_runner_,
|
| + FROM_HERE,
|
| + MakeCriticalClosure(
|
| + Bind(&ImportantFileWriter::WriteFileAtomically, path_, data)),
|
| + Bind(&ImportantFileWriter::ForwardSuccessfulWrite,
|
| + weak_factory_.GetWeakPtr()));
|
| + }
|
| + return task_runner_->PostTask(
|
| + FROM_HERE,
|
| + MakeCriticalClosure(
|
| + Bind(IgnoreResult(&ImportantFileWriter::WriteFileAtomically),
|
| + path_, data)));
|
| +}
|
| +
|
| +void ImportantFileWriter::ForwardSuccessfulWrite(bool result) {
|
| + DCHECK(CalledOnValidThread());
|
| + if (result && !on_next_successful_write_.is_null()) {
|
| + on_next_successful_write_.Run();
|
| + on_next_successful_write_.Reset();
|
| + }
|
| +}
|
| +
|
| } // namespace base
|
|
|