| OLD | NEW |
| 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 "base/message_loop.h" | 5 #include "base/message_loop.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 } | 296 } |
| 297 | 297 |
| 298 void MessageLoop::PostNonNestableDelayedTask( | 298 void MessageLoop::PostNonNestableDelayedTask( |
| 299 const tracked_objects::Location& from_here, | 299 const tracked_objects::Location& from_here, |
| 300 const base::Closure& task, | 300 const base::Closure& task, |
| 301 base::TimeDelta delay) { | 301 base::TimeDelta delay) { |
| 302 PostNonNestableDelayedTask(from_here, task, delay.InMillisecondsRoundedUp()); | 302 PostNonNestableDelayedTask(from_here, task, delay.InMillisecondsRoundedUp()); |
| 303 } | 303 } |
| 304 | 304 |
| 305 void MessageLoop::Run() { | 305 void MessageLoop::Run() { |
| 306 AutoRunState save_state(this); | 306 AutoRunState save_state(this, NULL); |
| 307 RunHandler(); |
| 308 } |
| 309 |
| 310 void MessageLoop::RunWithID(const RunID& run_id) { |
| 311 AutoRunState save_state(this, run_id); |
| 312 if (run_id->quit_now_received_) |
| 313 return; |
| 307 RunHandler(); | 314 RunHandler(); |
| 308 } | 315 } |
| 309 | 316 |
| 310 void MessageLoop::RunAllPending() { | 317 void MessageLoop::RunAllPending() { |
| 311 AutoRunState save_state(this); | 318 AutoRunState save_state(this, NULL); |
| 312 state_->quit_received = true; // Means run until we would otherwise block. | 319 state_->quit_received_ = true; // Means run until we would otherwise block. |
| 313 RunHandler(); | 320 RunHandler(); |
| 314 } | 321 } |
| 315 | 322 |
| 316 void MessageLoop::Quit() { | 323 void MessageLoop::QuitWhenIdle() { |
| 317 DCHECK_EQ(this, current()); | 324 DCHECK_EQ(this, current()); |
| 318 if (state_) { | 325 if (state_) { |
| 319 state_->quit_received = true; | 326 state_->quit_received_ = true; |
| 320 } else { | 327 } else { |
| 321 NOTREACHED() << "Must be inside Run to call Quit"; | 328 NOTREACHED() << "Must be inside Run to call Quit"; |
| 322 } | 329 } |
| 323 } | 330 } |
| 324 | 331 |
| 325 void MessageLoop::QuitNow() { | 332 void MessageLoop::QuitNow() { |
| 326 DCHECK_EQ(this, current()); | 333 DCHECK_EQ(this, current()); |
| 327 if (state_) { | 334 if (state_) { |
| 328 pump_->Quit(); | 335 pump_->Quit(); |
| 329 } else { | 336 } else { |
| 330 NOTREACHED() << "Must be inside Run to call Quit"; | 337 NOTREACHED() << "Must be inside Run to call Quit"; |
| 331 } | 338 } |
| 332 } | 339 } |
| 333 | 340 |
| 334 static void QuitCurrent() { | 341 void MessageLoop::QuitNowWithID(const RunID& run_id) { |
| 335 MessageLoop::current()->Quit(); | 342 DCHECK_EQ(this, current()); |
| 343 |
| 344 // Set quit_now_received_ so that the corresponding Run scope is quit as soon |
| 345 // as it is returned to. It's also possible that the corresponding Run has not |
| 346 // begun; in that case, this will cause the Run to immediately return. |
| 347 run_id->quit_now_received_ = true; |
| 348 |
| 349 if (!state_) |
| 350 return; |
| 351 |
| 352 // If the state_ pointer matches that of the RunIDObject, we're at the same |
| 353 // Run scope, so quit now. |
| 354 if (state_ == run_id->run_state_) |
| 355 QuitNow(); |
| 356 } |
| 357 |
| 358 static void QuitCurrentWhenIdle() { |
| 359 MessageLoop::current()->QuitWhenIdle(); |
| 360 } |
| 361 |
| 362 static void QuitCurrentNow() { |
| 363 MessageLoop::current()->QuitNow(); |
| 364 } |
| 365 |
| 366 static void QuitCurrentNowWithID(const MessageLoop::RunID& run_id) { |
| 367 MessageLoop::current()->QuitNowWithID(run_id); |
| 336 } | 368 } |
| 337 | 369 |
| 338 // static | 370 // static |
| 339 base::Closure MessageLoop::QuitClosure() { | 371 base::Closure MessageLoop::QuitWhenIdleClosure() { |
| 340 return base::Bind(&QuitCurrent); | 372 return base::Bind(&QuitCurrentWhenIdle); |
| 373 } |
| 374 |
| 375 // static |
| 376 base::Closure MessageLoop::QuitNowClosure() { |
| 377 return base::Bind(&QuitCurrentNow); |
| 378 } |
| 379 |
| 380 // static |
| 381 base::Closure MessageLoop::QuitNowWithIDClosure( |
| 382 const RunID& run_id) { |
| 383 return base::Bind(&QuitCurrentNowWithID, run_id); |
| 384 } |
| 385 |
| 386 MessageLoop::RunID MessageLoop::GetRunID() { |
| 387 return new RunIDObject(); |
| 341 } | 388 } |
| 342 | 389 |
| 343 void MessageLoop::SetNestableTasksAllowed(bool allowed) { | 390 void MessageLoop::SetNestableTasksAllowed(bool allowed) { |
| 344 if (nestable_tasks_allowed_ != allowed) { | 391 if (nestable_tasks_allowed_ != allowed) { |
| 345 nestable_tasks_allowed_ = allowed; | 392 nestable_tasks_allowed_ = allowed; |
| 346 if (!nestable_tasks_allowed_) | 393 if (!nestable_tasks_allowed_) |
| 347 return; | 394 return; |
| 348 // Start the native pump if we are not already pumping. | 395 // Start the native pump if we are not already pumping. |
| 349 pump_->ScheduleWork(); | 396 pump_->ScheduleWork(); |
| 350 } | 397 } |
| 351 } | 398 } |
| 352 | 399 |
| 353 bool MessageLoop::NestableTasksAllowed() const { | 400 bool MessageLoop::NestableTasksAllowed() const { |
| 354 return nestable_tasks_allowed_; | 401 return nestable_tasks_allowed_; |
| 355 } | 402 } |
| 356 | 403 |
| 357 bool MessageLoop::IsNested() { | 404 bool MessageLoop::IsNested() { |
| 358 return state_->run_depth > 1; | 405 return state_->run_depth_ > 1; |
| 359 } | 406 } |
| 360 | 407 |
| 361 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { | 408 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { |
| 362 DCHECK_EQ(this, current()); | 409 DCHECK_EQ(this, current()); |
| 363 task_observers_.AddObserver(task_observer); | 410 task_observers_.AddObserver(task_observer); |
| 364 } | 411 } |
| 365 | 412 |
| 366 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { | 413 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { |
| 367 DCHECK_EQ(this, current()); | 414 DCHECK_EQ(this, current()); |
| 368 task_observers_.RemoveObserver(task_observer); | 415 task_observers_.RemoveObserver(task_observer); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 return; | 454 return; |
| 408 } | 455 } |
| 409 #endif | 456 #endif |
| 410 | 457 |
| 411 void MessageLoop::RunInternal() { | 458 void MessageLoop::RunInternal() { |
| 412 DCHECK_EQ(this, current()); | 459 DCHECK_EQ(this, current()); |
| 413 | 460 |
| 414 StartHistogrammer(); | 461 StartHistogrammer(); |
| 415 | 462 |
| 416 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | 463 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 417 if (state_->dispatcher && type() == TYPE_UI) { | 464 if (state_->dispatcher_ && type() == TYPE_UI) { |
| 418 static_cast<base::MessagePumpForUI*>(pump_.get())-> | 465 static_cast<base::MessagePumpForUI*>(pump_.get())-> |
| 419 RunWithDispatcher(this, state_->dispatcher); | 466 RunWithDispatcher(this, state_->dispatcher_); |
| 420 return; | 467 return; |
| 421 } | 468 } |
| 422 #endif | 469 #endif |
| 423 | 470 |
| 424 pump_->Run(this); | 471 pump_->Run(this); |
| 425 } | 472 } |
| 426 | 473 |
| 427 bool MessageLoop::ProcessNextDelayedNonNestableTask() { | 474 bool MessageLoop::ProcessNextDelayedNonNestableTask() { |
| 428 if (state_->run_depth != 1) | 475 if (state_->run_depth_ != 1) |
| 429 return false; | 476 return false; |
| 430 | 477 |
| 431 if (deferred_non_nestable_work_queue_.empty()) | 478 if (deferred_non_nestable_work_queue_.empty()) |
| 432 return false; | 479 return false; |
| 433 | 480 |
| 434 PendingTask pending_task = deferred_non_nestable_work_queue_.front(); | 481 PendingTask pending_task = deferred_non_nestable_work_queue_.front(); |
| 435 deferred_non_nestable_work_queue_.pop(); | 482 deferred_non_nestable_work_queue_.pop(); |
| 436 | 483 |
| 437 RunTask(pending_task); | 484 RunTask(pending_task); |
| 438 return true; | 485 return true; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 466 FOR_EACH_OBSERVER(TaskObserver, task_observers_, | 513 FOR_EACH_OBSERVER(TaskObserver, task_observers_, |
| 467 DidProcessTask(pending_task.time_posted)); | 514 DidProcessTask(pending_task.time_posted)); |
| 468 | 515 |
| 469 tracked_objects::ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, | 516 tracked_objects::ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 470 start_time, tracked_objects::ThreadData::NowForEndOfRun()); | 517 start_time, tracked_objects::ThreadData::NowForEndOfRun()); |
| 471 | 518 |
| 472 nestable_tasks_allowed_ = true; | 519 nestable_tasks_allowed_ = true; |
| 473 } | 520 } |
| 474 | 521 |
| 475 bool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) { | 522 bool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) { |
| 476 if (pending_task.nestable || state_->run_depth == 1) { | 523 if (pending_task.nestable || state_->run_depth_ == 1) { |
| 477 RunTask(pending_task); | 524 RunTask(pending_task); |
| 478 // Show that we ran a task (Note: a new one might arrive as a | 525 // Show that we ran a task (Note: a new one might arrive as a |
| 479 // consequence!). | 526 // consequence!). |
| 480 return true; | 527 return true; |
| 481 } | 528 } |
| 482 | 529 |
| 483 // We couldn't run the task now because we're in a nested message loop | 530 // We couldn't run the task now because we're in a nested message loop |
| 484 // and the task isn't nestable. | 531 // and the task isn't nestable. |
| 485 deferred_non_nestable_work_queue_.push(pending_task); | 532 deferred_non_nestable_work_queue_.push(pending_task); |
| 486 return false; | 533 return false; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 if (!delayed_work_queue_.empty()) | 736 if (!delayed_work_queue_.empty()) |
| 690 *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; | 737 *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; |
| 691 | 738 |
| 692 return DeferOrRunPendingTask(pending_task); | 739 return DeferOrRunPendingTask(pending_task); |
| 693 } | 740 } |
| 694 | 741 |
| 695 bool MessageLoop::DoIdleWork() { | 742 bool MessageLoop::DoIdleWork() { |
| 696 if (ProcessNextDelayedNonNestableTask()) | 743 if (ProcessNextDelayedNonNestableTask()) |
| 697 return true; | 744 return true; |
| 698 | 745 |
| 699 if (state_->quit_received) | 746 if (state_->quit_received_) |
| 700 pump_->Quit(); | 747 pump_->Quit(); |
| 701 | 748 |
| 702 return false; | 749 return false; |
| 703 } | 750 } |
| 704 | 751 |
| 705 void MessageLoop::DeleteSoonInternal(const tracked_objects::Location& from_here, | 752 void MessageLoop::DeleteSoonInternal(const tracked_objects::Location& from_here, |
| 706 void(*deleter)(const void*), | 753 void(*deleter)(const void*), |
| 707 const void* object) { | 754 const void* object) { |
| 708 PostNonNestableTask(from_here, base::Bind(deleter, object)); | 755 PostNonNestableTask(from_here, base::Bind(deleter, object)); |
| 709 } | 756 } |
| 710 | 757 |
| 711 void MessageLoop::ReleaseSoonInternal( | 758 void MessageLoop::ReleaseSoonInternal( |
| 712 const tracked_objects::Location& from_here, | 759 const tracked_objects::Location& from_here, |
| 713 void(*releaser)(const void*), | 760 void(*releaser)(const void*), |
| 714 const void* object) { | 761 const void* object) { |
| 715 PostNonNestableTask(from_here, base::Bind(releaser, object)); | 762 PostNonNestableTask(from_here, base::Bind(releaser, object)); |
| 716 } | 763 } |
| 717 | 764 |
| 718 //------------------------------------------------------------------------------ | 765 //------------------------------------------------------------------------------ |
| 766 // MessageLoop::RunState |
| 767 |
| 768 MessageLoop::RunState::RunState() { |
| 769 } |
| 770 |
| 771 MessageLoop::RunState::~RunState() { |
| 772 } |
| 773 |
| 774 //------------------------------------------------------------------------------ |
| 719 // MessageLoop::AutoRunState | 775 // MessageLoop::AutoRunState |
| 720 | 776 |
| 721 MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) { | 777 MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop, const RunID& run_id) |
| 778 : loop_(loop) { |
| 722 // Make the loop reference us. | 779 // Make the loop reference us. |
| 723 previous_state_ = loop_->state_; | 780 previous_state_ = loop_->state_; |
| 724 if (previous_state_) { | 781 if (previous_state_) { |
| 725 run_depth = previous_state_->run_depth + 1; | 782 run_depth_ = previous_state_->run_depth_ + 1; |
| 726 } else { | 783 } else { |
| 727 run_depth = 1; | 784 run_depth_ = 1; |
| 728 } | 785 } |
| 729 loop_->state_ = this; | 786 loop_->state_ = this; |
| 730 | 787 |
| 788 if (run_id.get()) { |
| 789 DCHECK(!run_id->used_); |
| 790 run_state_id_ = run_id; |
| 791 run_state_id_->used_ = true; |
| 792 run_state_id_->run_state_ = this; |
| 793 } |
| 794 |
| 731 // Initialize the other fields: | 795 // Initialize the other fields: |
| 732 quit_received = false; | 796 quit_received_ = false; |
| 733 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | 797 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 734 dispatcher = NULL; | 798 dispatcher_ = NULL; |
| 735 #endif | 799 #endif |
| 736 } | 800 } |
| 737 | 801 |
| 738 MessageLoop::AutoRunState::~AutoRunState() { | 802 MessageLoop::AutoRunState::~AutoRunState() { |
| 739 loop_->state_ = previous_state_; | 803 loop_->state_ = previous_state_; |
| 804 if (run_state_id_.get()) { |
| 805 // run_state_id_->run_state_ points to 'this', so clear it. |
| 806 run_state_id_->run_state_ = NULL; |
| 807 } |
| 808 if (previous_state_ && previous_state_->run_state_id_.get() |
| 809 && previous_state_->run_state_id_->quit_now_received_) |
| 810 MessageLoop::current()->QuitNow(); |
| 740 } | 811 } |
| 741 | 812 |
| 742 //------------------------------------------------------------------------------ | 813 //------------------------------------------------------------------------------ |
| 743 // MessageLoopForUI | 814 // MessageLoopForUI |
| 744 | 815 |
| 745 #if defined(OS_WIN) | 816 #if defined(OS_WIN) |
| 746 void MessageLoopForUI::DidProcessMessage(const MSG& message) { | 817 void MessageLoopForUI::DidProcessMessage(const MSG& message) { |
| 747 pump_win()->DidProcessMessage(message); | 818 pump_win()->DidProcessMessage(message); |
| 748 } | 819 } |
| 749 #endif // defined(OS_WIN) | 820 #endif // defined(OS_WIN) |
| 750 | 821 |
| 751 #if defined(OS_ANDROID) | 822 #if defined(OS_ANDROID) |
| 752 void MessageLoopForUI::Start() { | 823 void MessageLoopForUI::Start() { |
| 753 // No Histogram support for UI message loop as it is managed by Java side | 824 // No Histogram support for UI message loop as it is managed by Java side |
| 754 static_cast<base::MessagePumpForUI*>(pump_.get())->Start(this); | 825 static_cast<base::MessagePumpForUI*>(pump_.get())->Start(this); |
| 755 } | 826 } |
| 756 #endif | 827 #endif |
| 757 | 828 |
| 758 #if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_ANDROID) | 829 #if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_ANDROID) |
| 759 void MessageLoopForUI::AddObserver(Observer* observer) { | 830 void MessageLoopForUI::AddObserver(Observer* observer) { |
| 760 pump_ui()->AddObserver(observer); | 831 pump_ui()->AddObserver(observer); |
| 761 } | 832 } |
| 762 | 833 |
| 763 void MessageLoopForUI::RemoveObserver(Observer* observer) { | 834 void MessageLoopForUI::RemoveObserver(Observer* observer) { |
| 764 pump_ui()->RemoveObserver(observer); | 835 pump_ui()->RemoveObserver(observer); |
| 765 } | 836 } |
| 766 | 837 |
| 767 void MessageLoopForUI::RunWithDispatcher(Dispatcher* dispatcher) { | 838 void MessageLoopForUI::RunWithDispatcher(Dispatcher* dispatcher) { |
| 768 AutoRunState save_state(this); | 839 AutoRunState save_state(this, NULL); |
| 769 state_->dispatcher = dispatcher; | 840 state_->dispatcher_ = dispatcher; |
| 841 RunHandler(); |
| 842 } |
| 843 |
| 844 void MessageLoopForUI::RunWithDispatcher(Dispatcher* dispatcher, |
| 845 const RunID& run_id) { |
| 846 AutoRunState save_state(this, run_id); |
| 847 state_->dispatcher_ = dispatcher; |
| 770 RunHandler(); | 848 RunHandler(); |
| 771 } | 849 } |
| 772 | 850 |
| 773 void MessageLoopForUI::RunAllPendingWithDispatcher(Dispatcher* dispatcher) { | 851 void MessageLoopForUI::RunAllPendingWithDispatcher(Dispatcher* dispatcher) { |
| 774 AutoRunState save_state(this); | 852 AutoRunState save_state(this, NULL); |
| 775 state_->dispatcher = dispatcher; | 853 state_->dispatcher_ = dispatcher; |
| 776 state_->quit_received = true; // Means run until we would otherwise block. | 854 state_->quit_received_ = true; // Means run until we would otherwise block. |
| 777 RunHandler(); | 855 RunHandler(); |
| 778 } | 856 } |
| 779 | 857 |
| 780 #endif // !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_ANDROID) | 858 #endif // !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_ANDROID) |
| 781 | 859 |
| 782 //------------------------------------------------------------------------------ | 860 //------------------------------------------------------------------------------ |
| 783 // MessageLoopForIO | 861 // MessageLoopForIO |
| 784 | 862 |
| 785 #if defined(OS_WIN) | 863 #if defined(OS_WIN) |
| 786 | 864 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 801 Watcher *delegate) { | 879 Watcher *delegate) { |
| 802 return pump_libevent()->WatchFileDescriptor( | 880 return pump_libevent()->WatchFileDescriptor( |
| 803 fd, | 881 fd, |
| 804 persistent, | 882 persistent, |
| 805 static_cast<base::MessagePumpLibevent::Mode>(mode), | 883 static_cast<base::MessagePumpLibevent::Mode>(mode), |
| 806 controller, | 884 controller, |
| 807 delegate); | 885 delegate); |
| 808 } | 886 } |
| 809 | 887 |
| 810 #endif | 888 #endif |
| OLD | NEW |