OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 | 7 |
8 #include <queue> | 8 #include <queue> |
9 #include <string> | 9 #include <string> |
10 | 10 |
| 11 #include "base/basictypes.h" |
11 #include "base/histogram.h" | 12 #include "base/histogram.h" |
12 #include "base/message_pump.h" | 13 #include "base/message_pump.h" |
13 #include "base/observer_list.h" | 14 #include "base/observer_list.h" |
14 #include "base/ref_counted.h" | 15 #include "base/ref_counted.h" |
15 #include "base/scoped_ptr.h" | 16 #include "base/scoped_ptr.h" |
16 #include "base/task.h" | 17 #include "base/task.h" |
17 | 18 |
18 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
19 // We need this to declare base::MessagePumpWin::Dispatcher, which we should | 20 // We need this to declare base::MessagePumpWin::Dispatcher, which we should |
20 // really just eliminate. | 21 // really just eliminate. |
(...skipping 30 matching lines...) Expand all Loading... |
51 // MessageLoop::current()->SetNestableTasksAllowed(true); | 52 // MessageLoop::current()->SetNestableTasksAllowed(true); |
52 // HRESULT hr = DoDragDrop(...); // Implicitly runs a modal message loop here. | 53 // HRESULT hr = DoDragDrop(...); // Implicitly runs a modal message loop here. |
53 // MessageLoop::current()->SetNestableTasksAllowed(old_state); | 54 // MessageLoop::current()->SetNestableTasksAllowed(old_state); |
54 // // Process hr (the result returned by DoDragDrop(). | 55 // // Process hr (the result returned by DoDragDrop(). |
55 // | 56 // |
56 // Please be SURE your task is reentrant (nestable) and all global variables | 57 // Please be SURE your task is reentrant (nestable) and all global variables |
57 // are stable and accessible before calling SetNestableTasksAllowed(true). | 58 // are stable and accessible before calling SetNestableTasksAllowed(true). |
58 // | 59 // |
59 class MessageLoop : public base::MessagePump::Delegate { | 60 class MessageLoop : public base::MessagePump::Delegate { |
60 public: | 61 public: |
| 62 // A TaskObserver is an object that receives task notifications from the |
| 63 // MessageLoop. |
| 64 // |
| 65 // NOTE: A TaskObserver implementation should be extremely fast! |
| 66 class TaskObserver { |
| 67 public: |
| 68 TaskObserver() {} |
| 69 |
| 70 // This method is called before processing a task. |
| 71 virtual void WillProcessTask(base::TimeTicks birth_time) = 0; |
| 72 |
| 73 // This method is called after processing a task. |
| 74 virtual void DidProcessTask() = 0; |
| 75 |
| 76 protected: |
| 77 virtual ~TaskObserver() {} |
| 78 }; |
| 79 |
61 static void EnableHistogrammer(bool enable_histogrammer); | 80 static void EnableHistogrammer(bool enable_histogrammer); |
62 | 81 |
63 // A DestructionObserver is notified when the current MessageLoop is being | 82 // A DestructionObserver is notified when the current MessageLoop is being |
64 // destroyed. These obsevers are notified prior to MessageLoop::current() | 83 // destroyed. These obsevers are notified prior to MessageLoop::current() |
65 // being changed to return NULL. This gives interested parties the chance to | 84 // being changed to return NULL. This gives interested parties the chance to |
66 // do final cleanup that depends on the MessageLoop. | 85 // do final cleanup that depends on the MessageLoop. |
67 // | 86 // |
68 // NOTE: Any tasks posted to the MessageLoop during this notification will | 87 // NOTE: Any tasks posted to the MessageLoop during this notification will |
69 // not be run. Instead, they will be deleted. | 88 // not be run. Instead, they will be deleted. |
70 // | 89 // |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 // exception filter that was active when Run() was called. This can happen | 267 // exception filter that was active when Run() was called. This can happen |
249 // if some third party code call SetUnhandledExceptionFilter() and never | 268 // if some third party code call SetUnhandledExceptionFilter() and never |
250 // restores the previous filter. | 269 // restores the previous filter. |
251 void set_exception_restoration(bool restore) { | 270 void set_exception_restoration(bool restore) { |
252 exception_restoration_ = restore; | 271 exception_restoration_ = restore; |
253 } | 272 } |
254 | 273 |
255 // Returns true if we are currently running a nested message loop. | 274 // Returns true if we are currently running a nested message loop. |
256 bool IsNested(); | 275 bool IsNested(); |
257 | 276 |
| 277 // These functions can only be called on the same thread that |this| is |
| 278 // running on. |
| 279 void AddTaskObserver(TaskObserver* task_observer); |
| 280 void RemoveTaskObserver(TaskObserver* task_observer); |
| 281 |
258 #if defined(OS_WIN) | 282 #if defined(OS_WIN) |
259 typedef base::MessagePumpWin::Dispatcher Dispatcher; | 283 typedef base::MessagePumpWin::Dispatcher Dispatcher; |
260 typedef base::MessagePumpWin::Observer Observer; | 284 typedef base::MessagePumpForUI::Observer Observer; |
261 #elif !defined(OS_MACOSX) | 285 #elif !defined(OS_MACOSX) |
262 typedef base::MessagePumpForUI::Dispatcher Dispatcher; | 286 typedef base::MessagePumpForUI::Dispatcher Dispatcher; |
263 typedef base::MessagePumpForUI::Observer Observer; | 287 typedef base::MessagePumpForUI::Observer Observer; |
264 #endif | 288 #endif |
265 | 289 |
266 //---------------------------------------------------------------------------- | 290 //---------------------------------------------------------------------------- |
267 protected: | 291 protected: |
268 struct RunState { | 292 struct RunState { |
269 // Used to count how many Run() invocations are on the stack. | 293 // Used to count how many Run() invocations are on the stack. |
270 int run_depth; | 294 int run_depth; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 // will be handled by the TimerManager. | 450 // will be handled by the TimerManager. |
427 TaskQueue incoming_queue_; | 451 TaskQueue incoming_queue_; |
428 // Protect access to incoming_queue_. | 452 // Protect access to incoming_queue_. |
429 Lock incoming_queue_lock_; | 453 Lock incoming_queue_lock_; |
430 | 454 |
431 RunState* state_; | 455 RunState* state_; |
432 | 456 |
433 // The next sequence number to use for delayed tasks. | 457 // The next sequence number to use for delayed tasks. |
434 int next_sequence_num_; | 458 int next_sequence_num_; |
435 | 459 |
| 460 ObserverList<TaskObserver> task_observers_; |
| 461 |
436 DISALLOW_COPY_AND_ASSIGN(MessageLoop); | 462 DISALLOW_COPY_AND_ASSIGN(MessageLoop); |
437 }; | 463 }; |
438 | 464 |
439 //----------------------------------------------------------------------------- | 465 //----------------------------------------------------------------------------- |
440 // MessageLoopForUI extends MessageLoop with methods that are particular to a | 466 // MessageLoopForUI extends MessageLoop with methods that are particular to a |
441 // MessageLoop instantiated with TYPE_UI. | 467 // MessageLoop instantiated with TYPE_UI. |
442 // | 468 // |
443 // This class is typically used like so: | 469 // This class is typically used like so: |
444 // MessageLoopForUI::current()->...call some method... | 470 // MessageLoopForUI::current()->...call some method... |
445 // | 471 // |
446 class MessageLoopForUI : public MessageLoop { | 472 class MessageLoopForUI : public MessageLoop { |
447 public: | 473 public: |
448 MessageLoopForUI() : MessageLoop(TYPE_UI) { | 474 MessageLoopForUI() : MessageLoop(TYPE_UI) { |
449 } | 475 } |
450 | 476 |
451 // Returns the MessageLoopForUI of the current thread. | 477 // Returns the MessageLoopForUI of the current thread. |
452 static MessageLoopForUI* current() { | 478 static MessageLoopForUI* current() { |
453 MessageLoop* loop = MessageLoop::current(); | 479 MessageLoop* loop = MessageLoop::current(); |
454 DCHECK_EQ(MessageLoop::TYPE_UI, loop->type()); | 480 DCHECK_EQ(MessageLoop::TYPE_UI, loop->type()); |
455 return static_cast<MessageLoopForUI*>(loop); | 481 return static_cast<MessageLoopForUI*>(loop); |
456 } | 482 } |
457 | 483 |
458 #if defined(OS_WIN) | 484 #if defined(OS_WIN) |
459 void WillProcessMessage(const MSG& message); | |
460 void DidProcessMessage(const MSG& message); | 485 void DidProcessMessage(const MSG& message); |
461 void PumpOutPendingPaintMessages(); | 486 #endif // defined(OS_WIN) |
462 #endif | |
463 | 487 |
464 #if !defined(OS_MACOSX) | 488 #if !defined(OS_MACOSX) |
465 // Please see message_pump_win/message_pump_glib for definitions of these | 489 // Please see message_pump_win/message_pump_glib for definitions of these |
466 // methods. | 490 // methods. |
467 void AddObserver(Observer* observer); | 491 void AddObserver(Observer* observer); |
468 void RemoveObserver(Observer* observer); | 492 void RemoveObserver(Observer* observer); |
469 void Run(Dispatcher* dispatcher); | 493 void Run(Dispatcher* dispatcher); |
470 | 494 |
471 protected: | 495 protected: |
472 // TODO(rvargas): Make this platform independent. | 496 // TODO(rvargas): Make this platform independent. |
473 base::MessagePumpForUI* pump_ui() { | 497 base::MessagePumpForUI* pump_ui() { |
474 return static_cast<base::MessagePumpForUI*>(pump_.get()); | 498 return static_cast<base::MessagePumpForUI*>(pump_.get()); |
475 } | 499 } |
476 #endif // defined(OS_MACOSX) | 500 #endif // !defined(OS_MACOSX) |
477 }; | 501 }; |
478 | 502 |
479 // Do not add any member variables to MessageLoopForUI! This is important b/c | 503 // Do not add any member variables to MessageLoopForUI! This is important b/c |
480 // MessageLoopForUI is often allocated via MessageLoop(TYPE_UI). Any extra | 504 // MessageLoopForUI is often allocated via MessageLoop(TYPE_UI). Any extra |
481 // data that you need should be stored on the MessageLoop's pump_ instance. | 505 // data that you need should be stored on the MessageLoop's pump_ instance. |
482 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI), | 506 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI), |
483 MessageLoopForUI_should_not_have_extra_member_variables); | 507 MessageLoopForUI_should_not_have_extra_member_variables); |
484 | 508 |
485 //----------------------------------------------------------------------------- | 509 //----------------------------------------------------------------------------- |
486 // MessageLoopForIO extends MessageLoop with methods that are particular to a | 510 // MessageLoopForIO extends MessageLoop with methods that are particular to a |
487 // MessageLoop instantiated with TYPE_IO. | 511 // MessageLoop instantiated with TYPE_IO. |
488 // | 512 // |
489 // This class is typically used like so: | 513 // This class is typically used like so: |
490 // MessageLoopForIO::current()->...call some method... | 514 // MessageLoopForIO::current()->...call some method... |
491 // | 515 // |
492 class MessageLoopForIO : public MessageLoop { | 516 class MessageLoopForIO : public MessageLoop { |
493 public: | 517 public: |
| 518 #if defined(OS_WIN) |
| 519 typedef base::MessagePumpForIO::IOHandler IOHandler; |
| 520 typedef base::MessagePumpForIO::IOContext IOContext; |
| 521 typedef base::MessagePumpForIO::IOObserver IOObserver; |
| 522 #elif defined(OS_POSIX) |
| 523 typedef base::MessagePumpLibevent::Watcher Watcher; |
| 524 typedef base::MessagePumpLibevent::FileDescriptorWatcher |
| 525 FileDescriptorWatcher; |
| 526 typedef base::MessagePumpLibevent::IOObserver IOObserver; |
| 527 |
| 528 enum Mode { |
| 529 WATCH_READ = base::MessagePumpLibevent::WATCH_READ, |
| 530 WATCH_WRITE = base::MessagePumpLibevent::WATCH_WRITE, |
| 531 WATCH_READ_WRITE = base::MessagePumpLibevent::WATCH_READ_WRITE |
| 532 }; |
| 533 |
| 534 #endif |
| 535 |
494 MessageLoopForIO() : MessageLoop(TYPE_IO) { | 536 MessageLoopForIO() : MessageLoop(TYPE_IO) { |
495 } | 537 } |
496 | 538 |
497 // Returns the MessageLoopForIO of the current thread. | 539 // Returns the MessageLoopForIO of the current thread. |
498 static MessageLoopForIO* current() { | 540 static MessageLoopForIO* current() { |
499 MessageLoop* loop = MessageLoop::current(); | 541 MessageLoop* loop = MessageLoop::current(); |
500 DCHECK_EQ(MessageLoop::TYPE_IO, loop->type()); | 542 DCHECK_EQ(MessageLoop::TYPE_IO, loop->type()); |
501 return static_cast<MessageLoopForIO*>(loop); | 543 return static_cast<MessageLoopForIO*>(loop); |
502 } | 544 } |
503 | 545 |
| 546 void AddIOObserver(IOObserver* io_observer) { |
| 547 pump_io()->AddIOObserver(io_observer); |
| 548 } |
| 549 |
| 550 void RemoveIOObserver(IOObserver* io_observer) { |
| 551 pump_io()->RemoveIOObserver(io_observer); |
| 552 } |
| 553 |
504 #if defined(OS_WIN) | 554 #if defined(OS_WIN) |
505 typedef base::MessagePumpForIO::IOHandler IOHandler; | |
506 typedef base::MessagePumpForIO::IOContext IOContext; | |
507 | |
508 // Please see MessagePumpWin for definitions of these methods. | 555 // Please see MessagePumpWin for definitions of these methods. |
509 void RegisterIOHandler(HANDLE file_handle, IOHandler* handler); | 556 void RegisterIOHandler(HANDLE file_handle, IOHandler* handler); |
510 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter); | 557 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter); |
511 | 558 |
512 protected: | 559 protected: |
513 // TODO(rvargas): Make this platform independent. | 560 // TODO(rvargas): Make this platform independent. |
514 base::MessagePumpForIO* pump_io() { | 561 base::MessagePumpForIO* pump_io() { |
515 return static_cast<base::MessagePumpForIO*>(pump_.get()); | 562 return static_cast<base::MessagePumpForIO*>(pump_.get()); |
516 } | 563 } |
517 | 564 |
518 #elif defined(OS_POSIX) | 565 #elif defined(OS_POSIX) |
519 typedef base::MessagePumpLibevent::Watcher Watcher; | |
520 typedef base::MessagePumpLibevent::FileDescriptorWatcher | |
521 FileDescriptorWatcher; | |
522 | |
523 enum Mode { | |
524 WATCH_READ = base::MessagePumpLibevent::WATCH_READ, | |
525 WATCH_WRITE = base::MessagePumpLibevent::WATCH_WRITE, | |
526 WATCH_READ_WRITE = base::MessagePumpLibevent::WATCH_READ_WRITE | |
527 }; | |
528 | |
529 // Please see MessagePumpLibevent for definition. | 566 // Please see MessagePumpLibevent for definition. |
530 bool WatchFileDescriptor(int fd, | 567 bool WatchFileDescriptor(int fd, |
531 bool persistent, | 568 bool persistent, |
532 Mode mode, | 569 Mode mode, |
533 FileDescriptorWatcher *controller, | 570 FileDescriptorWatcher *controller, |
534 Watcher *delegate); | 571 Watcher *delegate); |
| 572 |
| 573 private: |
| 574 base::MessagePumpLibevent* pump_io() { |
| 575 return static_cast<base::MessagePumpLibevent*>(pump_.get()); |
| 576 } |
535 #endif // defined(OS_POSIX) | 577 #endif // defined(OS_POSIX) |
536 }; | 578 }; |
537 | 579 |
538 // Do not add any member variables to MessageLoopForIO! This is important b/c | 580 // Do not add any member variables to MessageLoopForIO! This is important b/c |
539 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 581 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
540 // data that you need should be stored on the MessageLoop's pump_ instance. | 582 // data that you need should be stored on the MessageLoop's pump_ instance. |
541 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 583 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
542 MessageLoopForIO_should_not_have_extra_member_variables); | 584 MessageLoopForIO_should_not_have_extra_member_variables); |
543 | 585 |
544 #endif // BASE_MESSAGE_LOOP_H_ | 586 #endif // BASE_MESSAGE_LOOP_H_ |
OLD | NEW |