| OLD | NEW |
| 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 #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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 | 78 |
| 79 // A few events we handle (kindred to messages), and used to profile actions. | 79 // A few events we handle (kindred to messages), and used to profile actions. |
| 80 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) | 80 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) |
| 81 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) | 81 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) |
| 82 | 82 |
| 83 {-1, NULL} // The list must be null terminated, per API to histogram. | 83 {-1, NULL} // The list must be null terminated, per API to histogram. |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 bool enable_histogrammer_ = false; | 86 bool enable_histogrammer_ = false; |
| 87 | 87 |
| 88 // TODO(ajwong): This is one use case for having a Owned() tag that behaves | |
| 89 // like a "Unique" pointer. If we had that, and Tasks were always safe to | |
| 90 // delete on MessageLoop shutdown, this class could just be a function. | |
| 91 class TaskClosureAdapter : public base::RefCounted<TaskClosureAdapter> { | |
| 92 public: | |
| 93 // |should_leak_task| points to a flag variable that can be used to determine | |
| 94 // if this class should leak the Task on destruction. This is important | |
| 95 // at MessageLoop shutdown since not all tasks can be safely deleted without | |
| 96 // running. See MessageLoop::DeletePendingTasks() for the exact behavior | |
| 97 // of when a Task should be deleted. It is subtle. | |
| 98 TaskClosureAdapter(Task* task, bool* should_leak_task) | |
| 99 : task_(task), | |
| 100 should_leak_task_(should_leak_task) { | |
| 101 } | |
| 102 | |
| 103 void Run() { | |
| 104 task_->Run(); | |
| 105 delete task_; | |
| 106 task_ = NULL; | |
| 107 } | |
| 108 | |
| 109 private: | |
| 110 friend class base::RefCounted<TaskClosureAdapter>; | |
| 111 | |
| 112 ~TaskClosureAdapter() { | |
| 113 if (!*should_leak_task_) { | |
| 114 delete task_; | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 Task* task_; | |
| 119 bool* should_leak_task_; | |
| 120 }; | |
| 121 | |
| 122 } // namespace | 88 } // namespace |
| 123 | 89 |
| 124 //------------------------------------------------------------------------------ | 90 //------------------------------------------------------------------------------ |
| 125 | 91 |
| 126 #if defined(OS_WIN) | 92 #if defined(OS_WIN) |
| 127 | 93 |
| 128 // Upon a SEH exception in this thread, it restores the original unhandled | 94 // Upon a SEH exception in this thread, it restores the original unhandled |
| 129 // exception filter. | 95 // exception filter. |
| 130 static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) { | 96 static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) { |
| 131 ::SetUnhandledExceptionFilter(old_filter); | 97 ::SetUnhandledExceptionFilter(old_filter); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 void MessageLoop::RemoveDestructionObserver( | 230 void MessageLoop::RemoveDestructionObserver( |
| 265 DestructionObserver* destruction_observer) { | 231 DestructionObserver* destruction_observer) { |
| 266 DCHECK_EQ(this, current()); | 232 DCHECK_EQ(this, current()); |
| 267 destruction_observers_.RemoveObserver(destruction_observer); | 233 destruction_observers_.RemoveObserver(destruction_observer); |
| 268 } | 234 } |
| 269 | 235 |
| 270 void MessageLoop::PostTask( | 236 void MessageLoop::PostTask( |
| 271 const tracked_objects::Location& from_here, Task* task) { | 237 const tracked_objects::Location& from_here, Task* task) { |
| 272 CHECK(task); | 238 CHECK(task); |
| 273 PendingTask pending_task( | 239 PendingTask pending_task( |
| 274 base::Bind(&TaskClosureAdapter::Run, | 240 base::Bind( |
| 275 new TaskClosureAdapter(task, &should_leak_tasks_)), | 241 &base::subtle::TaskClosureAdapter::Run, |
| 242 new base::subtle::TaskClosureAdapter(task, &should_leak_tasks_)), |
| 276 from_here, | 243 from_here, |
| 277 CalculateDelayedRuntime(0), true); | 244 CalculateDelayedRuntime(0), true); |
| 278 AddToIncomingQueue(&pending_task); | 245 AddToIncomingQueue(&pending_task); |
| 279 } | 246 } |
| 280 | 247 |
| 281 void MessageLoop::PostDelayedTask( | 248 void MessageLoop::PostDelayedTask( |
| 282 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) { | 249 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) { |
| 283 CHECK(task); | 250 CHECK(task); |
| 284 PendingTask pending_task( | 251 PendingTask pending_task( |
| 285 base::Bind(&TaskClosureAdapter::Run, | 252 base::Bind( |
| 286 new TaskClosureAdapter(task, &should_leak_tasks_)), | 253 &base::subtle::TaskClosureAdapter::Run, |
| 254 new base::subtle::TaskClosureAdapter(task, &should_leak_tasks_)), |
| 287 from_here, | 255 from_here, |
| 288 CalculateDelayedRuntime(delay_ms), true); | 256 CalculateDelayedRuntime(delay_ms), true); |
| 289 AddToIncomingQueue(&pending_task); | 257 AddToIncomingQueue(&pending_task); |
| 290 } | 258 } |
| 291 | 259 |
| 292 void MessageLoop::PostNonNestableTask( | 260 void MessageLoop::PostNonNestableTask( |
| 293 const tracked_objects::Location& from_here, Task* task) { | 261 const tracked_objects::Location& from_here, Task* task) { |
| 294 CHECK(task); | 262 CHECK(task); |
| 295 PendingTask pending_task( | 263 PendingTask pending_task( |
| 296 base::Bind(&TaskClosureAdapter::Run, | 264 base::Bind( |
| 297 new TaskClosureAdapter(task, &should_leak_tasks_)), | 265 &base::subtle::TaskClosureAdapter::Run, |
| 266 new base::subtle::TaskClosureAdapter(task, &should_leak_tasks_)), |
| 298 from_here, | 267 from_here, |
| 299 CalculateDelayedRuntime(0), false); | 268 CalculateDelayedRuntime(0), false); |
| 300 AddToIncomingQueue(&pending_task); | 269 AddToIncomingQueue(&pending_task); |
| 301 } | 270 } |
| 302 | 271 |
| 303 void MessageLoop::PostNonNestableDelayedTask( | 272 void MessageLoop::PostNonNestableDelayedTask( |
| 304 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) { | 273 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) { |
| 305 CHECK(task); | 274 CHECK(task); |
| 306 PendingTask pending_task( | 275 PendingTask pending_task( |
| 307 base::Bind(&TaskClosureAdapter::Run, | 276 base::Bind( |
| 308 new TaskClosureAdapter(task, &should_leak_tasks_)), | 277 &base::subtle::TaskClosureAdapter::Run, |
| 278 new base::subtle::TaskClosureAdapter(task, &should_leak_tasks_)), |
| 309 from_here, | 279 from_here, |
| 310 CalculateDelayedRuntime(delay_ms), false); | 280 CalculateDelayedRuntime(delay_ms), false); |
| 311 AddToIncomingQueue(&pending_task); | 281 AddToIncomingQueue(&pending_task); |
| 312 } | 282 } |
| 313 | 283 |
| 314 void MessageLoop::PostTask( | 284 void MessageLoop::PostTask( |
| 315 const tracked_objects::Location& from_here, const base::Closure& task) { | 285 const tracked_objects::Location& from_here, const base::Closure& task) { |
| 316 CHECK(!task.is_null()); | 286 CHECK(!task.is_null()); |
| 317 PendingTask pending_task(task, from_here, CalculateDelayedRuntime(0), true); | 287 PendingTask pending_task(task, from_here, CalculateDelayedRuntime(0), true); |
| 318 AddToIncomingQueue(&pending_task); | 288 AddToIncomingQueue(&pending_task); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 base::debug::Alias(&program_counter); | 449 base::debug::Alias(&program_counter); |
| 480 | 450 |
| 481 HistogramEvent(kTaskRunEvent); | 451 HistogramEvent(kTaskRunEvent); |
| 482 FOR_EACH_OBSERVER(TaskObserver, task_observers_, | 452 FOR_EACH_OBSERVER(TaskObserver, task_observers_, |
| 483 WillProcessTask(pending_task.time_posted)); | 453 WillProcessTask(pending_task.time_posted)); |
| 484 pending_task.task.Run(); | 454 pending_task.task.Run(); |
| 485 FOR_EACH_OBSERVER(TaskObserver, task_observers_, | 455 FOR_EACH_OBSERVER(TaskObserver, task_observers_, |
| 486 DidProcessTask(pending_task.time_posted)); | 456 DidProcessTask(pending_task.time_posted)); |
| 487 | 457 |
| 488 #if defined(TRACK_ALL_TASK_OBJECTS) | 458 #if defined(TRACK_ALL_TASK_OBJECTS) |
| 489 if (tracked_objects::ThreadData::IsActive() && pending_task.post_births) { | 459 tracked_objects::ThreadData::TallyADeathIfActive( |
| 490 tracked_objects::ThreadData::current()->TallyADeath( | 460 pending_task.post_births, |
| 491 *pending_task.post_births, | 461 TimeTicks::Now() - pending_task.time_posted); |
| 492 TimeTicks::Now() - pending_task.time_posted); | |
| 493 } | |
| 494 #endif // defined(TRACK_ALL_TASK_OBJECTS) | 462 #endif // defined(TRACK_ALL_TASK_OBJECTS) |
| 495 | 463 |
| 496 nestable_tasks_allowed_ = true; | 464 nestable_tasks_allowed_ = true; |
| 497 } | 465 } |
| 498 | 466 |
| 499 bool MessageLoop::DeferOrRunPendingTask( | 467 bool MessageLoop::DeferOrRunPendingTask( |
| 500 const PendingTask& pending_task) { | 468 const PendingTask& pending_task) { |
| 501 if (pending_task.nestable || state_->run_depth == 1) { | 469 if (pending_task.nestable || state_->run_depth == 1) { |
| 502 RunTask(pending_task); | 470 RunTask(pending_task); |
| 503 // Show that we ran a task (Note: a new one might arrive as a | 471 // Show that we ran a task (Note: a new one might arrive as a |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 const tracked_objects::Location& posted_from, | 741 const tracked_objects::Location& posted_from, |
| 774 TimeTicks delayed_run_time, | 742 TimeTicks delayed_run_time, |
| 775 bool nestable) | 743 bool nestable) |
| 776 : task(task), | 744 : task(task), |
| 777 time_posted(TimeTicks::Now()), | 745 time_posted(TimeTicks::Now()), |
| 778 delayed_run_time(delayed_run_time), | 746 delayed_run_time(delayed_run_time), |
| 779 sequence_num(0), | 747 sequence_num(0), |
| 780 nestable(nestable), | 748 nestable(nestable), |
| 781 birth_program_counter(posted_from.program_counter()) { | 749 birth_program_counter(posted_from.program_counter()) { |
| 782 #if defined(TRACK_ALL_TASK_OBJECTS) | 750 #if defined(TRACK_ALL_TASK_OBJECTS) |
| 783 if (tracked_objects::ThreadData::IsActive()) { | 751 post_births = tracked_objects::ThreadData::TallyABirthIfActive(posted_from); |
| 784 tracked_objects::ThreadData* current_thread_data = | |
| 785 tracked_objects::ThreadData::current(); | |
| 786 if (current_thread_data) { | |
| 787 post_births = current_thread_data->TallyABirth(posted_from); | |
| 788 } else { | |
| 789 // Shutdown started, and this thread wasn't registered. | |
| 790 post_births = NULL; | |
| 791 } | |
| 792 } | |
| 793 #endif // defined(TRACK_ALL_TASK_OBJECTS) | 752 #endif // defined(TRACK_ALL_TASK_OBJECTS) |
| 794 } | 753 } |
| 795 | 754 |
| 796 MessageLoop::PendingTask::~PendingTask() { | 755 MessageLoop::PendingTask::~PendingTask() { |
| 797 } | 756 } |
| 798 | 757 |
| 799 bool MessageLoop::PendingTask::operator<(const PendingTask& other) const { | 758 bool MessageLoop::PendingTask::operator<(const PendingTask& other) const { |
| 800 // Since the top of a priority queue is defined as the "greatest" element, we | 759 // Since the top of a priority queue is defined as the "greatest" element, we |
| 801 // need to invert the comparison here. We want the smaller time to be at the | 760 // need to invert the comparison here. We want the smaller time to be at the |
| 802 // top of the heap. | 761 // top of the heap. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 Watcher *delegate) { | 824 Watcher *delegate) { |
| 866 return pump_libevent()->WatchFileDescriptor( | 825 return pump_libevent()->WatchFileDescriptor( |
| 867 fd, | 826 fd, |
| 868 persistent, | 827 persistent, |
| 869 static_cast<base::MessagePumpLibevent::Mode>(mode), | 828 static_cast<base::MessagePumpLibevent::Mode>(mode), |
| 870 controller, | 829 controller, |
| 871 delegate); | 830 delegate); |
| 872 } | 831 } |
| 873 | 832 |
| 874 #endif | 833 #endif |
| OLD | NEW |