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