15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/history_model_worker.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::WaitableEvent; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WorkerTask : public history::HistoryDBTask { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkerTask( 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::WorkCallback& work, 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* done, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncerError* error) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : work_(work), done_(done), error_(error) {} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RunOnDBThread(history::HistoryBackend* backend, 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) history::HistoryDatabase* db) OVERRIDE { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *error_ = work_.Run(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_->Signal(); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Since the DoWorkAndWaitUntilDone() is synchronous, we don't need to run 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // any code asynchronously on the main thread after completion. 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void DoneRunOnMainThread() OVERRIDE {} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~WorkerTask() {} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::WorkCallback work_; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* done_; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncerError* error_; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class AddDBThreadObserverTask : public history::HistoryDBTask { 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) explicit AddDBThreadObserverTask(base::Closure register_callback) 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : register_callback_(register_callback) {} 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual bool RunOnDBThread(history::HistoryBackend* backend, 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) history::HistoryDatabase* db) OVERRIDE { 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) register_callback_.Run(); 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void DoneRunOnMainThread() OVERRIDE {} 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~AddDBThreadObserverTask() {} 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Closure register_callback_; 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Post the work task on |history_service|'s DB thread from the UI 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PostWorkerTask(const base::WeakPtr<HistoryService>& history_service, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::WorkCallback& work, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelableRequestConsumerT<int, 0>* cancelable_consumer, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* done, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncerError* error) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (history_service.get()) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WorkerTask> task(new WorkerTask(work, done, error)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_service->ScheduleDBTask(task.get(), cancelable_consumer); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *error = syncer::CANNOT_DO_WORK; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done->Signal(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryModelWorker::HistoryModelWorker( 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::WeakPtr<HistoryService>& history_service, 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) syncer::WorkerLoopDestructionObserver* observer) 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : syncer::ModelSafeWorker(observer), 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) history_service_(history_service) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(history_service.get()); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void HistoryModelWorker::RegisterForLoopDestruction() { 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(history_service_.get()); 94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) history_service_->ScheduleDBTask( 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new AddDBThreadObserverTask( 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&HistoryModelWorker::RegisterOnDBThread, this)), 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &cancelable_consumer_); 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void HistoryModelWorker::RegisterOnDBThread() { 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::MessageLoop::current()->AddDestructionObserver(this); 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SetWorkingLoopToCurrent(); 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)syncer::SyncerError HistoryModelWorker::DoWorkAndWaitUntilDoneImpl( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::WorkCallback& work) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncerError error = syncer::UNSET; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&PostWorkerTask, history_service_, 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) work, &cancelable_consumer_, 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) work_done_or_stopped(), 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &error))) { 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) work_done_or_stopped()->Wait(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = syncer::CANNOT_DO_WORK; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::ModelSafeGroup HistoryModelWorker::GetModelSafeGroup() { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::GROUP_HISTORY; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryModelWorker::~HistoryModelWorker() {} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace browser_sync 127