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

Side by Side Diff: base/message_loop/message_loop.cc

Issue 2394833004: MessageLoop mischief
Patch Set: . Created 3 years, 10 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
« no previous file with comments | « base/message_loop/message_loop.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 DCHECK_EQ(this, current()); 383 DCHECK_EQ(this, current());
384 DCHECK(run_loop_); 384 DCHECK(run_loop_);
385 CHECK(allow_nesting_ || run_loop_->run_depth_ == 1); 385 CHECK(allow_nesting_ || run_loop_->run_depth_ == 1);
386 pump_->Run(this); 386 pump_->Run(this);
387 } 387 }
388 388
389 bool MessageLoop::ProcessNextDelayedNonNestableTask() { 389 bool MessageLoop::ProcessNextDelayedNonNestableTask() {
390 if (run_loop_->run_depth_ != 1) 390 if (run_loop_->run_depth_ != 1)
391 return false; 391 return false;
392 392
393 if (deferred_non_nestable_work_queue_.empty()) 393 while (!deferred_non_nestable_work_queue_.empty()) {
394 return false; 394 PendingTask pending_task =
395 std::move(deferred_non_nestable_work_queue_.front());
396 deferred_non_nestable_work_queue_.pop();
395 397
396 PendingTask pending_task = 398 if (pending_task.task.IsCancelled()) {
397 std::move(deferred_non_nestable_work_queue_.front()); 399 #if defined(OS_WIN)
398 deferred_non_nestable_work_queue_.pop(); 400 if (pending_task.is_high_res) {
401 pending_high_res_tasks_--;
402 CHECK_GE(pending_high_res_tasks_, 0);
403 }
404 #endif
405 continue;
406 }
399 407
400 RunTask(&pending_task); 408 RunTask(&pending_task);
401 return true; 409 return true;
410 }
411
412 return false;
402 } 413 }
403 414
404 void MessageLoop::RunTask(PendingTask* pending_task) { 415 void MessageLoop::RunTask(PendingTask* pending_task) {
405 DCHECK(nestable_tasks_allowed_); 416 DCHECK(nestable_tasks_allowed_);
406 417
407 #if defined(OS_WIN) 418 #if defined(OS_WIN)
408 if (pending_task->is_high_res) { 419 if (pending_task->is_high_res) {
409 pending_high_res_tasks_--; 420 pending_high_res_tasks_--;
410 CHECK_GE(pending_high_res_tasks_, 0); 421 CHECK_GE(pending_high_res_tasks_, 0);
411 } 422 }
(...skipping 25 matching lines...) Expand all
437 // and the task isn't nestable. 448 // and the task isn't nestable.
438 deferred_non_nestable_work_queue_.push(std::move(pending_task)); 449 deferred_non_nestable_work_queue_.push(std::move(pending_task));
439 return false; 450 return false;
440 } 451 }
441 452
442 void MessageLoop::AddToDelayedWorkQueue(PendingTask pending_task) { 453 void MessageLoop::AddToDelayedWorkQueue(PendingTask pending_task) {
443 // Move to the delayed work queue. 454 // Move to the delayed work queue.
444 delayed_work_queue_.push(std::move(pending_task)); 455 delayed_work_queue_.push(std::move(pending_task));
445 } 456 }
446 457
458 bool MessageLoop::SweepDelayedWorkQueue() {
459 DCHECK(!delayed_work_queue_.empty());
460
461 do {
462 const auto& pending_task = delayed_work_queue_.top();
463 if (pending_task.task.IsCancelled()) {
464 #if defined(OS_WIN)
465 if (pending_task.is_high_res) {
466 pending_high_res_tasks_--;
467 CHECK_GE(pending_high_res_tasks_, 0);
468 }
469 #endif
470 delayed_work_queue_.pop();
471 continue;
472 } else {
473 return false;
474 }
475 } while (!delayed_work_queue_.empty());
476
477 return true;
478 }
479
447 bool MessageLoop::DeletePendingTasks() { 480 bool MessageLoop::DeletePendingTasks() {
448 bool did_work = !work_queue_.empty(); 481 bool did_work = !work_queue_.empty();
449 while (!work_queue_.empty()) { 482 while (!work_queue_.empty()) {
450 PendingTask pending_task = std::move(work_queue_.front()); 483 PendingTask pending_task = std::move(work_queue_.front());
451 work_queue_.pop(); 484 work_queue_.pop();
452 if (!pending_task.delayed_run_time.is_null()) { 485 if (!pending_task.delayed_run_time.is_null()) {
453 // We want to delete delayed tasks in the same order in which they would 486 // We want to delete delayed tasks in the same order in which they would
454 // normally be deleted in case of any funny dependencies between delayed 487 // normally be deleted in case of any funny dependencies between delayed
455 // tasks. 488 // tasks.
456 AddToDelayedWorkQueue(std::move(pending_task)); 489 AddToDelayedWorkQueue(std::move(pending_task));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 538
506 for (;;) { 539 for (;;) {
507 ReloadWorkQueue(); 540 ReloadWorkQueue();
508 if (work_queue_.empty()) 541 if (work_queue_.empty())
509 break; 542 break;
510 543
511 // Execute oldest task. 544 // Execute oldest task.
512 do { 545 do {
513 PendingTask pending_task = std::move(work_queue_.front()); 546 PendingTask pending_task = std::move(work_queue_.front());
514 work_queue_.pop(); 547 work_queue_.pop();
548
549 if (pending_task.task.IsCancelled()) {
550 #if defined(OS_WIN)
551 if (pending_task.is_high_res) {
552 pending_high_res_tasks_--;
553 CHECK_GE(pending_high_res_tasks_, 0);
554 }
555 #endif
556 continue;
557 }
558
515 if (!pending_task.delayed_run_time.is_null()) { 559 if (!pending_task.delayed_run_time.is_null()) {
516 int sequence_num = pending_task.sequence_num; 560 int sequence_num = pending_task.sequence_num;
517 TimeTicks delayed_run_time = pending_task.delayed_run_time; 561 TimeTicks delayed_run_time = pending_task.delayed_run_time;
518 AddToDelayedWorkQueue(std::move(pending_task)); 562 AddToDelayedWorkQueue(std::move(pending_task));
519 // If we changed the topmost task, then it is time to reschedule. 563 // If we changed the topmost task, then it is time to reschedule.
520 if (delayed_work_queue_.top().sequence_num == sequence_num) 564 if (delayed_work_queue_.top().sequence_num == sequence_num)
521 pump_->ScheduleDelayedWork(delayed_run_time); 565 pump_->ScheduleDelayedWork(delayed_run_time);
522 } else { 566 } else {
523 if (DeferOrRunPendingTask(std::move(pending_task))) 567 if (DeferOrRunPendingTask(std::move(pending_task)))
524 return true; 568 return true;
525 } 569 }
526 } while (!work_queue_.empty()); 570 } while (!work_queue_.empty());
527 } 571 }
528 572
529 // Nothing happened. 573 // Nothing happened.
530 return false; 574 return false;
531 } 575 }
532 576
533 bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { 577 bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) {
534 if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { 578 if (!nestable_tasks_allowed_ || delayed_work_queue_.empty() ||
579 SweepDelayedWorkQueue()) {
535 recent_time_ = *next_delayed_work_time = TimeTicks(); 580 recent_time_ = *next_delayed_work_time = TimeTicks();
536 return false; 581 return false;
537 } 582 }
538 583
539 // When we "fall behind", there will be a lot of tasks in the delayed work 584 // When we "fall behind", there will be a lot of tasks in the delayed work
540 // queue that are ready to run. To increase efficiency when we fall behind, 585 // queue that are ready to run. To increase efficiency when we fall behind,
541 // we will only call Time::Now() intermittently, and then process all tasks 586 // we will only call Time::Now() intermittently, and then process all tasks
542 // that are ready to run before calling it again. As a result, the more we 587 // that are ready to run before calling it again. As a result, the more we
543 // fall behind (and have a lot of ready-to-run delayed tasks), the more 588 // fall behind (and have a lot of ready-to-run delayed tasks), the more
544 // efficient we'll be at handling the tasks. 589 // efficient we'll be at handling the tasks.
545 590
546 TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time; 591 TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time;
547 if (next_run_time > recent_time_) { 592 if (next_run_time > recent_time_) {
548 recent_time_ = TimeTicks::Now(); // Get a better view of Now(); 593 recent_time_ = TimeTicks::Now(); // Get a better view of Now();
549 if (next_run_time > recent_time_) { 594 if (next_run_time > recent_time_) {
550 *next_delayed_work_time = next_run_time; 595 *next_delayed_work_time = next_run_time;
551 return false; 596 return false;
552 } 597 }
553 } 598 }
554 599
555 PendingTask pending_task = 600 PendingTask pending_task =
556 std::move(const_cast<PendingTask&>(delayed_work_queue_.top())); 601 std::move(const_cast<PendingTask&>(delayed_work_queue_.top()));
557 delayed_work_queue_.pop(); 602 delayed_work_queue_.pop();
558 603
559 if (!delayed_work_queue_.empty()) 604 bool did_work = DeferOrRunPendingTask(std::move(pending_task));
605
606 if (!delayed_work_queue_.empty() && !SweepDelayedWorkQueue())
560 *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; 607 *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time;
561 608
562 return DeferOrRunPendingTask(std::move(pending_task)); 609 return did_work;
563 } 610 }
564 611
565 bool MessageLoop::DoIdleWork() { 612 bool MessageLoop::DoIdleWork() {
566 if (ProcessNextDelayedNonNestableTask()) 613 if (ProcessNextDelayedNonNestableTask())
567 return true; 614 return true;
568 615
569 if (run_loop_->quit_when_idle_received_) 616 if (run_loop_->quit_when_idle_received_)
570 pump_->Quit(); 617 pump_->Quit();
571 618
572 // When we return we will do a kernel wait for more tasks. 619 // When we return we will do a kernel wait for more tasks.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 persistent, 709 persistent,
663 mode, 710 mode,
664 controller, 711 controller,
665 delegate); 712 delegate);
666 } 713 }
667 #endif 714 #endif
668 715
669 #endif // !defined(OS_NACL_SFI) 716 #endif // !defined(OS_NACL_SFI)
670 717
671 } // namespace base 718 } // namespace base
OLDNEW
« no previous file with comments | « base/message_loop/message_loop.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698