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 #ifndef BASE_MESSAGE_LOOP_H_ | 5 #ifndef BASE_MESSAGE_LOOP_H_ |
6 #define BASE_MESSAGE_LOOP_H_ | 6 #define BASE_MESSAGE_LOOP_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <queue> | 9 #include <queue> |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/callback.h" |
13 #include "base/message_pump.h" | 14 #include "base/message_pump.h" |
14 #include "base/observer_list.h" | 15 #include "base/observer_list.h" |
15 #include "base/ref_counted.h" | 16 #include "base/ref_counted.h" |
16 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
17 #include "base/task.h" | 18 #include "base/task.h" |
| 19 #include "base/time.h" |
| 20 #include "base/tracked.h" |
18 | 21 |
19 #if defined(OS_WIN) | 22 #if defined(OS_WIN) |
20 // We need this to declare base::MessagePumpWin::Dispatcher, which we should | 23 // We need this to declare base::MessagePumpWin::Dispatcher, which we should |
21 // really just eliminate. | 24 // really just eliminate. |
22 #include "base/message_pump_win.h" | 25 #include "base/message_pump_win.h" |
23 #elif defined(OS_POSIX) | 26 #elif defined(OS_POSIX) |
24 #include "base/message_pump_libevent.h" | 27 #include "base/message_pump_libevent.h" |
25 #if !defined(OS_MACOSX) | 28 #if !defined(OS_MACOSX) |
26 #include "base/message_pump_glib.h" | 29 #include "base/message_pump_glib.h" |
27 typedef struct _XDisplay Display; | 30 typedef struct _XDisplay Display; |
28 #endif | 31 #endif |
29 #endif | 32 #endif |
30 #if defined(TOUCH_UI) | 33 #if defined(TOUCH_UI) |
31 #include "base/message_pump_glib_x_dispatch.h" | 34 #include "base/message_pump_glib_x_dispatch.h" |
32 #endif | 35 #endif |
33 | 36 |
34 namespace base { | 37 namespace base { |
35 class Histogram; | 38 class Histogram; |
36 } | 39 } |
37 | 40 |
| 41 #if defined(TRACK_ALL_TASK_OBJECTS) |
| 42 namespace tracked_objects { |
| 43 class Births; |
| 44 } |
| 45 #endif // defined(TRACK_ALL_TASK_OBJECTS) |
| 46 |
38 // A MessageLoop is used to process events for a particular thread. There is | 47 // A MessageLoop is used to process events for a particular thread. There is |
39 // at most one MessageLoop instance per thread. | 48 // at most one MessageLoop instance per thread. |
40 // | 49 // |
41 // Events include at a minimum Task instances submitted to PostTask or those | 50 // Events include at a minimum Task instances submitted to PostTask or those |
42 // managed by TimerManager. Depending on the type of message pump used by the | 51 // managed by TimerManager. Depending on the type of message pump used by the |
43 // MessageLoop other events such as UI messages may be processed. On Windows | 52 // MessageLoop other events such as UI messages may be processed. On Windows |
44 // APC calls (as time permits) and signals sent to a registered set of HANDLEs | 53 // APC calls (as time permits) and signals sent to a registered set of HANDLEs |
45 // may also be processed. | 54 // may also be processed. |
46 // | 55 // |
47 // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called | 56 // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 164 |
156 void PostDelayedTask( | 165 void PostDelayedTask( |
157 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); | 166 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); |
158 | 167 |
159 void PostNonNestableTask( | 168 void PostNonNestableTask( |
160 const tracked_objects::Location& from_here, Task* task); | 169 const tracked_objects::Location& from_here, Task* task); |
161 | 170 |
162 void PostNonNestableDelayedTask( | 171 void PostNonNestableDelayedTask( |
163 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); | 172 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); |
164 | 173 |
| 174 void PostClosure( |
| 175 const tracked_objects::Location& from_here, |
| 176 const base::Closure& closure); |
| 177 |
| 178 void PostDelayedClosure( |
| 179 const tracked_objects::Location& from_here, |
| 180 const base::Closure& closure, int64 delay_ms); |
| 181 |
| 182 void PostNonNestableClosure( |
| 183 const tracked_objects::Location& from_here, |
| 184 const base::Closure& closure); |
| 185 |
| 186 void PostNonNestableDelayedClosure( |
| 187 const tracked_objects::Location& from_here, |
| 188 const base::Closure& closure, int64 delay_ms); |
| 189 |
165 // A variant on PostTask that deletes the given object. This is useful | 190 // A variant on PostTask that deletes the given object. This is useful |
166 // if the object needs to live until the next run of the MessageLoop (for | 191 // if the object needs to live until the next run of the MessageLoop (for |
167 // example, deleting a RenderProcessHost from within an IPC callback is not | 192 // example, deleting a RenderProcessHost from within an IPC callback is not |
168 // good). | 193 // good). |
169 // | 194 // |
170 // NOTE: This method may be called on any thread. The object will be deleted | 195 // NOTE: This method may be called on any thread. The object will be deleted |
171 // on the thread that executes MessageLoop::Run(). If this is not the same | 196 // on the thread that executes MessageLoop::Run(). If this is not the same |
172 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit | 197 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit |
173 // from RefCountedThreadSafe<T>! | 198 // from RefCountedThreadSafe<T>! |
174 template <class T> | 199 template <class T> |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 // exception filter that was active when Run() was called. This can happen | 297 // exception filter that was active when Run() was called. This can happen |
273 // if some third party code call SetUnhandledExceptionFilter() and never | 298 // if some third party code call SetUnhandledExceptionFilter() and never |
274 // restores the previous filter. | 299 // restores the previous filter. |
275 void set_exception_restoration(bool restore) { | 300 void set_exception_restoration(bool restore) { |
276 exception_restoration_ = restore; | 301 exception_restoration_ = restore; |
277 } | 302 } |
278 | 303 |
279 // Returns true if we are currently running a nested message loop. | 304 // Returns true if we are currently running a nested message loop. |
280 bool IsNested(); | 305 bool IsNested(); |
281 | 306 |
282 // A TaskObserver is an object that receives task notifications from the | 307 // A ClosureObserver is an object that receives task notifications from the |
283 // MessageLoop. | 308 // MessageLoop. |
284 // | 309 // |
285 // NOTE: A TaskObserver implementation should be extremely fast! | 310 // NOTE: A ClosureObserver implementation should be extremely fast! |
286 class TaskObserver { | 311 class ClosureObserver { |
287 public: | 312 public: |
288 TaskObserver(); | 313 ClosureObserver(); |
289 | 314 |
290 // This method is called before processing a task. | 315 // This method is called before processing a task. |
291 virtual void WillProcessTask(const Task* task) = 0; | 316 virtual void WillProcessClosure(base::TimeTicks time_posted) = 0; |
292 | 317 |
293 // This method is called after processing a task. | 318 // This method is called after processing a task. |
294 virtual void DidProcessTask(const Task* task) = 0; | 319 virtual void DidProcessClosure(base::TimeTicks time_posted) = 0; |
295 | 320 |
296 protected: | 321 protected: |
297 virtual ~TaskObserver(); | 322 virtual ~ClosureObserver(); |
298 }; | 323 }; |
299 | 324 |
300 // These functions can only be called on the same thread that |this| is | 325 // These functions can only be called on the same thread that |this| is |
301 // running on. | 326 // running on. |
302 void AddTaskObserver(TaskObserver* task_observer); | 327 void AddClosureObserver(ClosureObserver* closure_observer); |
303 void RemoveTaskObserver(TaskObserver* task_observer); | 328 void RemoveClosureObserver(ClosureObserver* closure_observer); |
304 | 329 |
305 // Returns true if the message loop has high resolution timers enabled. | 330 // Returns true if the message loop has high resolution timers enabled. |
306 // Provided for testing. | 331 // Provided for testing. |
307 bool high_resolution_timers_enabled() { | 332 bool high_resolution_timers_enabled() { |
308 #if defined(OS_WIN) | 333 #if defined(OS_WIN) |
309 return !high_resolution_timer_expiration_.is_null(); | 334 return !high_resolution_timer_expiration_.is_null(); |
310 #else | 335 #else |
311 return true; | 336 return true; |
312 #endif | 337 #endif |
313 } | 338 } |
(...skipping 23 matching lines...) Expand all Loading... |
337 class AutoRunState : RunState { | 362 class AutoRunState : RunState { |
338 public: | 363 public: |
339 explicit AutoRunState(MessageLoop* loop); | 364 explicit AutoRunState(MessageLoop* loop); |
340 ~AutoRunState(); | 365 ~AutoRunState(); |
341 private: | 366 private: |
342 MessageLoop* loop_; | 367 MessageLoop* loop_; |
343 RunState* previous_state_; | 368 RunState* previous_state_; |
344 }; | 369 }; |
345 | 370 |
346 // This structure is copied around by value. | 371 // This structure is copied around by value. |
347 struct PendingTask { | 372 struct PendingClosure { |
348 PendingTask(Task* task, bool nestable) | 373 PendingClosure(const base::Closure& closure, |
349 : task(task), sequence_num(0), nestable(nestable) { | 374 const tracked_objects::Location& posted_from, |
350 } | 375 base::TimeTicks delayed_run_time, |
| 376 bool nestable); |
351 | 377 |
352 // Used to support sorting. | 378 // Used to support sorting. |
353 bool operator<(const PendingTask& other) const; | 379 bool operator<(const PendingClosure& other) const; |
354 | 380 |
355 Task* task; // The task to run. | 381 // The Closure to run. |
356 base::TimeTicks delayed_run_time; // The time when the task should be run. | 382 base::Closure closure; |
357 int sequence_num; // Secondary sort key for run time. | 383 |
358 bool nestable; // OK to dispatch from a nested loop. | 384 #if defined(TRACK_ALL_TASK_OBJECTS) |
| 385 // Counter for location where the Closure was posted from. |
| 386 tracked_objects::Births* post_births; |
| 387 #endif // defined(TRACK_ALL_TASK_OBJECTS) |
| 388 |
| 389 // Time this PendingClosure was posted. |
| 390 base::TimeTicks time_posted; |
| 391 |
| 392 // The time when the task should be run. |
| 393 base::TimeTicks delayed_run_time; |
| 394 |
| 395 // Secondary sort key for run time. |
| 396 int sequence_num; |
| 397 |
| 398 // OK to dispatch from a nested loop. |
| 399 bool nestable; |
359 }; | 400 }; |
360 | 401 |
361 class TaskQueue : public std::queue<PendingTask> { | 402 class TaskQueue : public std::queue<PendingClosure> { |
362 public: | 403 public: |
363 void Swap(TaskQueue* queue) { | 404 void Swap(TaskQueue* queue) { |
364 c.swap(queue->c); // Calls std::deque::swap | 405 c.swap(queue->c); // Calls std::deque::swap |
365 } | 406 } |
366 }; | 407 }; |
367 | 408 |
368 typedef std::priority_queue<PendingTask> DelayedTaskQueue; | 409 typedef std::priority_queue<PendingClosure> DelayedTaskQueue; |
369 | 410 |
370 #if defined(OS_WIN) | 411 #if defined(OS_WIN) |
371 base::MessagePumpWin* pump_win() { | 412 base::MessagePumpWin* pump_win() { |
372 return static_cast<base::MessagePumpWin*>(pump_.get()); | 413 return static_cast<base::MessagePumpWin*>(pump_.get()); |
373 } | 414 } |
374 #elif defined(OS_POSIX) | 415 #elif defined(OS_POSIX) |
375 base::MessagePumpLibevent* pump_libevent() { | 416 base::MessagePumpLibevent* pump_libevent() { |
376 return static_cast<base::MessagePumpLibevent*>(pump_.get()); | 417 return static_cast<base::MessagePumpLibevent*>(pump_.get()); |
377 } | 418 } |
378 #endif | 419 #endif |
379 | 420 |
380 // A function to encapsulate all the exception handling capability in the | 421 // A function to encapsulate all the exception handling capability in the |
381 // stacks around the running of a main message loop. It will run the message | 422 // stacks around the running of a main message loop. It will run the message |
382 // loop in a SEH try block or not depending on the set_SEH_restoration() | 423 // loop in a SEH try block or not depending on the set_SEH_restoration() |
383 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). | 424 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). |
384 void RunHandler(); | 425 void RunHandler(); |
385 | 426 |
386 #if defined(OS_WIN) | 427 #if defined(OS_WIN) |
387 __declspec(noinline) void RunInternalInSEHFrame(); | 428 __declspec(noinline) void RunInternalInSEHFrame(); |
388 #endif | 429 #endif |
389 | 430 |
390 // A surrounding stack frame around the running of the message loop that | 431 // A surrounding stack frame around the running of the message loop that |
391 // supports all saving and restoring of state, as is needed for any/all (ugly) | 432 // supports all saving and restoring of state, as is needed for any/all (ugly) |
392 // recursive calls. | 433 // recursive calls. |
393 void RunInternal(); | 434 void RunInternal(); |
394 | 435 |
395 // Called to process any delayed non-nestable tasks. | 436 // Called to process any delayed non-nestable tasks. |
396 bool ProcessNextDelayedNonNestableTask(); | 437 bool ProcessNextDelayedNonNestableTask(); |
397 | 438 |
398 // Runs the specified task and deletes it. | 439 // Runs the specified PendingClosure. |
399 void RunTask(Task* task); | 440 void RunClosure(const PendingClosure& closure); |
400 | 441 |
401 // Calls RunTask or queues the pending_task on the deferred task list if it | 442 // Calls RunTask or queues the pending_closure on the deferred task list if it |
402 // cannot be run right now. Returns true if the task was run. | 443 // cannot be run right now. Returns true if the task was run. |
403 bool DeferOrRunPendingTask(const PendingTask& pending_task); | 444 bool DeferOrRunPendingClosure(const PendingClosure& pending_closure); |
404 | 445 |
405 // Adds the pending task to delayed_work_queue_. | 446 // Adds the pending task to delayed_work_queue_. |
406 void AddToDelayedWorkQueue(const PendingTask& pending_task); | 447 void AddToDelayedWorkQueue(const PendingClosure& pending_closure); |
| 448 |
| 449 // Adds the pending task to our incoming_queue_. |
| 450 // Caller retains ownership of |pending_closure|, but this function will |
| 451 // reset the value of pending_closure->closure. |
| 452 void AddToIncomingQueue(PendingClosure* pending_closure); |
407 | 453 |
408 // Load tasks from the incoming_queue_ into work_queue_ if the latter is | 454 // Load tasks from the incoming_queue_ into work_queue_ if the latter is |
409 // empty. The former requires a lock to access, while the latter is directly | 455 // empty. The former requires a lock to access, while the latter is directly |
410 // accessible on this thread. | 456 // accessible on this thread. |
411 void ReloadWorkQueue(); | 457 void ReloadWorkQueue(); |
412 | 458 |
413 // Delete tasks that haven't run yet without running them. Used in the | 459 // Delete tasks that haven't run yet without running them. Used in the |
414 // destructor to make sure all the task's destructors get called. Returns | 460 // destructor to make sure all the task's destructors get called. Returns |
415 // true if some work was done. | 461 // true if some work was done. |
416 bool DeletePendingTasks(); | 462 bool DeletePendingClosures(); |
417 | 463 |
418 // Post a task to our incomming queue. | 464 // Calcuates the time at which a PendingClosure should run. |
419 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, | 465 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms); |
420 int64 delay_ms, bool nestable); | |
421 | 466 |
422 // Start recording histogram info about events and action IF it was enabled | 467 // Start recording histogram info about events and action IF it was enabled |
423 // and IF the statistics recorder can accept a registration of our histogram. | 468 // and IF the statistics recorder can accept a registration of our histogram. |
424 void StartHistogrammer(); | 469 void StartHistogrammer(); |
425 | 470 |
426 // Add occurence of event to our histogram, so that we can see what is being | 471 // Add occurence of event to our histogram, so that we can see what is being |
427 // done in a specific MessageLoop instance (i.e., specific thread). | 472 // done in a specific MessageLoop instance (i.e., specific thread). |
428 // If message_histogram_ is NULL, this is a no-op. | 473 // If message_histogram_ is NULL, this is a no-op. |
429 void HistogramEvent(int event); | 474 void HistogramEvent(int event); |
430 | 475 |
(...skipping 28 matching lines...) Expand all Loading... |
459 bool nestable_tasks_allowed_; | 504 bool nestable_tasks_allowed_; |
460 | 505 |
461 bool exception_restoration_; | 506 bool exception_restoration_; |
462 | 507 |
463 std::string thread_name_; | 508 std::string thread_name_; |
464 // A profiling histogram showing the counts of various messages and events. | 509 // A profiling histogram showing the counts of various messages and events. |
465 scoped_refptr<base::Histogram> message_histogram_; | 510 scoped_refptr<base::Histogram> message_histogram_; |
466 | 511 |
467 // A null terminated list which creates an incoming_queue of tasks that are | 512 // A null terminated list which creates an incoming_queue of tasks that are |
468 // acquired under a mutex for processing on this instance's thread. These | 513 // acquired under a mutex for processing on this instance's thread. These |
469 // tasks have not yet been sorted out into items for our work_queue_ vs | 514 // tasks have not yet been sorted out into items for our work_queue_ vs items |
470 // items that will be handled by the TimerManager. | 515 // that will be handled by the TimerManager. |
471 TaskQueue incoming_queue_; | 516 TaskQueue incoming_queue_; |
472 // Protect access to incoming_queue_. | 517 // Protect access to incoming_queue_. |
473 mutable base::Lock incoming_queue_lock_; | 518 mutable base::Lock incoming_queue_lock_; |
474 | 519 |
475 RunState* state_; | 520 RunState* state_; |
476 | 521 |
| 522 bool should_leak_tasks_; |
| 523 |
477 #if defined(OS_WIN) | 524 #if defined(OS_WIN) |
478 base::TimeTicks high_resolution_timer_expiration_; | 525 base::TimeTicks high_resolution_timer_expiration_; |
479 #endif | 526 #endif |
480 | 527 |
481 // The next sequence number to use for delayed tasks. | 528 // The next sequence number to use for delayed tasks. |
482 int next_sequence_num_; | 529 int next_sequence_num_; |
483 | 530 |
484 ObserverList<TaskObserver> task_observers_; | 531 ObserverList<ClosureObserver> closure_observers_; |
485 | 532 |
486 DISALLOW_COPY_AND_ASSIGN(MessageLoop); | 533 DISALLOW_COPY_AND_ASSIGN(MessageLoop); |
487 }; | 534 }; |
488 | 535 |
489 //----------------------------------------------------------------------------- | 536 //----------------------------------------------------------------------------- |
490 // MessageLoopForUI extends MessageLoop with methods that are particular to a | 537 // MessageLoopForUI extends MessageLoop with methods that are particular to a |
491 // MessageLoop instantiated with TYPE_UI. | 538 // MessageLoop instantiated with TYPE_UI. |
492 // | 539 // |
493 // This class is typically used like so: | 540 // This class is typically used like so: |
494 // MessageLoopForUI::current()->...call some method... | 541 // MessageLoopForUI::current()->...call some method... |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 #endif // defined(OS_POSIX) | 660 #endif // defined(OS_POSIX) |
614 }; | 661 }; |
615 | 662 |
616 // Do not add any member variables to MessageLoopForIO! This is important b/c | 663 // Do not add any member variables to MessageLoopForIO! This is important b/c |
617 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 664 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
618 // data that you need should be stored on the MessageLoop's pump_ instance. | 665 // data that you need should be stored on the MessageLoop's pump_ instance. |
619 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 666 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
620 MessageLoopForIO_should_not_have_extra_member_variables); | 667 MessageLoopForIO_should_not_have_extra_member_variables); |
621 | 668 |
622 #endif // BASE_MESSAGE_LOOP_H_ | 669 #endif // BASE_MESSAGE_LOOP_H_ |
OLD | NEW |