Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync / glue / ui_model_worker.cc
blob2d8bc7d1435d9a875d34e0cf7bb27b9151df9407
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 "chrome/browser/sync/glue/ui_model_worker.h"
7 #include "base/bind.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"
13 #include "content/public/browser/browser_thread.h"
15 using content::BrowserThread;
17 namespace browser_sync {
19 namespace {
21 // A simple callback to signal a waitable event after running a closure.
22 void CallDoWorkAndSignalCallback(const syncer::WorkCallback& work,
23 base::WaitableEvent* work_done,
24 syncer::SyncerError* error_info) {
25 if (work.is_null()) {
26 // This can happen during tests or cases where there are more than just the
27 // default UIModelWorker in existence and it gets destroyed before
28 // the main UI loop has terminated. There is no easy way to assert the
29 // loop is running / not running at the moment, so we just provide cancel
30 // semantics here and short-circuit.
31 // TODO(timsteele): Maybe we should have the message loop destruction
32 // observer fire when the loop has ended, just a bit before it
33 // actually gets destroyed.
34 return;
37 *error_info = work.Run();
39 work_done->Signal(); // Unblock the syncer thread that scheduled us.
42 } // namespace
44 UIModelWorker::UIModelWorker(syncer::WorkerLoopDestructionObserver* observer)
45 : syncer::ModelSafeWorker(observer) {
48 void UIModelWorker::RegisterForLoopDestruction() {
49 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
50 base::MessageLoop::current()->AddDestructionObserver(this);
51 SetWorkingLoopToCurrent();
54 syncer::SyncerError UIModelWorker::DoWorkAndWaitUntilDoneImpl(
55 const syncer::WorkCallback& work) {
56 syncer::SyncerError error_info;
57 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
58 DLOG(WARNING) << "DoWorkAndWaitUntilDone called from "
59 << "ui_loop_. Probably a nested invocation?";
60 return work.Run();
63 if (!BrowserThread::PostTask(
64 BrowserThread::UI, FROM_HERE,
65 base::Bind(&CallDoWorkAndSignalCallback,
66 work, work_done_or_stopped(), &error_info))) {
67 DLOG(WARNING) << "Could not post work to UI loop.";
68 error_info = syncer::CANNOT_DO_WORK;
69 return error_info;
71 work_done_or_stopped()->Wait();
73 return error_info;
76 syncer::ModelSafeGroup UIModelWorker::GetModelSafeGroup() {
77 return syncer::GROUP_UI;
80 UIModelWorker::~UIModelWorker() {
83 } // namespace browser_sync