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

Side by Side Diff: base/message_loop.cc

Issue 10479018: Add base::RunLoop and update ui_test_utils to use it to reduce flakiness (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: jar, phajdan feedback Created 8 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 | Annotate | Revision Log
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 "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
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
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
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
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
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
OLDNEW
« base/message_loop.h ('K') | « base/message_loop.h ('k') | base/message_loop_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698