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

Side by Side Diff: base/message_loop.cc

Issue 6463013: Add support for base::Closure in the MessageLoop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: rebased Created 9 years, 8 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
« no previous file with comments | « base/message_loop.h ('k') | base/message_loop_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #if defined(OS_POSIX) && !defined(OS_MACOSX)
8 #include <gdk/gdk.h>
9 #include <gdk/gdkx.h>
10 #endif
11
12 #include <algorithm> 7 #include <algorithm>
13 8
9 #include "base/bind.h"
14 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
15 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
16 #include "base/logging.h" 12 #include "base/logging.h"
17 #include "base/message_pump_default.h" 13 #include "base/message_pump_default.h"
18 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/scoped_ptr.h"
19 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 16 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
20 #include "base/threading/thread_local.h" 17 #include "base/threading/thread_local.h"
18 #include "base/tracked_objects.h"
21 19
22 #if defined(OS_MACOSX) 20 #if defined(OS_MACOSX)
23 #include "base/message_pump_mac.h" 21 #include "base/message_pump_mac.h"
24 #endif 22 #endif
25 #if defined(OS_POSIX) 23 #if defined(OS_POSIX)
26 #include "base/message_pump_libevent.h" 24 #include "base/message_pump_libevent.h"
27 #endif 25 #endif
28 #if defined(OS_POSIX) && !defined(OS_MACOSX) 26 #if defined(OS_POSIX) && !defined(OS_MACOSX)
27 #include <gdk/gdk.h>
28 #include <gdk/gdkx.h>
29 #include "base/message_pump_glib.h" 29 #include "base/message_pump_glib.h"
30 #endif 30 #endif
31 #if defined(TOUCH_UI) 31 #if defined(TOUCH_UI)
32 #include "base/message_pump_glib_x.h" 32 #include "base/message_pump_glib_x.h"
33 #endif 33 #endif
34 34
35 using base::TimeDelta; 35 using base::TimeDelta;
36 using base::TimeTicks; 36 using base::TimeTicks;
37 37
38 namespace { 38 namespace {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 74
75 // A few events we handle (kindred to messages), and used to profile actions. 75 // A few events we handle (kindred to messages), and used to profile actions.
76 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) 76 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent)
77 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) 77 VALUE_TO_NUMBER_AND_NAME(kTimerEvent)
78 78
79 {-1, NULL} // The list must be null terminated, per API to histogram. 79 {-1, NULL} // The list must be null terminated, per API to histogram.
80 }; 80 };
81 81
82 bool enable_histogrammer_ = false; 82 bool enable_histogrammer_ = false;
83 83
84 // TODO(ajwong): This is one use case for having a Owned() tag that behaves
85 // like a "Unique" pointer. If we had that, and Tasks were always safe to
86 // delete on MessageLoop shutdown, this class could just be a function.
87 class TaskClosureAdapter : public base::RefCounted<TaskClosureAdapter> {
88 public:
89 // |should_leak_task| points to a flag variable that can be used to determine
90 // if this class should leak the Task on destruction. This is important
91 // at MessageLoop shutdown since not all tasks can be safely deleted without
92 // running. See MessageLoop::DeletePendingTasks() for the exact behavior
93 // of when a Task should be deleted. It is subtle.
94 TaskClosureAdapter(Task* task, bool* should_leak_task)
95 : task_(task),
96 should_leak_task_(should_leak_task) {
97 }
98
99 void Run() {
100 task_->Run();
101 delete task_;
102 task_ = NULL;
103 }
104
105 private:
106 friend class base::RefCounted<TaskClosureAdapter>;
107
108 ~TaskClosureAdapter() {
109 if (!*should_leak_task_) {
110 delete task_;
111 }
112 }
113
114 Task* task_;
115 bool* should_leak_task_;
116 };
117
84 } // namespace 118 } // namespace
85 119
86 //------------------------------------------------------------------------------ 120 //------------------------------------------------------------------------------
87 121
88 #if defined(OS_WIN) 122 #if defined(OS_WIN)
89 123
90 // Upon a SEH exception in this thread, it restores the original unhandled 124 // Upon a SEH exception in this thread, it restores the original unhandled
91 // exception filter. 125 // exception filter.
92 static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) { 126 static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) {
93 ::SetUnhandledExceptionFilter(old_filter); 127 ::SetUnhandledExceptionFilter(old_filter);
(...skipping 23 matching lines...) Expand all
117 } 151 }
118 152
119 //------------------------------------------------------------------------------ 153 //------------------------------------------------------------------------------
120 154
121 MessageLoop::MessageLoop(Type type) 155 MessageLoop::MessageLoop(Type type)
122 : type_(type), 156 : type_(type),
123 nestable_tasks_allowed_(true), 157 nestable_tasks_allowed_(true),
124 exception_restoration_(false), 158 exception_restoration_(false),
125 message_histogram_(NULL), 159 message_histogram_(NULL),
126 state_(NULL), 160 state_(NULL),
161 should_leak_tasks_(true),
127 #ifdef OS_WIN 162 #ifdef OS_WIN
128 os_modal_loop_(false), 163 os_modal_loop_(false),
129 #endif // OS_WIN 164 #endif // OS_WIN
130 next_sequence_num_(0) { 165 next_sequence_num_(0) {
131 DCHECK(!current()) << "should only have one message loop per thread"; 166 DCHECK(!current()) << "should only have one message loop per thread";
132 lazy_tls_ptr.Pointer()->Set(this); 167 lazy_tls_ptr.Pointer()->Set(this);
133 168
134 // TODO(rvargas): Get rid of the OS guards. 169 // TODO(rvargas): Get rid of the OS guards.
135 #if defined(OS_WIN) 170 #if defined(OS_WIN)
136 #define MESSAGE_PUMP_UI new base::MessagePumpForUI() 171 #define MESSAGE_PUMP_UI new base::MessagePumpForUI()
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 248 }
214 249
215 void MessageLoop::RemoveDestructionObserver( 250 void MessageLoop::RemoveDestructionObserver(
216 DestructionObserver* destruction_observer) { 251 DestructionObserver* destruction_observer) {
217 DCHECK_EQ(this, current()); 252 DCHECK_EQ(this, current());
218 destruction_observers_.RemoveObserver(destruction_observer); 253 destruction_observers_.RemoveObserver(destruction_observer);
219 } 254 }
220 255
221 void MessageLoop::PostTask( 256 void MessageLoop::PostTask(
222 const tracked_objects::Location& from_here, Task* task) { 257 const tracked_objects::Location& from_here, Task* task) {
223 PostTask_Helper(from_here, task, 0, true); 258 PendingTask pending_task(
259 base::Bind(&TaskClosureAdapter::Run,
260 new TaskClosureAdapter(task, &should_leak_tasks_)),
261 from_here,
262 CalculateDelayedRuntime(0), true);
263 AddToIncomingQueue(&pending_task);
224 } 264 }
225 265
226 void MessageLoop::PostDelayedTask( 266 void MessageLoop::PostDelayedTask(
227 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) { 267 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) {
228 PostTask_Helper(from_here, task, delay_ms, true); 268 PendingTask pending_task(
269 base::Bind(&TaskClosureAdapter::Run,
270 new TaskClosureAdapter(task, &should_leak_tasks_)),
271 from_here,
272 CalculateDelayedRuntime(delay_ms), true);
273 AddToIncomingQueue(&pending_task);
229 } 274 }
230 275
231 void MessageLoop::PostNonNestableTask( 276 void MessageLoop::PostNonNestableTask(
232 const tracked_objects::Location& from_here, Task* task) { 277 const tracked_objects::Location& from_here, Task* task) {
233 PostTask_Helper(from_here, task, 0, false); 278 PendingTask pending_task(
279 base::Bind(&TaskClosureAdapter::Run,
280 new TaskClosureAdapter(task, &should_leak_tasks_)),
281 from_here,
282 CalculateDelayedRuntime(0), false);
283 AddToIncomingQueue(&pending_task);
234 } 284 }
235 285
236 void MessageLoop::PostNonNestableDelayedTask( 286 void MessageLoop::PostNonNestableDelayedTask(
237 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) { 287 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) {
238 PostTask_Helper(from_here, task, delay_ms, false); 288 PendingTask pending_task(
289 base::Bind(&TaskClosureAdapter::Run,
290 new TaskClosureAdapter(task, &should_leak_tasks_)),
291 from_here,
292 CalculateDelayedRuntime(delay_ms), false);
293 AddToIncomingQueue(&pending_task);
294 }
295
296 void MessageLoop::PostTask(
297 const tracked_objects::Location& from_here, const base::Closure& task) {
298 DCHECK(!task.is_null());
299 PendingTask pending_task(task, from_here, CalculateDelayedRuntime(0), true);
300 AddToIncomingQueue(&pending_task);
301 }
302
303 void MessageLoop::PostDelayedTask(
304 const tracked_objects::Location& from_here, const base::Closure& task,
305 int64 delay_ms) {
306 DCHECK(!task.is_null());
307 PendingTask pending_task(task, from_here,
308 CalculateDelayedRuntime(delay_ms), true);
309 AddToIncomingQueue(&pending_task);
310 }
311
312 void MessageLoop::PostNonNestableTask(
313 const tracked_objects::Location& from_here, const base::Closure& task) {
314 DCHECK(!task.is_null());
315 PendingTask pending_task(task, from_here, CalculateDelayedRuntime(0), false);
316 AddToIncomingQueue(&pending_task);
317 }
318
319 void MessageLoop::PostNonNestableDelayedTask(
320 const tracked_objects::Location& from_here, const base::Closure& task,
321 int64 delay_ms) {
322 DCHECK(!task.is_null());
323 PendingTask pending_task(task, from_here,
324 CalculateDelayedRuntime(delay_ms), false);
325 AddToIncomingQueue(&pending_task);
239 } 326 }
240 327
241 void MessageLoop::Run() { 328 void MessageLoop::Run() {
242 AutoRunState save_state(this); 329 AutoRunState save_state(this);
243 RunHandler(); 330 RunHandler();
244 } 331 }
245 332
246 void MessageLoop::RunAllPending() { 333 void MessageLoop::RunAllPending() {
247 AutoRunState save_state(this); 334 AutoRunState save_state(this);
248 state_->quit_received = true; // Means run until we would otherwise block. 335 state_->quit_received = true; // Means run until we would otherwise block.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 pump_->Run(this); 433 pump_->Run(this);
347 } 434 }
348 435
349 bool MessageLoop::ProcessNextDelayedNonNestableTask() { 436 bool MessageLoop::ProcessNextDelayedNonNestableTask() {
350 if (state_->run_depth != 1) 437 if (state_->run_depth != 1)
351 return false; 438 return false;
352 439
353 if (deferred_non_nestable_work_queue_.empty()) 440 if (deferred_non_nestable_work_queue_.empty())
354 return false; 441 return false;
355 442
356 Task* task = deferred_non_nestable_work_queue_.front().task; 443 PendingTask pending_task = deferred_non_nestable_work_queue_.front();
357 deferred_non_nestable_work_queue_.pop(); 444 deferred_non_nestable_work_queue_.pop();
358 445
359 RunTask(task); 446 RunTask(pending_task);
360 return true; 447 return true;
361 } 448 }
362 449
363 void MessageLoop::RunTask(Task* task) { 450 void MessageLoop::RunTask(const PendingTask& pending_task) {
364 DCHECK(nestable_tasks_allowed_); 451 DCHECK(nestable_tasks_allowed_);
365 // Execute the task and assume the worst: It is probably not reentrant. 452 // Execute the task and assume the worst: It is probably not reentrant.
366 nestable_tasks_allowed_ = false; 453 nestable_tasks_allowed_ = false;
367 454
368 HistogramEvent(kTaskRunEvent); 455 HistogramEvent(kTaskRunEvent);
369 FOR_EACH_OBSERVER(TaskObserver, task_observers_, 456 FOR_EACH_OBSERVER(TaskObserver, task_observers_,
370 WillProcessTask(task)); 457 WillProcessTask(pending_task.time_posted));
371 task->Run(); 458 pending_task.task.Run();
372 FOR_EACH_OBSERVER(TaskObserver, task_observers_, DidProcessTask(task)); 459 FOR_EACH_OBSERVER(TaskObserver, task_observers_,
373 delete task; 460 DidProcessTask(pending_task.time_posted));
461
462 #if defined(TRACK_ALL_TASK_OBJECTS)
463 if (tracked_objects::ThreadData::IsActive() && pending_task.post_births) {
464 tracked_objects::ThreadData::current()->TallyADeath(
465 *pending_task.post_births,
466 TimeTicks::Now() - pending_task.time_posted);
467 }
468 #endif // defined(TRACK_ALL_TASK_OBJECTS)
374 469
375 nestable_tasks_allowed_ = true; 470 nestable_tasks_allowed_ = true;
376 } 471 }
377 472
378 bool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) { 473 bool MessageLoop::DeferOrRunPendingTask(
474 const PendingTask& pending_task) {
379 if (pending_task.nestable || state_->run_depth == 1) { 475 if (pending_task.nestable || state_->run_depth == 1) {
380 RunTask(pending_task.task); 476 RunTask(pending_task);
381 // Show that we ran a task (Note: a new one might arrive as a 477 // Show that we ran a task (Note: a new one might arrive as a
382 // consequence!). 478 // consequence!).
383 return true; 479 return true;
384 } 480 }
385 481
386 // We couldn't run the task now because we're in a nested message loop 482 // We couldn't run the task now because we're in a nested message loop
387 // and the task isn't nestable. 483 // and the task isn't nestable.
388 deferred_non_nestable_work_queue_.push(pending_task); 484 deferred_non_nestable_work_queue_.push(pending_task);
389 return false; 485 return false;
390 } 486 }
(...skipping 21 matching lines...) Expand all
412 base::AutoLock lock(incoming_queue_lock_); 508 base::AutoLock lock(incoming_queue_lock_);
413 if (incoming_queue_.empty()) 509 if (incoming_queue_.empty())
414 return; 510 return;
415 incoming_queue_.Swap(&work_queue_); // Constant time 511 incoming_queue_.Swap(&work_queue_); // Constant time
416 DCHECK(incoming_queue_.empty()); 512 DCHECK(incoming_queue_.empty());
417 } 513 }
418 } 514 }
419 515
420 bool MessageLoop::DeletePendingTasks() { 516 bool MessageLoop::DeletePendingTasks() {
421 bool did_work = !work_queue_.empty(); 517 bool did_work = !work_queue_.empty();
518 // TODO(darin): Delete all tasks once it is safe to do so.
519 // Until it is totally safe, just do it when running Purify or
520 // Valgrind.
521 //
522 // See http://crbug.com/61131
523 //
524 #if defined(PURIFY) || defined(USE_HEAPCHECKER)
525 should_leak_tasks_ = false;
526 #else
527 if (RunningOnValgrind())
528 should_leak_tasks_ = false;
529 #endif // defined(OS_POSIX)
422 while (!work_queue_.empty()) { 530 while (!work_queue_.empty()) {
423 PendingTask pending_task = work_queue_.front(); 531 PendingTask pending_task = work_queue_.front();
424 work_queue_.pop(); 532 work_queue_.pop();
425 if (!pending_task.delayed_run_time.is_null()) { 533 if (!pending_task.delayed_run_time.is_null()) {
426 // We want to delete delayed tasks in the same order in which they would 534 // We want to delete delayed tasks in the same order in which they would
427 // normally be deleted in case of any funny dependencies between delayed 535 // normally be deleted in case of any funny dependencies between delayed
428 // tasks. 536 // tasks.
429 AddToDelayedWorkQueue(pending_task); 537 AddToDelayedWorkQueue(pending_task);
430 } else {
431 // TODO(darin): Delete all tasks once it is safe to do so.
432 // Until it is totally safe, just do it when running Purify or
433 // Valgrind.
434 #if defined(PURIFY) || defined(USE_HEAPCHECKER)
435 delete pending_task.task;
436 #else
437 if (RunningOnValgrind())
438 delete pending_task.task;
439 #endif // defined(OS_POSIX)
440 } 538 }
441 } 539 }
442 did_work |= !deferred_non_nestable_work_queue_.empty(); 540 did_work |= !deferred_non_nestable_work_queue_.empty();
443 while (!deferred_non_nestable_work_queue_.empty()) { 541 while (!deferred_non_nestable_work_queue_.empty()) {
444 // TODO(darin): Delete all tasks once it is safe to do so.
445 // Until it is totaly safe, only delete them under Purify and Valgrind.
446 Task* task = NULL;
447 #if defined(PURIFY) || defined(USE_HEAPCHECKER)
448 task = deferred_non_nestable_work_queue_.front().task;
449 #else
450 if (RunningOnValgrind())
451 task = deferred_non_nestable_work_queue_.front().task;
452 #endif
453 deferred_non_nestable_work_queue_.pop(); 542 deferred_non_nestable_work_queue_.pop();
454 if (task)
455 delete task;
456 } 543 }
457 did_work |= !delayed_work_queue_.empty(); 544 did_work |= !delayed_work_queue_.empty();
545
546 // Historically, we always delete the task regardless of valgrind status. It's
547 // not completely clear why we want to leak them in the loops above. This
548 // code is replicating legacy behavior, and should not be considered
549 // absolutely "correct" behavior. See TODO above about deleting all tasks
550 // when it's safe.
551 should_leak_tasks_ = false;
458 while (!delayed_work_queue_.empty()) { 552 while (!delayed_work_queue_.empty()) {
459 Task* task = delayed_work_queue_.top().task;
460 delayed_work_queue_.pop(); 553 delayed_work_queue_.pop();
461 delete task;
462 } 554 }
555 should_leak_tasks_ = true;
463 return did_work; 556 return did_work;
464 } 557 }
465 558
466 // Possibly called on a background thread! 559 TimeTicks MessageLoop::CalculateDelayedRuntime(int64 delay_ms) {
467 void MessageLoop::PostTask_Helper( 560 TimeTicks delayed_run_time;
468 const tracked_objects::Location& from_here, Task* task, int64 delay_ms,
469 bool nestable) {
470 task->SetBirthPlace(from_here);
471
472 PendingTask pending_task(task, nestable);
473
474 if (delay_ms > 0) { 561 if (delay_ms > 0) {
475 pending_task.delayed_run_time = 562 delayed_run_time =
476 TimeTicks::Now() + TimeDelta::FromMilliseconds(delay_ms); 563 TimeTicks::Now() + TimeDelta::FromMilliseconds(delay_ms);
477 564
478 #if defined(OS_WIN) 565 #if defined(OS_WIN)
479 if (high_resolution_timer_expiration_.is_null()) { 566 if (high_resolution_timer_expiration_.is_null()) {
480 // Windows timers are granular to 15.6ms. If we only set high-res 567 // Windows timers are granular to 15.6ms. If we only set high-res
481 // timers for those under 15.6ms, then a 18ms timer ticks at ~32ms, 568 // timers for those under 15.6ms, then a 18ms timer ticks at ~32ms,
482 // which as a percentage is pretty inaccurate. So enable high 569 // which as a percentage is pretty inaccurate. So enable high
483 // res timers for any timer which is within 2x of the granularity. 570 // res timers for any timer which is within 2x of the granularity.
484 // This is a tradeoff between accuracy and power management. 571 // This is a tradeoff between accuracy and power management.
485 bool needs_high_res_timers = 572 bool needs_high_res_timers =
(...skipping 11 matching lines...) Expand all
497 584
498 #if defined(OS_WIN) 585 #if defined(OS_WIN)
499 if (!high_resolution_timer_expiration_.is_null()) { 586 if (!high_resolution_timer_expiration_.is_null()) {
500 if (TimeTicks::Now() > high_resolution_timer_expiration_) { 587 if (TimeTicks::Now() > high_resolution_timer_expiration_) {
501 base::Time::ActivateHighResolutionTimer(false); 588 base::Time::ActivateHighResolutionTimer(false);
502 high_resolution_timer_expiration_ = TimeTicks(); 589 high_resolution_timer_expiration_ = TimeTicks();
503 } 590 }
504 } 591 }
505 #endif 592 #endif
506 593
594 return delayed_run_time;
595 }
596
597 // Possibly called on a background thread!
598 void MessageLoop::AddToIncomingQueue(PendingTask* pending_task) {
507 // Warning: Don't try to short-circuit, and handle this thread's tasks more 599 // Warning: Don't try to short-circuit, and handle this thread's tasks more
508 // directly, as it could starve handling of foreign threads. Put every task 600 // directly, as it could starve handling of foreign threads. Put every task
509 // into this queue. 601 // into this queue.
510 602
511 scoped_refptr<base::MessagePump> pump; 603 scoped_refptr<base::MessagePump> pump;
512 { 604 {
513 base::AutoLock locked(incoming_queue_lock_); 605 base::AutoLock locked(incoming_queue_lock_);
514 606
515 bool was_empty = incoming_queue_.empty(); 607 bool was_empty = incoming_queue_.empty();
516 incoming_queue_.push(pending_task); 608 incoming_queue_.push(*pending_task);
609 pending_task->task.Reset();
517 if (!was_empty) 610 if (!was_empty)
518 return; // Someone else should have started the sub-pump. 611 return; // Someone else should have started the sub-pump.
519 612
520 pump = pump_; 613 pump = pump_;
521 } 614 }
522 // Since the incoming_queue_ may contain a task that destroys this message 615 // Since the incoming_queue_ may contain a task that destroys this message
523 // loop, we cannot exit incoming_queue_lock_ until we are done with |this|. 616 // loop, we cannot exit incoming_queue_lock_ until we are done with |this|.
524 // We use a stack-based reference to the message pump so that we can call 617 // We use a stack-based reference to the message pump so that we can call
525 // ScheduleWork outside of incoming_queue_lock_. 618 // ScheduleWork outside of incoming_queue_lock_.
526 619
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 ReloadWorkQueue(); 652 ReloadWorkQueue();
560 if (work_queue_.empty()) 653 if (work_queue_.empty())
561 break; 654 break;
562 655
563 // Execute oldest task. 656 // Execute oldest task.
564 do { 657 do {
565 PendingTask pending_task = work_queue_.front(); 658 PendingTask pending_task = work_queue_.front();
566 work_queue_.pop(); 659 work_queue_.pop();
567 if (!pending_task.delayed_run_time.is_null()) { 660 if (!pending_task.delayed_run_time.is_null()) {
568 AddToDelayedWorkQueue(pending_task); 661 AddToDelayedWorkQueue(pending_task);
569 // If we changed the topmost task, then it is time to re-schedule. 662 // If we changed the topmost task, then it is time to reschedule.
570 if (delayed_work_queue_.top().task == pending_task.task) 663 if (delayed_work_queue_.top().task.Equals(pending_task.task))
571 pump_->ScheduleDelayedWork(pending_task.delayed_run_time); 664 pump_->ScheduleDelayedWork(pending_task.delayed_run_time);
572 } else { 665 } else {
573 if (DeferOrRunPendingTask(pending_task)) 666 if (DeferOrRunPendingTask(pending_task))
574 return true; 667 return true;
575 } 668 }
576 } while (!work_queue_.empty()); 669 } while (!work_queue_.empty());
577 } 670 }
578 671
579 // Nothing happened. 672 // Nothing happened.
580 return false; 673 return false;
581 } 674 }
582 675
583 bool MessageLoop::DoDelayedWork(base::TimeTicks* next_delayed_work_time) { 676 bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) {
584 if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { 677 if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) {
585 recent_time_ = *next_delayed_work_time = TimeTicks(); 678 recent_time_ = *next_delayed_work_time = TimeTicks();
586 return false; 679 return false;
587 } 680 }
588 681
589 // When we "fall behind," there will be a lot of tasks in the delayed work 682 // When we "fall behind," there will be a lot of tasks in the delayed work
590 // queue that are ready to run. To increase efficiency when we fall behind, 683 // queue that are ready to run. To increase efficiency when we fall behind,
591 // we will only call Time::Now() intermittently, and then process all tasks 684 // we will only call Time::Now() intermittently, and then process all tasks
592 // that are ready to run before calling it again. As a result, the more we 685 // that are ready to run before calling it again. As a result, the more we
593 // fall behind (and have a lot of ready-to-run delayed tasks), the more 686 // fall behind (and have a lot of ready-to-run delayed tasks), the more
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 #endif 734 #endif
642 } 735 }
643 736
644 MessageLoop::AutoRunState::~AutoRunState() { 737 MessageLoop::AutoRunState::~AutoRunState() {
645 loop_->state_ = previous_state_; 738 loop_->state_ = previous_state_;
646 } 739 }
647 740
648 //------------------------------------------------------------------------------ 741 //------------------------------------------------------------------------------
649 // MessageLoop::PendingTask 742 // MessageLoop::PendingTask
650 743
744 MessageLoop::PendingTask::PendingTask(
745 const base::Closure& task,
746 const tracked_objects::Location& posted_from,
747 TimeTicks delayed_run_time,
748 bool nestable)
749 : task(task),
750 time_posted(TimeTicks::Now()),
751 delayed_run_time(delayed_run_time),
752 sequence_num(0),
753 nestable(nestable) {
754 #if defined(TRACK_ALL_TASK_OBJECTS)
755 if (tracked_objects::ThreadData::IsActive()) {
756 tracked_objects::ThreadData* current_thread_data =
757 tracked_objects::ThreadData::current();
758 if (current_thread_data) {
759 post_births = current_thread_data->TallyABirth(posted_from);
760 } else {
761 // Shutdown started, and this thread wasn't registered.
762 post_births = NULL;
763 }
764 }
765 #endif // defined(TRACK_ALL_TASK_OBJECTS)
766 }
767
768 MessageLoop::PendingTask::~PendingTask() {
769 }
770
651 bool MessageLoop::PendingTask::operator<(const PendingTask& other) const { 771 bool MessageLoop::PendingTask::operator<(const PendingTask& other) const {
652 // Since the top of a priority queue is defined as the "greatest" element, we 772 // Since the top of a priority queue is defined as the "greatest" element, we
653 // need to invert the comparison here. We want the smaller time to be at the 773 // need to invert the comparison here. We want the smaller time to be at the
654 // top of the heap. 774 // top of the heap.
655 775
656 if (delayed_run_time < other.delayed_run_time) 776 if (delayed_run_time < other.delayed_run_time)
657 return false; 777 return false;
658 778
659 if (delayed_run_time > other.delayed_run_time) 779 if (delayed_run_time > other.delayed_run_time)
660 return true; 780 return true;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 Watcher *delegate) { 837 Watcher *delegate) {
718 return pump_libevent()->WatchFileDescriptor( 838 return pump_libevent()->WatchFileDescriptor(
719 fd, 839 fd,
720 persistent, 840 persistent,
721 static_cast<base::MessagePumpLibevent::Mode>(mode), 841 static_cast<base::MessagePumpLibevent::Mode>(mode),
722 controller, 842 controller,
723 delegate); 843 delegate);
724 } 844 }
725 845
726 #endif 846 #endif
OLDNEW
« no previous file with comments | « 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