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

Side by Side Diff: sync/internal_api/public/engine/model_safe_worker.cc

Issue 2083713002: Remove calls to MessageLoop::current() in sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: self-review Created 4 years, 6 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 "sync/internal_api/public/engine/model_safe_worker.h" 5 #include "sync/internal_api/public/engine/model_safe_worker.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
11 #include "base/threading/thread_task_runner_handle.h"
11 #include "base/values.h" 12 #include "base/values.h"
12 13
13 namespace syncer { 14 namespace syncer {
14 15
15 std::unique_ptr<base::DictionaryValue> ModelSafeRoutingInfoToValue( 16 std::unique_ptr<base::DictionaryValue> ModelSafeRoutingInfoToValue(
16 const ModelSafeRoutingInfo& routing_info) { 17 const ModelSafeRoutingInfo& routing_info) {
17 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 18 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
18 for (ModelSafeRoutingInfo::const_iterator it = routing_info.begin(); 19 for (ModelSafeRoutingInfo::const_iterator it = routing_info.begin();
19 it != routing_info.end(); ++it) { 20 it != routing_info.end(); ++it) {
20 dict->SetString(ModelTypeToString(it->first), 21 dict->SetString(ModelTypeToString(it->first),
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 default: 70 default:
70 NOTREACHED(); 71 NOTREACHED();
71 return "INVALID"; 72 return "INVALID";
72 } 73 }
73 } 74 }
74 75
75 ModelSafeWorker::ModelSafeWorker(WorkerLoopDestructionObserver* observer) 76 ModelSafeWorker::ModelSafeWorker(WorkerLoopDestructionObserver* observer)
76 : stopped_(false), 77 : stopped_(false),
77 work_done_or_stopped_(base::WaitableEvent::ResetPolicy::AUTOMATIC, 78 work_done_or_stopped_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
78 base::WaitableEvent::InitialState::NOT_SIGNALED), 79 base::WaitableEvent::InitialState::NOT_SIGNALED),
79 observer_(observer), 80 observer_(observer) {}
80 working_loop_(NULL) {}
81 81
82 ModelSafeWorker::~ModelSafeWorker() {} 82 ModelSafeWorker::~ModelSafeWorker() {}
83 83
84 void ModelSafeWorker::RequestStop() { 84 void ModelSafeWorker::RequestStop() {
85 base::AutoLock al(stopped_lock_); 85 base::AutoLock al(stopped_lock_);
86 86
87 // Set stop flag but don't signal work_done_or_stopped_ to unblock sync loop 87 // Set stop flag but don't signal work_done_or_stopped_ to unblock sync loop
88 // because the worker may be working and depending on sync command object 88 // because the worker may be working and depending on sync command object
89 // living on sync thread. This prevents any *further* tasks from being posted 89 // living on sync thread. This prevents any *further* tasks from being posted
90 // to worker threads (see DoWorkAndWaitUntilDone below), but note that one 90 // to worker threads (see DoWorkAndWaitUntilDone below), but note that one
(...skipping 27 matching lines...) Expand all
118 // finish. At this point, all pending tasks posted to the loop have been 118 // finish. At this point, all pending tasks posted to the loop have been
119 // destroyed (see MessageLoop::~MessageLoop). So syncer will be blocked 119 // destroyed (see MessageLoop::~MessageLoop). So syncer will be blocked
120 // indefinitely without signaling here. 120 // indefinitely without signaling here.
121 work_done_or_stopped_.Signal(); 121 work_done_or_stopped_.Signal();
122 122
123 DVLOG(1) << ModelSafeGroupToString(GetModelSafeGroup()) 123 DVLOG(1) << ModelSafeGroupToString(GetModelSafeGroup())
124 << " worker stops on destruction of its working thread."; 124 << " worker stops on destruction of its working thread.";
125 } 125 }
126 126
127 { 127 {
128 base::AutoLock l(working_loop_lock_); 128 base::AutoLock l(working_task_runner_lock_);
129 working_loop_ = NULL; 129 working_task_runner_ = NULL;
130 } 130 }
131 131
132 if (observer_) 132 if (observer_)
133 observer_->OnWorkerLoopDestroyed(GetModelSafeGroup()); 133 observer_->OnWorkerLoopDestroyed(GetModelSafeGroup());
134 } 134 }
135 135
136 void ModelSafeWorker::SetWorkingLoopToCurrent() { 136 void ModelSafeWorker::SetWorkingLoopToCurrent() {
137 base::Callback<void(ModelSafeGroup)> unregister_done_callback; 137 base::Callback<void(ModelSafeGroup)> unregister_done_callback;
138 138
139 { 139 {
140 base::AutoLock l(working_loop_lock_); 140 base::AutoLock l(working_task_runner_lock_);
141 DCHECK(!working_loop_); 141 DCHECK(!working_task_runner_);
142 142
143 if (unregister_done_callback_.is_null()) { 143 if (unregister_done_callback_.is_null()) {
144 // Expected case - UnregisterForLoopDestruction hasn't been called yet. 144 // Expected case - UnregisterForLoopDestruction hasn't been called yet.
145 base::MessageLoop::current()->AddDestructionObserver(this); 145 base::MessageLoop::current()->AddDestructionObserver(this);
146 working_loop_ = base::MessageLoop::current(); 146 working_task_runner_ = base::ThreadTaskRunnerHandle::Get();
147 } else { 147 } else {
148 // Rare case which is possible when the model type thread remains 148 // Rare case which is possible when the model type thread remains
149 // blocked for the entire session and UnregisterForLoopDestruction ends 149 // blocked for the entire session and UnregisterForLoopDestruction ends
150 // up being called before this method. This method is posted unlike 150 // up being called before this method. This method is posted unlike
151 // UnregisterForLoopDestruction - that's why they can end up being called 151 // UnregisterForLoopDestruction - that's why they can end up being called
152 // out of order. 152 // out of order.
153 // In this case we skip the destruction observer registration 153 // In this case we skip the destruction observer registration
154 // and just invoke the callback stored at UnregisterForLoopDestruction. 154 // and just invoke the callback stored at UnregisterForLoopDestruction.
155 DCHECK(stopped_); 155 DCHECK(stopped_);
156 unregister_done_callback = unregister_done_callback_; 156 unregister_done_callback = unregister_done_callback_;
157 unregister_done_callback_.Reset(); 157 unregister_done_callback_.Reset();
158 } 158 }
159 } 159 }
160 160
161 if (!unregister_done_callback.is_null()) { 161 if (!unregister_done_callback.is_null()) {
162 unregister_done_callback.Run(GetModelSafeGroup()); 162 unregister_done_callback.Run(GetModelSafeGroup());
163 } 163 }
164 } 164 }
165 165
166 void ModelSafeWorker::UnregisterForLoopDestruction( 166 void ModelSafeWorker::UnregisterForLoopDestruction(
167 base::Callback<void(ModelSafeGroup)> unregister_done_callback) { 167 base::Callback<void(ModelSafeGroup)> unregister_done_callback) {
168 base::AutoLock l(working_loop_lock_); 168 base::AutoLock l(working_task_runner_lock_);
169 if (working_loop_ != NULL) { 169 if (working_task_runner_) {
170 // Normal case - observer registration has been already done. 170 // Normal case - observer registration has been already done.
171 // Delegate to the sync thread to do the actual unregistration in 171 // Delegate to the sync thread to do the actual unregistration in
172 // UnregisterForLoopDestructionAsync. 172 // UnregisterForLoopDestructionAsync.
173 DCHECK_NE(base::MessageLoop::current(), working_loop_); 173 DCHECK(!working_task_runner_->BelongsToCurrentThread());
174 working_loop_->PostTask( 174 working_task_runner_->PostTask(
175 FROM_HERE, 175 FROM_HERE,
176 base::Bind(&ModelSafeWorker::UnregisterForLoopDestructionAsync, 176 base::Bind(&ModelSafeWorker::UnregisterForLoopDestructionAsync, this,
177 this,
178 unregister_done_callback)); 177 unregister_done_callback));
179 } else { 178 } else {
180 // The working loop is still unknown, probably because the model type 179 // The working loop is still unknown, probably because the model type
181 // thread is blocked. Store the callback to be called from 180 // thread is blocked. Store the callback to be called from
182 // SetWorkingLoopToCurrent. 181 // SetWorkingLoopToCurrent.
183 unregister_done_callback_ = unregister_done_callback; 182 unregister_done_callback_ = unregister_done_callback;
184 } 183 }
185 } 184 }
186 185
187 void ModelSafeWorker::UnregisterForLoopDestructionAsync( 186 void ModelSafeWorker::UnregisterForLoopDestructionAsync(
188 base::Callback<void(ModelSafeGroup)> unregister_done_callback) { 187 base::Callback<void(ModelSafeGroup)> unregister_done_callback) {
189 { 188 {
190 base::AutoLock l(working_loop_lock_); 189 base::AutoLock l(working_task_runner_lock_);
191 if (!working_loop_) 190 if (!working_task_runner_)
192 return; 191 return;
193 DCHECK_EQ(base::MessageLoop::current(), working_loop_); 192 DCHECK(working_task_runner_->BelongsToCurrentThread());
194 } 193 }
195 194
196 DCHECK(stopped_); 195 DCHECK(stopped_);
197 base::MessageLoop::current()->RemoveDestructionObserver(this); 196 base::MessageLoop::current()->RemoveDestructionObserver(this);
198 unregister_done_callback.Run(GetModelSafeGroup()); 197 unregister_done_callback.Run(GetModelSafeGroup());
199 } 198 }
200 199
201 } // namespace syncer 200 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/internal_api/public/engine/model_safe_worker.h ('k') | sync/internal_api/public/http_bridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698