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

Side by Side Diff: base/message_loop.cc

Issue 7316015: Support Closure in ALL the loops! (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: I AM NOT A NUMBER TO BE TALLIED (remove all object tracking for right now). Created 9 years, 5 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 | « no previous file | base/message_loop_proxy.h » ('j') | base/task.h » ('J')
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 #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
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
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_)),
willchan no longer on Chromium 2011/07/10 16:47:33 I was looking at the refcounted nature of TaskClos
awong 2011/07/14 23:03:30 I'm not quite sure how this would work. The reaso
willchan no longer on Chromium 2011/07/19 12:18:26 I started writing out how this would work, but the
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | base/message_loop_proxy.h » ('j') | base/task.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698