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

Side by Side Diff: components/sync/engine/model_safe_worker.cc

Issue 2820623002: Revert of [Sync] Refactor ModelSafeWorker::DoWorkAndWaitUntilDone() to avoid code duplication. (Closed)
Patch Set: 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 (c) 2012 The Chromium Authors. All rights reserved. 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 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/sync/engine/model_safe_worker.h" 5 #include "components/sync/engine/model_safe_worker.h"
6 6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/json/json_writer.h" 7 #include "base/json/json_writer.h"
11 #include "base/values.h" 8 #include "base/values.h"
12 9
13 namespace syncer { 10 namespace syncer {
14 11
15 std::unique_ptr<base::DictionaryValue> ModelSafeRoutingInfoToValue( 12 std::unique_ptr<base::DictionaryValue> ModelSafeRoutingInfoToValue(
16 const ModelSafeRoutingInfo& routing_info) { 13 const ModelSafeRoutingInfo& routing_info) {
17 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 14 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
18 for (ModelSafeRoutingInfo::const_iterator it = routing_info.begin(); 15 for (ModelSafeRoutingInfo::const_iterator it = routing_info.begin();
19 it != routing_info.end(); ++it) { 16 it != routing_info.end(); ++it) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 case GROUP_PASSWORD: 62 case GROUP_PASSWORD:
66 return "GROUP_PASSWORD"; 63 return "GROUP_PASSWORD";
67 case GROUP_NON_BLOCKING: 64 case GROUP_NON_BLOCKING:
68 return "GROUP_NON_BLOCKING"; 65 return "GROUP_NON_BLOCKING";
69 default: 66 default:
70 NOTREACHED(); 67 NOTREACHED();
71 return "INVALID"; 68 return "INVALID";
72 } 69 }
73 } 70 }
74 71
75 ModelSafeWorker::ModelSafeWorker() 72 ModelSafeWorker::ModelSafeWorker() {}
76 : work_done_or_abandoned_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
77 base::WaitableEvent::InitialState::NOT_SIGNALED) {
78 }
79 ModelSafeWorker::~ModelSafeWorker() {} 73 ModelSafeWorker::~ModelSafeWorker() {}
80 74
81 void ModelSafeWorker::RequestStop() { 75 void ModelSafeWorker::RequestStop() {
82 base::AutoLock auto_lock(lock_); 76 // Set stop flag. This prevents any *further* tasks from being posted to
83 77 // worker threads (see DoWorkAndWaitUntilDone below), but note that one may
84 // Set stop flag to prevent any *further* WorkCallback from starting to run 78 // already be posted.
85 // (note that one may alreay be running). 79 stopped_.Set();
86 stopped_ = true;
87
88 // If no work is running, unblock DoWorkAndWaitUntilDone(). If work is
89 // running, it is unsafe to return from DoWorkAndWaitUntilDone().
90 // ScopedSignalWorkDoneOrAbandoned will take care of signaling the event when
91 // the work is done.
92 if (!is_work_running_)
93 work_done_or_abandoned_.Signal();
94 } 80 }
95 81
96 SyncerError ModelSafeWorker::DoWorkAndWaitUntilDone(WorkCallback work) { 82 SyncerError ModelSafeWorker::DoWorkAndWaitUntilDone(const WorkCallback& work) {
97 { 83 if (stopped_.IsSet())
98 // It is important to check |stopped_| and reset |work_done_or_abandoned_| 84 return CANNOT_DO_WORK;
99 // atomically to prevent this race: 85 return DoWorkAndWaitUntilDoneImpl(work);
100 //
101 // Thread Action
102 // Sync Sees that |stopped_| is false.
103 // UI Calls RequestStop(). Signals |work_done_or_abandoned_|.
104 // Sync Resets |work_done_or_abandoned_|.
105 // Waits on |work_done_or_abandoned_| forever since the task may not
106 // run after RequestStop() is called.
107 base::AutoLock auto_lock(lock_);
108 if (stopped_)
109 return CANNOT_DO_WORK;
110 DCHECK(!is_work_running_);
111 work_done_or_abandoned_.Reset();
112 }
113
114 SyncerError error = UNSET;
115 bool did_run = false;
116 ScheduleWork(base::BindOnce(
117 &ModelSafeWorker::DoWork, this, base::Passed(std::move(work)),
118 base::Passed(base::ScopedClosureRunner(base::Bind(
119 [](scoped_refptr<ModelSafeWorker> worker) {
120 worker->work_done_or_abandoned_.Signal();
121 },
122 make_scoped_refptr(this)))),
123 base::Unretained(&error), base::Unretained(&did_run)));
124
125 // Unblocked when the task runs or is deleted or when RequestStop() is called
126 // before the task starts running.
127 work_done_or_abandoned_.Wait();
128
129 return did_run ? error : CANNOT_DO_WORK;
130 } 86 }
131 87
132 void ModelSafeWorker::DoWork(WorkCallback work, 88 bool ModelSafeWorker::IsStopped() {
133 base::ScopedClosureRunner scoped_closure_runner, 89 return stopped_.IsSet();
134 SyncerError* error,
135 bool* did_run) {
136 {
137 base::AutoLock auto_lock(lock_);
138 if (stopped_)
139 return;
140
141 // Set |is_work_running_| to make sure that DoWorkAndWaitUntilDone() doesn't
142 // return while |work| is running.
143 DCHECK(!is_work_running_);
144 is_work_running_ = true;
145 }
146
147 *error = std::move(work).Run();
148 *did_run = true;
149
150 {
151 base::AutoLock auto_lock(lock_);
152 DCHECK(is_work_running_);
153 is_work_running_ = false;
154 }
155 } 90 }
156 91
157 } // namespace syncer 92 } // namespace syncer
OLDNEW
« no previous file with comments | « components/sync/engine/model_safe_worker.h ('k') | components/sync/engine/model_safe_worker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698