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.
4
5 #include "chrome/browser/sync/glue/browser_thread_model_worker.h"
6
7 #include "base/bind.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "content/public/browser/browser_thread.h"
10
11 using base::WaitableEvent;
12 using content::BrowserThread;
13
14 namespace browser_sync {
15
BrowserThreadModelWorker(BrowserThread::ID thread,syncer::ModelSafeGroup group,syncer::WorkerLoopDestructionObserver * observer)16 BrowserThreadModelWorker::BrowserThreadModelWorker(
17 BrowserThread::ID thread, syncer::ModelSafeGroup group,
18 syncer::WorkerLoopDestructionObserver* observer)
19 : ModelSafeWorker(observer),
20 thread_(thread), group_(group) {
21 }
22
DoWorkAndWaitUntilDoneImpl(const syncer::WorkCallback & work)23 syncer::SyncerError BrowserThreadModelWorker::DoWorkAndWaitUntilDoneImpl(
24 const syncer::WorkCallback& work) {
25 syncer::SyncerError error = syncer::UNSET;
26 if (BrowserThread::CurrentlyOn(thread_)) {
27 DLOG(WARNING) << "Already on thread " << thread_;
28 return work.Run();
29 }
30
31 if (!BrowserThread::PostTask(
32 thread_,
33 FROM_HERE,
34 base::Bind(&BrowserThreadModelWorker::CallDoWorkAndSignalTask,
35 this, work,
36 work_done_or_stopped(), &error))) {
37 DLOG(WARNING) << "Failed to post task to thread " << thread_;
38 error = syncer::CANNOT_DO_WORK;
39 return error;
40 }
41 work_done_or_stopped()->Wait();
42 return error;
43 }
44
GetModelSafeGroup()45 syncer::ModelSafeGroup BrowserThreadModelWorker::GetModelSafeGroup() {
46 return group_;
47 }
48
~BrowserThreadModelWorker()49 BrowserThreadModelWorker::~BrowserThreadModelWorker() {}
50
RegisterForLoopDestruction()51 void BrowserThreadModelWorker::RegisterForLoopDestruction() {
52 if (BrowserThread::CurrentlyOn(thread_)) {
53 base::MessageLoop::current()->AddDestructionObserver(this);
54 SetWorkingLoopToCurrent();
55 } else {
56 BrowserThread::PostTask(
57 thread_, FROM_HERE,
58 Bind(&BrowserThreadModelWorker::RegisterForLoopDestruction, this));
59 }
60 }
61
CallDoWorkAndSignalTask(const syncer::WorkCallback & work,WaitableEvent * done,syncer::SyncerError * error)62 void BrowserThreadModelWorker::CallDoWorkAndSignalTask(
63 const syncer::WorkCallback& work,
64 WaitableEvent* done,
65 syncer::SyncerError* error) {
66 DCHECK(BrowserThread::CurrentlyOn(thread_));
67 if (!IsStopped())
68 *error = work.Run();
69 done->Signal();
70 }
71
DatabaseModelWorker(syncer::WorkerLoopDestructionObserver * observer)72 DatabaseModelWorker::DatabaseModelWorker(
73 syncer::WorkerLoopDestructionObserver* observer)
74 : BrowserThreadModelWorker(BrowserThread::DB, syncer::GROUP_DB, observer) {
75 }
76
CallDoWorkAndSignalTask(const syncer::WorkCallback & work,WaitableEvent * done,syncer::SyncerError * error)77 void DatabaseModelWorker::CallDoWorkAndSignalTask(
78 const syncer::WorkCallback& work,
79 WaitableEvent* done,
80 syncer::SyncerError* error) {
81 BrowserThreadModelWorker::CallDoWorkAndSignalTask(work, done, error);
82 }
83
~DatabaseModelWorker()84 DatabaseModelWorker::~DatabaseModelWorker() {}
85
FileModelWorker(syncer::WorkerLoopDestructionObserver * observer)86 FileModelWorker::FileModelWorker(
87 syncer::WorkerLoopDestructionObserver* observer)
88 : BrowserThreadModelWorker(BrowserThread::FILE, syncer::GROUP_FILE,
89 observer) {
90 }
91
CallDoWorkAndSignalTask(const syncer::WorkCallback & work,WaitableEvent * done,syncer::SyncerError * error)92 void FileModelWorker::CallDoWorkAndSignalTask(
93 const syncer::WorkCallback& work,
94 WaitableEvent* done,
95 syncer::SyncerError* error) {
96 BrowserThreadModelWorker::CallDoWorkAndSignalTask(work, done, error);
97 }
98
~FileModelWorker()99 FileModelWorker::~FileModelWorker() {}
100
101 } // namespace browser_sync
102