OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/message_loop/message_loop.h" | 5 #include "base/message_loop/message_loop.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 68 |
69 MessageLoop::TaskObserver::TaskObserver() { | 69 MessageLoop::TaskObserver::TaskObserver() { |
70 } | 70 } |
71 | 71 |
72 MessageLoop::TaskObserver::~TaskObserver() { | 72 MessageLoop::TaskObserver::~TaskObserver() { |
73 } | 73 } |
74 | 74 |
75 MessageLoop::DestructionObserver::~DestructionObserver() { | 75 MessageLoop::DestructionObserver::~DestructionObserver() { |
76 } | 76 } |
77 | 77 |
78 MessageLoop::NestingObserver::~NestingObserver() {} | |
79 | |
80 //------------------------------------------------------------------------------ | 78 //------------------------------------------------------------------------------ |
81 | 79 |
82 MessageLoop::MessageLoop(Type type) | 80 MessageLoop::MessageLoop(Type type) |
83 : MessageLoop(type, MessagePumpFactoryCallback()) { | 81 : MessageLoop(type, MessagePumpFactoryCallback()) { |
84 BindToCurrentThread(); | 82 BindToCurrentThread(); |
85 } | 83 } |
86 | 84 |
87 MessageLoop::MessageLoop(std::unique_ptr<MessagePump> pump) | 85 MessageLoop::MessageLoop(std::unique_ptr<MessagePump> pump) |
88 : MessageLoop(TYPE_CUSTOM, Bind(&ReturnPump, Passed(&pump))) { | 86 : MessageLoop(TYPE_CUSTOM, Bind(&ReturnPump, Passed(&pump))) { |
89 BindToCurrentThread(); | 87 BindToCurrentThread(); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 DCHECK_EQ(this, current()); | 205 DCHECK_EQ(this, current()); |
208 destruction_observers_.AddObserver(destruction_observer); | 206 destruction_observers_.AddObserver(destruction_observer); |
209 } | 207 } |
210 | 208 |
211 void MessageLoop::RemoveDestructionObserver( | 209 void MessageLoop::RemoveDestructionObserver( |
212 DestructionObserver* destruction_observer) { | 210 DestructionObserver* destruction_observer) { |
213 DCHECK_EQ(this, current()); | 211 DCHECK_EQ(this, current()); |
214 destruction_observers_.RemoveObserver(destruction_observer); | 212 destruction_observers_.RemoveObserver(destruction_observer); |
215 } | 213 } |
216 | 214 |
217 void MessageLoop::AddNestingObserver(NestingObserver* observer) { | |
218 DCHECK_EQ(this, current()); | |
219 CHECK(allow_nesting_); | |
220 nesting_observers_.AddObserver(observer); | |
221 } | |
222 | |
223 void MessageLoop::RemoveNestingObserver(NestingObserver* observer) { | |
224 DCHECK_EQ(this, current()); | |
225 CHECK(allow_nesting_); | |
226 nesting_observers_.RemoveObserver(observer); | |
227 } | |
228 | |
229 void MessageLoop::QuitWhenIdle() { | 215 void MessageLoop::QuitWhenIdle() { |
230 DCHECK_EQ(this, current()); | 216 DCHECK_EQ(this, current()); |
231 if (run_loop_) { | 217 if (run_loop_) { |
232 run_loop_->QuitWhenIdle(); | 218 run_loop_->QuitWhenIdle(); |
233 } else { | 219 } else { |
234 NOTREACHED() << "Must be inside Run to call QuitWhenIdle"; | 220 NOTREACHED() << "Must be inside Run to call QuitWhenIdle"; |
235 } | 221 } |
236 } | 222 } |
237 | 223 |
238 void MessageLoop::QuitNow() { | 224 void MessageLoop::QuitNow() { |
(...skipping 13 matching lines...) Expand all Loading... |
252 MessageLoop::current()->QuitWhenIdle(); | 238 MessageLoop::current()->QuitWhenIdle(); |
253 } | 239 } |
254 | 240 |
255 // static | 241 // static |
256 Closure MessageLoop::QuitWhenIdleClosure() { | 242 Closure MessageLoop::QuitWhenIdleClosure() { |
257 return Bind(&QuitCurrentWhenIdle); | 243 return Bind(&QuitCurrentWhenIdle); |
258 } | 244 } |
259 | 245 |
260 void MessageLoop::SetNestableTasksAllowed(bool allowed) { | 246 void MessageLoop::SetNestableTasksAllowed(bool allowed) { |
261 if (allowed) { | 247 if (allowed) { |
262 CHECK(allow_nesting_); | 248 CHECK(base::RunLoop::IsNestingAllowedOnCurrentThread()); |
263 | 249 |
264 // Kick the native pump just in case we enter a OS-driven nested message | 250 // Kick the native pump just in case we enter a OS-driven nested message |
265 // loop. | 251 // loop. |
266 pump_->ScheduleWork(); | 252 pump_->ScheduleWork(); |
267 } | 253 } |
268 nestable_tasks_allowed_ = allowed; | 254 nestable_tasks_allowed_ = allowed; |
269 } | 255 } |
270 | 256 |
271 bool MessageLoop::NestableTasksAllowed() const { | 257 bool MessageLoop::NestableTasksAllowed() const { |
272 return nestable_tasks_allowed_; | 258 return nestable_tasks_allowed_; |
273 } | 259 } |
274 | 260 |
275 bool MessageLoop::IsNested() { | 261 // TODO(gab): Migrate TaskObservers to RunLoop as part of separating concerns |
276 return run_loop_->run_depth_ > 1; | 262 // between MessageLoop and RunLoop and making MessageLoop a swappable |
277 } | 263 // implementation detail. http://crbug.com/703346 |
278 | |
279 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { | 264 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { |
280 DCHECK_EQ(this, current()); | 265 DCHECK_EQ(this, current()); |
281 CHECK(allow_task_observers_); | 266 CHECK(allow_task_observers_); |
282 task_observers_.AddObserver(task_observer); | 267 task_observers_.AddObserver(task_observer); |
283 } | 268 } |
284 | 269 |
285 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { | 270 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { |
286 DCHECK_EQ(this, current()); | 271 DCHECK_EQ(this, current()); |
287 CHECK(allow_task_observers_); | 272 CHECK(allow_task_observers_); |
288 task_observers_.RemoveObserver(task_observer); | 273 task_observers_.RemoveObserver(task_observer); |
289 } | 274 } |
290 | 275 |
291 bool MessageLoop::is_running() const { | |
292 DCHECK_EQ(this, current()); | |
293 return run_loop_ != NULL; | |
294 } | |
295 | |
296 bool MessageLoop::HasHighResolutionTasks() { | 276 bool MessageLoop::HasHighResolutionTasks() { |
297 return incoming_task_queue_->HasHighResolutionTasks(); | 277 return incoming_task_queue_->HasHighResolutionTasks(); |
298 } | 278 } |
299 | 279 |
300 bool MessageLoop::IsIdleForTesting() { | 280 bool MessageLoop::IsIdleForTesting() { |
301 // We only check the incoming queue, since we don't want to lock the work | 281 // We only check the incoming queue, since we don't want to lock the work |
302 // queue. | 282 // queue. |
303 return incoming_task_queue_->IsIdleForTesting(); | 283 return incoming_task_queue_->IsIdleForTesting(); |
304 } | 284 } |
305 | 285 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 DCHECK_EQ(this, current()); | 356 DCHECK_EQ(this, current()); |
377 // Clear the previous thread task runner first, because only one can exist at | 357 // Clear the previous thread task runner first, because only one can exist at |
378 // a time. | 358 // a time. |
379 thread_task_runner_handle_.reset(); | 359 thread_task_runner_handle_.reset(); |
380 thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_)); | 360 thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_)); |
381 } | 361 } |
382 | 362 |
383 void MessageLoop::RunHandler() { | 363 void MessageLoop::RunHandler() { |
384 DCHECK_EQ(this, current()); | 364 DCHECK_EQ(this, current()); |
385 DCHECK(run_loop_); | 365 DCHECK(run_loop_); |
386 CHECK(allow_nesting_ || run_loop_->run_depth_ == 1); | |
387 pump_->Run(this); | 366 pump_->Run(this); |
388 } | 367 } |
389 | 368 |
390 bool MessageLoop::ProcessNextDelayedNonNestableTask() { | 369 bool MessageLoop::ProcessNextDelayedNonNestableTask() { |
391 if (run_loop_->run_depth_ != 1) | 370 if (is_nested_) |
392 return false; | 371 return false; |
393 | 372 |
394 if (deferred_non_nestable_work_queue_.empty()) | 373 if (deferred_non_nestable_work_queue_.empty()) |
395 return false; | 374 return false; |
396 | 375 |
397 PendingTask pending_task = | 376 PendingTask pending_task = |
398 std::move(deferred_non_nestable_work_queue_.front()); | 377 std::move(deferred_non_nestable_work_queue_.front()); |
399 deferred_non_nestable_work_queue_.pop(); | 378 deferred_non_nestable_work_queue_.pop(); |
400 | 379 |
401 RunTask(&pending_task); | 380 RunTask(&pending_task); |
(...skipping 21 matching lines...) Expand all Loading... |
423 task_annotator_.RunTask("MessageLoop::PostTask", pending_task); | 402 task_annotator_.RunTask("MessageLoop::PostTask", pending_task); |
424 for (auto& observer : task_observers_) | 403 for (auto& observer : task_observers_) |
425 observer.DidProcessTask(*pending_task); | 404 observer.DidProcessTask(*pending_task); |
426 | 405 |
427 nestable_tasks_allowed_ = true; | 406 nestable_tasks_allowed_ = true; |
428 | 407 |
429 current_pending_task_ = nullptr; | 408 current_pending_task_ = nullptr; |
430 } | 409 } |
431 | 410 |
432 bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { | 411 bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { |
433 if (pending_task.nestable || run_loop_->run_depth_ == 1) { | 412 if (pending_task.nestable || !is_nested_) { |
434 RunTask(&pending_task); | 413 RunTask(&pending_task); |
435 // Show that we ran a task (Note: a new one might arrive as a | 414 // Show that we ran a task (Note: a new one might arrive as a |
436 // consequence!). | 415 // consequence!). |
437 return true; | 416 return true; |
438 } | 417 } |
439 | 418 |
440 // We couldn't run the task now because we're in a nested message loop | 419 // We couldn't run the task now because we're in a nested message loop |
441 // and the task isn't nestable. | 420 // and the task isn't nestable. |
442 deferred_non_nestable_work_queue_.push(std::move(pending_task)); | 421 deferred_non_nestable_work_queue_.push(std::move(pending_task)); |
443 return false; | 422 return false; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 #else | 468 #else |
490 incoming_task_queue_->ReloadWorkQueue(&work_queue_); | 469 incoming_task_queue_->ReloadWorkQueue(&work_queue_); |
491 #endif | 470 #endif |
492 } | 471 } |
493 } | 472 } |
494 | 473 |
495 void MessageLoop::ScheduleWork() { | 474 void MessageLoop::ScheduleWork() { |
496 pump_->ScheduleWork(); | 475 pump_->ScheduleWork(); |
497 } | 476 } |
498 | 477 |
499 void MessageLoop::NotifyBeginNestedLoop() { | |
500 for (auto& observer : nesting_observers_) | |
501 observer.OnBeginNestedMessageLoop(); | |
502 } | |
503 | |
504 bool MessageLoop::DoWork() { | 478 bool MessageLoop::DoWork() { |
505 if (!nestable_tasks_allowed_) { | 479 if (!nestable_tasks_allowed_) { |
506 // Task can't be executed right now. | 480 // Task can't be executed right now. |
507 return false; | 481 return false; |
508 } | 482 } |
509 | 483 |
510 for (;;) { | 484 for (;;) { |
511 ReloadWorkQueue(); | 485 ReloadWorkQueue(); |
512 if (work_queue_.empty()) | 486 if (work_queue_.empty()) |
513 break; | 487 break; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 persistent, | 640 persistent, |
667 mode, | 641 mode, |
668 controller, | 642 controller, |
669 delegate); | 643 delegate); |
670 } | 644 } |
671 #endif | 645 #endif |
672 | 646 |
673 #endif // !defined(OS_NACL_SFI) | 647 #endif // !defined(OS_NACL_SFI) |
674 | 648 |
675 } // namespace base | 649 } // namespace base |
OLD | NEW |