Home | History | Annotate | Download | only in glue
      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 
     16 BrowserThreadModelWorker::BrowserThreadModelWorker(
     17     BrowserThread::ID thread, syncer::ModelSafeGroup group,
     18     syncer::WorkerLoopDestructionObserver* observer)
     19     : ModelSafeWorker(observer),
     20       thread_(thread), group_(group) {
     21 }
     22 
     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 
     45 syncer::ModelSafeGroup BrowserThreadModelWorker::GetModelSafeGroup() {
     46   return group_;
     47 }
     48 
     49 BrowserThreadModelWorker::~BrowserThreadModelWorker() {}
     50 
     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 
     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 
     72 DatabaseModelWorker::DatabaseModelWorker(
     73     syncer::WorkerLoopDestructionObserver* observer)
     74     : BrowserThreadModelWorker(BrowserThread::DB, syncer::GROUP_DB, observer) {
     75 }
     76 
     77 void DatabaseModelWorker::CallDoWorkAndSignalTask(
     78     const syncer::WorkCallback& work,
     79     WaitableEvent* done,
     80     syncer::SyncerError* error) {
     81   BrowserThreadModelWorker::CallDoWorkAndSignalTask(work, done, error);
     82 }
     83 
     84 DatabaseModelWorker::~DatabaseModelWorker() {}
     85 
     86 FileModelWorker::FileModelWorker(
     87     syncer::WorkerLoopDestructionObserver* observer)
     88     : BrowserThreadModelWorker(BrowserThread::FILE, syncer::GROUP_FILE,
     89                                observer) {
     90 }
     91 
     92 void FileModelWorker::CallDoWorkAndSignalTask(
     93     const syncer::WorkCallback& work,
     94     WaitableEvent* done,
     95     syncer::SyncerError* error) {
     96   BrowserThreadModelWorker::CallDoWorkAndSignalTask(work, done, error);
     97 }
     98 
     99 FileModelWorker::~FileModelWorker() {}
    100 
    101 }  // namespace browser_sync
    102