| Index: components/sync/engine/browser_thread_model_worker.cc
|
| diff --git a/components/sync/engine/browser_thread_model_worker.cc b/components/sync/engine/browser_thread_model_worker.cc
|
| index a6d92c54d56cd14e69c57e83083991bed7815162..3b29d8505a09387f3950b52bc29fc0ca81b87f1c 100644
|
| --- a/components/sync/engine/browser_thread_model_worker.cc
|
| +++ b/components/sync/engine/browser_thread_model_worker.cc
|
| @@ -4,22 +4,45 @@
|
|
|
| #include "components/sync/engine/browser_thread_model_worker.h"
|
|
|
| -#include <utility>
|
| +#include "base/bind.h"
|
| +#include "base/callback.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| +
|
| +using base::SingleThreadTaskRunner;
|
|
|
| namespace syncer {
|
|
|
| BrowserThreadModelWorker::BrowserThreadModelWorker(
|
| - const scoped_refptr<base::SingleThreadTaskRunner>& runner,
|
| + const scoped_refptr<SingleThreadTaskRunner>& runner,
|
| ModelSafeGroup group)
|
| : runner_(runner), group_(group) {}
|
|
|
| -void BrowserThreadModelWorker::ScheduleWork(base::OnceClosure work) {
|
| +SyncerError BrowserThreadModelWorker::DoWorkAndWaitUntilDoneImpl(
|
| + const WorkCallback& work) {
|
| + SyncerError error = UNSET;
|
| if (runner_->BelongsToCurrentThread()) {
|
| DLOG(WARNING) << "Already on thread " << runner_;
|
| - std::move(work).Run();
|
| - } else {
|
| - runner_->PostTask(FROM_HERE, std::move(work));
|
| + return work.Run();
|
| }
|
| +
|
| + // Signaled when the task is deleted, i.e. after it runs or when it is
|
| + // abandoned.
|
| + base::WaitableEvent work_done_or_abandoned(
|
| + base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
| + base::WaitableEvent::InitialState::NOT_SIGNALED);
|
| +
|
| + if (!runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &BrowserThreadModelWorker::CallDoWorkAndSignalTask, this, work,
|
| + base::Passed(syncer::ScopedEventSignal(&work_done_or_abandoned)),
|
| + &error))) {
|
| + DLOG(WARNING) << "Failed to post task to runner " << runner_;
|
| + error = CANNOT_DO_WORK;
|
| + return error;
|
| + }
|
| + work_done_or_abandoned.Wait();
|
| + return error;
|
| }
|
|
|
| ModelSafeGroup BrowserThreadModelWorker::GetModelSafeGroup() {
|
| @@ -32,4 +55,14 @@
|
|
|
| BrowserThreadModelWorker::~BrowserThreadModelWorker() {}
|
|
|
| +void BrowserThreadModelWorker::CallDoWorkAndSignalTask(
|
| + const WorkCallback& work,
|
| + syncer::ScopedEventSignal scoped_event_signal,
|
| + SyncerError* error) {
|
| + DCHECK(runner_->BelongsToCurrentThread());
|
| + if (!IsStopped())
|
| + *error = work.Run();
|
| + // The event in |scoped_event_signal| is signaled at the end of this scope.
|
| +}
|
| +
|
| } // namespace syncer
|
|
|