Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(812)

Side by Side Diff: components/history/core/browser/history_model_worker.cc

Issue 2782573002: [Sync] Refactor ModelSafeWorker::DoWorkAndWaitUntilDone() to avoid code duplication. (Closed)
Patch Set: self-review Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/history/core/browser/history_model_worker.h" 5 #include "components/history/core/browser/history_model_worker.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/synchronization/waitable_event.h" 9 #include "base/memory/ptr_util.h"
10 #include "components/history/core/browser/history_db_task.h" 10 #include "components/history/core/browser/history_db_task.h"
11 #include "components/history/core/browser/history_service.h" 11 #include "components/history/core/browser/history_service.h"
12 #include "components/sync/base/scoped_event_signal.h"
13 12
14 namespace browser_sync { 13 namespace browser_sync {
15 14
16 class WorkerTask : public history::HistoryDBTask { 15 class WorkerTask : public history::HistoryDBTask {
17 public: 16 public:
18 WorkerTask(const syncer::WorkCallback& work, 17 WorkerTask(base::OnceClosure work) : work_(std::move(work)) {}
19 syncer::ScopedEventSignal scoped_event_signal,
20 syncer::SyncerError* error)
21 : work_(work),
22 scoped_event_signal_(std::move(scoped_event_signal)),
23 error_(error) {}
24 18
25 bool RunOnDBThread(history::HistoryBackend* backend, 19 bool RunOnDBThread(history::HistoryBackend* backend,
26 history::HistoryDatabase* db) override { 20 history::HistoryDatabase* db) override {
27 // Signal the completion event at the end of this scope. 21 std::move(work_).Run();
28 auto scoped_event_signal = std::move(scoped_event_signal_);
29
30 // Run the task.
31 *error_ = work_.Run();
32
33 return true; 22 return true;
34 } 23 }
35 24
36 // Since the DoWorkAndWaitUntilDone() is synchronous, we don't need to run 25 // Since the DoWorkAndWaitUntilDone() is synchronous, we don't need to run
37 // any code asynchronously on the main thread after completion. 26 // any code asynchronously on the main thread after completion.
38 void DoneRunOnMainThread() override {} 27 void DoneRunOnMainThread() override {}
39 28
40 protected: 29 private:
41 ~WorkerTask() override { 30 // A OnceClosure is deleted right after it runs. This is important to unblock
42 // The event in |scoped_event_signal_| is signaled at the end of this 31 // DoWorkAndWaitUntilDone() right after the task runs.
43 // scope if this is destroyed before RunOnDBThread runs. 32 base::OnceClosure work_;
44 }
45 33
46 syncer::WorkCallback work_; 34 DISALLOW_COPY_AND_ASSIGN(WorkerTask);
47 syncer::ScopedEventSignal scoped_event_signal_;
48 syncer::SyncerError* error_;
49 };
50
51 class AddDBThreadObserverTask : public history::HistoryDBTask {
52 public:
53 explicit AddDBThreadObserverTask(base::Closure register_callback)
54 : register_callback_(register_callback) {}
55
56 bool RunOnDBThread(history::HistoryBackend* backend,
57 history::HistoryDatabase* db) override {
58 register_callback_.Run();
59 return true;
60 }
61
62 void DoneRunOnMainThread() override {}
63
64 private:
65 ~AddDBThreadObserverTask() override {}
66
67 base::Closure register_callback_;
68 }; 35 };
69 36
70 namespace { 37 namespace {
71 38
72 // Post the work task on |history_service|'s DB thread from the UI 39 // Post the work task on |history_service|'s DB thread from the UI
73 // thread. 40 // thread.
74 void PostWorkerTask( 41 void PostWorkerTask(
75 const base::WeakPtr<history::HistoryService>& history_service, 42 const base::WeakPtr<history::HistoryService>& history_service,
76 const syncer::WorkCallback& work, 43 base::OnceClosure work,
77 syncer::ScopedEventSignal scoped_event_signal, 44 base::CancelableTaskTracker* cancelable_tracker) {
78 base::CancelableTaskTracker* cancelable_tracker,
79 syncer::SyncerError* error) {
80 if (history_service.get()) { 45 if (history_service.get()) {
81 std::unique_ptr<history::HistoryDBTask> task( 46 history_service->ScheduleDBTask(
82 new WorkerTask(work, std::move(scoped_event_signal), error)); 47 base::MakeUnique<WorkerTask>(std::move(work)), cancelable_tracker);
83 history_service->ScheduleDBTask(std::move(task), cancelable_tracker);
84 } else {
85 *error = syncer::CANNOT_DO_WORK;
86 // The event in |scoped_event_signal| is signaled at the end of this
87 // scope.
88 } 48 }
89 } 49 }
90 50
91 } // namespace 51 } // namespace
92 52
93 HistoryModelWorker::HistoryModelWorker( 53 HistoryModelWorker::HistoryModelWorker(
94 const base::WeakPtr<history::HistoryService>& history_service, 54 const base::WeakPtr<history::HistoryService>& history_service,
95 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread) 55 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread)
96 : history_service_(history_service), ui_thread_(ui_thread) { 56 : history_service_(history_service), ui_thread_(ui_thread) {
97 CHECK(history_service.get()); 57 CHECK(history_service.get());
98 DCHECK(ui_thread_->BelongsToCurrentThread()); 58 DCHECK(ui_thread_->BelongsToCurrentThread());
99 cancelable_tracker_.reset(new base::CancelableTaskTracker); 59 cancelable_tracker_.reset(new base::CancelableTaskTracker);
100 } 60 }
101 61
102 syncer::SyncerError HistoryModelWorker::DoWorkAndWaitUntilDoneImpl(
103 const syncer::WorkCallback& work) {
104 syncer::SyncerError error = syncer::UNSET;
105
106 // Signaled after the task runs or when it is abandoned.
107 base::WaitableEvent work_done_or_abandoned(
108 base::WaitableEvent::ResetPolicy::AUTOMATIC,
109 base::WaitableEvent::InitialState::NOT_SIGNALED);
110
111 if (ui_thread_->PostTask(FROM_HERE,
112 base::Bind(&PostWorkerTask, history_service_, work,
113 base::Passed(syncer::ScopedEventSignal(
114 &work_done_or_abandoned)),
115 cancelable_tracker_.get(), &error))) {
116 work_done_or_abandoned.Wait();
117 } else {
118 error = syncer::CANNOT_DO_WORK;
119 }
120 return error;
121 }
122
123 syncer::ModelSafeGroup HistoryModelWorker::GetModelSafeGroup() { 62 syncer::ModelSafeGroup HistoryModelWorker::GetModelSafeGroup() {
124 return syncer::GROUP_HISTORY; 63 return syncer::GROUP_HISTORY;
125 } 64 }
126 65
127 bool HistoryModelWorker::IsOnModelThread() { 66 bool HistoryModelWorker::IsOnModelThread() {
128 // Ideally HistoryService would expose a way to check whether this is the 67 // Ideally HistoryService would expose a way to check whether this is the
129 // history DB thread. Since it doesn't, just return true to bypass a CHECK in 68 // history DB thread. Since it doesn't, just return true to bypass a CHECK in
130 // the sync code. 69 // the sync code.
131 return true; 70 return true;
132 } 71 }
133 72
134 HistoryModelWorker::~HistoryModelWorker() { 73 HistoryModelWorker::~HistoryModelWorker() {
135 // The base::CancelableTaskTracker class is not thread-safe and must only be 74 // The base::CancelableTaskTracker class is not thread-safe and must only be
136 // used from a single thread but the current object may not be destroyed from 75 // used from a single thread but the current object may not be destroyed from
137 // the UI thread, so delete it from the UI thread. 76 // the UI thread, so delete it from the UI thread.
138 ui_thread_->DeleteSoon(FROM_HERE, cancelable_tracker_.release()); 77 ui_thread_->DeleteSoon(FROM_HERE, cancelable_tracker_.release());
139 } 78 }
140 79
80 void HistoryModelWorker::ScheduleWork(base::OnceClosure work) {
81 ui_thread_->PostTask(FROM_HERE, base::Bind(&PostWorkerTask, history_service_,
82 base::Passed(std::move(work)),
83 cancelable_tracker_.get()));
84 }
85
141 } // namespace browser_sync 86 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698