OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h" | 5 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/sequenced_task_runner.h" | 10 #include "base/sequenced_task_runner.h" |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 token->clear_callback(); | 144 token->clear_callback(); |
145 callback.Run(status); | 145 callback.Run(status); |
146 return; | 146 return; |
147 } | 147 } |
148 | 148 |
149 if (manager) | 149 if (manager) |
150 manager->NotifyTaskDoneBody(token.Pass(), status); | 150 manager->NotifyTaskDoneBody(token.Pass(), status); |
151 } | 151 } |
152 | 152 |
153 // static | 153 // static |
154 void SyncTaskManager::UpdateBlockingFactor( | 154 void SyncTaskManager::UpdateTaskBlocker( |
155 scoped_ptr<SyncTaskToken> current_task_token, | 155 scoped_ptr<SyncTaskToken> current_task_token, |
156 scoped_ptr<BlockingFactor> blocking_factor, | 156 scoped_ptr<TaskBlocker> task_blocker, |
157 const Continuation& continuation) { | 157 const Continuation& continuation) { |
158 DCHECK(current_task_token); | 158 DCHECK(current_task_token); |
159 | 159 |
160 SyncTaskManager* manager = current_task_token->manager(); | 160 SyncTaskManager* manager = current_task_token->manager(); |
161 if (current_task_token->token_id() == SyncTaskToken::kTestingTaskTokenID) { | 161 if (current_task_token->token_id() == SyncTaskToken::kTestingTaskTokenID) { |
162 DCHECK(!manager); | 162 DCHECK(!manager); |
163 continuation.Run(current_task_token.Pass()); | 163 continuation.Run(current_task_token.Pass()); |
164 return; | 164 return; |
165 } | 165 } |
166 | 166 |
167 if (!manager) | 167 if (!manager) |
168 return; | 168 return; |
169 | 169 |
170 scoped_ptr<SyncTaskToken> foreground_task_token; | 170 scoped_ptr<SyncTaskToken> foreground_task_token; |
171 scoped_ptr<SyncTaskToken> background_task_token; | 171 scoped_ptr<SyncTaskToken> background_task_token; |
172 scoped_ptr<TaskLogger::TaskLog> task_log = current_task_token->PassTaskLog(); | 172 scoped_ptr<TaskLogger::TaskLog> task_log = current_task_token->PassTaskLog(); |
173 if (current_task_token->token_id() == SyncTaskToken::kForegroundTaskTokenID) | 173 if (current_task_token->token_id() == SyncTaskToken::kForegroundTaskTokenID) |
174 foreground_task_token = current_task_token.Pass(); | 174 foreground_task_token = current_task_token.Pass(); |
175 else | 175 else |
176 background_task_token = current_task_token.Pass(); | 176 background_task_token = current_task_token.Pass(); |
177 | 177 |
178 manager->UpdateBlockingFactorBody(foreground_task_token.Pass(), | 178 manager->UpdateTaskBlockerBody(foreground_task_token.Pass(), |
179 background_task_token.Pass(), | 179 background_task_token.Pass(), |
peria
2014/09/08 08:44:47
nit: fix indent
tzik
2014/09/08 08:58:33
Done.
| |
180 task_log.Pass(), | 180 task_log.Pass(), |
181 blocking_factor.Pass(), | 181 task_blocker.Pass(), |
182 continuation); | 182 continuation); |
183 } | 183 } |
184 | 184 |
185 bool SyncTaskManager::IsRunningTask(int64 token_id) const { | 185 bool SyncTaskManager::IsRunningTask(int64 token_id) const { |
186 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 186 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
187 | 187 |
188 // If the client is gone, all task should be aborted. | 188 // If the client is gone, all task should be aborted. |
189 if (!client_) | 189 if (!client_) |
190 return false; | 190 return false; |
191 | 191 |
192 if (token_id == SyncTaskToken::kForegroundTaskTokenID) | 192 if (token_id == SyncTaskToken::kForegroundTaskTokenID) |
193 return true; | 193 return true; |
194 | 194 |
195 return ContainsKey(running_background_tasks_, token_id); | 195 return ContainsKey(running_background_tasks_, token_id); |
196 } | 196 } |
197 | 197 |
198 void SyncTaskManager::DetachFromSequence() { | 198 void SyncTaskManager::DetachFromSequence() { |
199 sequence_checker_.DetachFromSequence(); | 199 sequence_checker_.DetachFromSequence(); |
200 } | 200 } |
201 | 201 |
202 void SyncTaskManager::NotifyTaskDoneBody(scoped_ptr<SyncTaskToken> token, | 202 void SyncTaskManager::NotifyTaskDoneBody(scoped_ptr<SyncTaskToken> token, |
203 SyncStatusCode status) { | 203 SyncStatusCode status) { |
204 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 204 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
205 DCHECK(token); | 205 DCHECK(token); |
206 | 206 |
207 DVLOG(3) << "NotifyTaskDone: " << "finished with status=" << status | 207 DVLOG(3) << "NotifyTaskDone: " << "finished with status=" << status |
208 << " (" << SyncStatusCodeToString(status) << ")" | 208 << " (" << SyncStatusCodeToString(status) << ")" |
209 << " " << token->location().ToString(); | 209 << " " << token->location().ToString(); |
210 | 210 |
211 if (token->blocking_factor()) { | 211 if (token->task_blocker()) { |
212 dependency_manager_.Erase(token->blocking_factor()); | 212 dependency_manager_.Erase(token->task_blocker()); |
213 token->clear_blocking_factor(); | 213 token->clear_task_blocker(); |
214 } | 214 } |
215 | 215 |
216 if (client_) { | 216 if (client_) { |
217 if (token->has_task_log()) { | 217 if (token->has_task_log()) { |
218 token->FinalizeTaskLog(SyncStatusCodeToString(status)); | 218 token->FinalizeTaskLog(SyncStatusCodeToString(status)); |
219 client_->RecordTaskLog(token->PassTaskLog()); | 219 client_->RecordTaskLog(token->PassTaskLog()); |
220 } | 220 } |
221 } | 221 } |
222 | 222 |
223 scoped_ptr<SyncTask> task; | 223 scoped_ptr<SyncTask> task; |
(...skipping 20 matching lines...) Expand all Loading... | |
244 callback.Run(status); | 244 callback.Run(status); |
245 | 245 |
246 // Post MaybeStartNextForegroundTask rather than calling it directly to avoid | 246 // Post MaybeStartNextForegroundTask rather than calling it directly to avoid |
247 // making the call-chaing longer. | 247 // making the call-chaing longer. |
248 task_runner_->PostTask( | 248 task_runner_->PostTask( |
249 FROM_HERE, | 249 FROM_HERE, |
250 base::Bind(&SyncTaskManager::MaybeStartNextForegroundTask, | 250 base::Bind(&SyncTaskManager::MaybeStartNextForegroundTask, |
251 AsWeakPtr(), base::Passed(&token))); | 251 AsWeakPtr(), base::Passed(&token))); |
252 } | 252 } |
253 | 253 |
254 void SyncTaskManager::UpdateBlockingFactorBody( | 254 void SyncTaskManager::UpdateTaskBlockerBody( |
255 scoped_ptr<SyncTaskToken> foreground_task_token, | 255 scoped_ptr<SyncTaskToken> foreground_task_token, |
256 scoped_ptr<SyncTaskToken> background_task_token, | 256 scoped_ptr<SyncTaskToken> background_task_token, |
257 scoped_ptr<TaskLogger::TaskLog> task_log, | 257 scoped_ptr<TaskLogger::TaskLog> task_log, |
258 scoped_ptr<BlockingFactor> blocking_factor, | 258 scoped_ptr<TaskBlocker> task_blocker, |
259 const Continuation& continuation) { | 259 const Continuation& continuation) { |
260 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 260 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
261 | 261 |
262 // Run the task directly if the parallelization is disabled. | 262 // Run the task directly if the parallelization is disabled. |
263 if (!maximum_background_task_) { | 263 if (!maximum_background_task_) { |
264 DCHECK(foreground_task_token); | 264 DCHECK(foreground_task_token); |
265 DCHECK(!background_task_token); | 265 DCHECK(!background_task_token); |
266 foreground_task_token->SetTaskLog(task_log.Pass()); | 266 foreground_task_token->SetTaskLog(task_log.Pass()); |
267 continuation.Run(foreground_task_token.Pass()); | 267 continuation.Run(foreground_task_token.Pass()); |
268 return; | 268 return; |
269 } | 269 } |
270 | 270 |
271 // Clear existing |blocking_factor| from |dependency_manager_| before | 271 // Clear existing |task_blocker| from |dependency_manager_| before |
272 // getting |foreground_task_token|, so that we can avoid dead lock. | 272 // getting |foreground_task_token|, so that we can avoid dead lock. |
273 if (background_task_token && background_task_token->blocking_factor()) { | 273 if (background_task_token && background_task_token->task_blocker()) { |
274 dependency_manager_.Erase(background_task_token->blocking_factor()); | 274 dependency_manager_.Erase(background_task_token->task_blocker()); |
275 background_task_token->clear_blocking_factor(); | 275 background_task_token->clear_task_blocker(); |
276 } | 276 } |
277 | 277 |
278 // Try to get |foreground_task_token|. If it's not available, wait for | 278 // Try to get |foreground_task_token|. If it's not available, wait for |
279 // current foreground task to finish. | 279 // current foreground task to finish. |
280 if (!foreground_task_token) { | 280 if (!foreground_task_token) { |
281 DCHECK(background_task_token); | 281 DCHECK(background_task_token); |
282 foreground_task_token = GetToken(background_task_token->location(), | 282 foreground_task_token = GetToken(background_task_token->location(), |
283 SyncStatusCallback()); | 283 SyncStatusCallback()); |
284 if (!foreground_task_token) { | 284 if (!foreground_task_token) { |
285 PushPendingTask( | 285 PushPendingTask( |
286 base::Bind(&SyncTaskManager::UpdateBlockingFactorBody, | 286 base::Bind(&SyncTaskManager::UpdateTaskBlockerBody, |
287 AsWeakPtr(), | 287 AsWeakPtr(), |
288 base::Passed(&foreground_task_token), | 288 base::Passed(&foreground_task_token), |
289 base::Passed(&background_task_token), | 289 base::Passed(&background_task_token), |
290 base::Passed(&task_log), | 290 base::Passed(&task_log), |
291 base::Passed(&blocking_factor), | 291 base::Passed(&task_blocker), |
292 continuation), | 292 continuation), |
293 PRIORITY_HIGH); | 293 PRIORITY_HIGH); |
294 MaybeStartNextForegroundTask(scoped_ptr<SyncTaskToken>()); | 294 MaybeStartNextForegroundTask(scoped_ptr<SyncTaskToken>()); |
295 return; | 295 return; |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 // Check if the task can run as a background task now. | 299 // Check if the task can run as a background task now. |
300 // If there are too many task running or any other task blocks current | 300 // If there are too many task running or any other task blocks current |
301 // task, wait for any other task to finish. | 301 // task, wait for any other task to finish. |
302 bool task_number_limit_exceeded = | 302 bool task_number_limit_exceeded = |
303 !background_task_token && | 303 !background_task_token && |
304 running_background_tasks_.size() >= maximum_background_task_; | 304 running_background_tasks_.size() >= maximum_background_task_; |
305 if (task_number_limit_exceeded || | 305 if (task_number_limit_exceeded || |
306 !dependency_manager_.Insert(blocking_factor.get())) { | 306 !dependency_manager_.Insert(task_blocker.get())) { |
307 DCHECK(!running_background_tasks_.empty()); | 307 DCHECK(!running_background_tasks_.empty()); |
308 DCHECK(pending_backgrounding_task_.is_null()); | 308 DCHECK(pending_backgrounding_task_.is_null()); |
309 | 309 |
310 // Wait for NotifyTaskDone to release a |blocking_factor|. | 310 // Wait for NotifyTaskDone to release a |task_blocker|. |
311 pending_backgrounding_task_ = | 311 pending_backgrounding_task_ = |
312 base::Bind(&SyncTaskManager::UpdateBlockingFactorBody, | 312 base::Bind(&SyncTaskManager::UpdateTaskBlockerBody, |
313 AsWeakPtr(), | 313 AsWeakPtr(), |
314 base::Passed(&foreground_task_token), | 314 base::Passed(&foreground_task_token), |
315 base::Passed(&background_task_token), | 315 base::Passed(&background_task_token), |
316 base::Passed(&task_log), | 316 base::Passed(&task_log), |
317 base::Passed(&blocking_factor), | 317 base::Passed(&task_blocker), |
318 continuation); | 318 continuation); |
319 return; | 319 return; |
320 } | 320 } |
321 | 321 |
322 if (background_task_token) { | 322 if (background_task_token) { |
323 background_task_token->set_blocking_factor(blocking_factor.Pass()); | 323 background_task_token->set_task_blocker(task_blocker.Pass()); |
324 } else { | 324 } else { |
325 tracked_objects::Location from_here = foreground_task_token->location(); | 325 tracked_objects::Location from_here = foreground_task_token->location(); |
326 SyncStatusCallback callback = foreground_task_token->callback(); | 326 SyncStatusCallback callback = foreground_task_token->callback(); |
327 foreground_task_token->clear_callback(); | 327 foreground_task_token->clear_callback(); |
328 | 328 |
329 background_task_token = | 329 background_task_token = |
330 SyncTaskToken::CreateForBackgroundTask(AsWeakPtr(), | 330 SyncTaskToken::CreateForBackgroundTask(AsWeakPtr(), |
331 task_runner_.get(), | 331 task_runner_.get(), |
332 task_token_seq_++, | 332 task_token_seq_++, |
333 blocking_factor.Pass()); | 333 task_blocker.Pass()); |
334 background_task_token->UpdateTask(from_here, callback); | 334 background_task_token->UpdateTask(from_here, callback); |
335 running_background_tasks_.set(background_task_token->token_id(), | 335 running_background_tasks_.set(background_task_token->token_id(), |
336 running_foreground_task_.Pass()); | 336 running_foreground_task_.Pass()); |
337 } | 337 } |
338 | 338 |
339 token_ = foreground_task_token.Pass(); | 339 token_ = foreground_task_token.Pass(); |
340 MaybeStartNextForegroundTask(scoped_ptr<SyncTaskToken>()); | 340 MaybeStartNextForegroundTask(scoped_ptr<SyncTaskToken>()); |
341 background_task_token->SetTaskLog(task_log.Pass()); | 341 background_task_token->SetTaskLog(task_log.Pass()); |
342 continuation.Run(background_task_token.Pass()); | 342 continuation.Run(background_task_token.Pass()); |
343 } | 343 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
394 closure.Run(); | 394 closure.Run(); |
395 return; | 395 return; |
396 } | 396 } |
397 | 397 |
398 if (client_) | 398 if (client_) |
399 client_->MaybeScheduleNextTask(); | 399 client_->MaybeScheduleNextTask(); |
400 } | 400 } |
401 | 401 |
402 } // namespace drive_backend | 402 } // namespace drive_backend |
403 } // namespace sync_file_system | 403 } // namespace sync_file_system |
OLD | NEW |