1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/sync_driver/glue/ui_model_worker.h"
8 #include "base/bind_helpers.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
12 #include "base/threading/thread_restrictions.h"
14 namespace browser_sync
{
18 // A simple callback to signal a waitable event after running a closure.
19 void CallDoWorkAndSignalCallback(const syncer::WorkCallback
& work
,
20 base::WaitableEvent
* work_done
,
21 syncer::SyncerError
* error_info
) {
23 // This can happen during tests or cases where there are more than just the
24 // default UIModelWorker in existence and it gets destroyed before
25 // the main UI loop has terminated. There is no easy way to assert the
26 // loop is running / not running at the moment, so we just provide cancel
27 // semantics here and short-circuit.
28 // TODO(timsteele): Maybe we should have the message loop destruction
29 // observer fire when the loop has ended, just a bit before it
30 // actually gets destroyed.
34 *error_info
= work
.Run();
36 work_done
->Signal(); // Unblock the syncer thread that scheduled us.
41 UIModelWorker::UIModelWorker(
42 const scoped_refptr
<base::SingleThreadTaskRunner
>& ui_thread
,
43 syncer::WorkerLoopDestructionObserver
* observer
)
44 : syncer::ModelSafeWorker(observer
), ui_thread_(ui_thread
) {}
46 void UIModelWorker::RegisterForLoopDestruction() {
47 CHECK(ui_thread_
->BelongsToCurrentThread());
48 SetWorkingLoopToCurrent();
51 syncer::SyncerError
UIModelWorker::DoWorkAndWaitUntilDoneImpl(
52 const syncer::WorkCallback
& work
) {
53 syncer::SyncerError error_info
;
54 if (ui_thread_
->BelongsToCurrentThread()) {
55 DLOG(WARNING
) << "DoWorkAndWaitUntilDone called from "
56 << "ui_loop_. Probably a nested invocation?";
60 if (!ui_thread_
->PostTask(FROM_HERE
,
61 base::Bind(&CallDoWorkAndSignalCallback
, work
,
62 work_done_or_stopped(), &error_info
))) {
63 DLOG(WARNING
) << "Could not post work to UI loop.";
64 error_info
= syncer::CANNOT_DO_WORK
;
67 work_done_or_stopped()->Wait();
72 syncer::ModelSafeGroup
UIModelWorker::GetModelSafeGroup() {
73 return syncer::GROUP_UI
;
76 UIModelWorker::~UIModelWorker() {}
78 } // namespace browser_sync