Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/base_export.h" | 12 #include "base/base_export.h" |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/callback_forward.h" | 14 #include "base/callback_forward.h" |
| 15 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
| 17 #include "base/memory/weak_ptr.h" | |
| 17 #include "base/message_loop_proxy.h" | 18 #include "base/message_loop_proxy.h" |
| 18 #include "base/message_pump.h" | 19 #include "base/message_pump.h" |
| 19 #include "base/observer_list.h" | 20 #include "base/observer_list.h" |
| 20 #include "base/pending_task.h" | 21 #include "base/pending_task.h" |
| 21 #include "base/sequenced_task_runner_helpers.h" | 22 #include "base/sequenced_task_runner_helpers.h" |
| 22 #include "base/synchronization/lock.h" | 23 #include "base/synchronization/lock.h" |
| 23 #include "base/tracking_info.h" | 24 #include "base/tracking_info.h" |
| 24 #include "base/time.h" | 25 #include "base/time.h" |
| 25 | 26 |
| 26 #if defined(OS_WIN) | 27 #if defined(OS_WIN) |
| 27 // We need this to declare base::MessagePumpWin::Dispatcher, which we should | 28 // We need this to declare base::MessagePumpWin::Dispatcher, which we should |
| 28 // really just eliminate. | 29 // really just eliminate. |
| 29 #include "base/message_pump_win.h" | 30 #include "base/message_pump_win.h" |
| 30 #elif defined(OS_POSIX) | 31 #elif defined(OS_POSIX) |
| 31 #include "base/message_pump_libevent.h" | 32 #include "base/message_pump_libevent.h" |
| 32 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | 33 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 33 | 34 |
| 34 #if defined(USE_AURA) | 35 #if defined(USE_AURA) |
| 35 #include "base/message_pump_aurax11.h" | 36 #include "base/message_pump_aurax11.h" |
| 36 #else | 37 #else |
| 37 #include "base/message_pump_gtk.h" | 38 #include "base/message_pump_gtk.h" |
| 38 #endif | 39 #endif |
| 39 | 40 |
| 40 #endif | 41 #endif |
| 41 #endif | 42 #endif |
| 42 | 43 |
| 43 namespace base { | 44 namespace base { |
| 44 class Histogram; | 45 class Histogram; |
| 45 class ThreadTaskRunnerHandle; | 46 class ThreadTaskRunnerHandle; |
| 47 #if defined(OS_ANDROID) | |
| 48 class MessagePumpForUI; | |
| 49 #endif | |
| 46 } // namespace base | 50 } // namespace base |
| 47 | 51 |
| 48 // A MessageLoop is used to process events for a particular thread. There is | 52 // A MessageLoop is used to process events for a particular thread. There is |
| 49 // at most one MessageLoop instance per thread. | 53 // at most one MessageLoop instance per thread. |
| 50 // | 54 // |
| 51 // Events include at a minimum Task instances submitted to PostTask or those | 55 // Events include at a minimum Task instances submitted to PostTask or those |
| 52 // managed by TimerManager. Depending on the type of message pump used by the | 56 // managed by TimerManager. Depending on the type of message pump used by the |
| 53 // MessageLoop other events such as UI messages may be processed. On Windows | 57 // MessageLoop other events such as UI messages may be processed. On Windows |
| 54 // APC calls (as time permits) and signals sent to a registered set of HANDLEs | 58 // APC calls (as time permits) and signals sent to a registered set of HANDLEs |
| 55 // may also be processed. | 59 // may also be processed. |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 // MessageLoop::Run(). If this is not the same as the thread that calls | 206 // MessageLoop::Run(). If this is not the same as the thread that calls |
| 203 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from | 207 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from |
| 204 // RefCountedThreadSafe<T>! | 208 // RefCountedThreadSafe<T>! |
| 205 template <class T> | 209 template <class T> |
| 206 void ReleaseSoon(const tracked_objects::Location& from_here, | 210 void ReleaseSoon(const tracked_objects::Location& from_here, |
| 207 const T* object) { | 211 const T* object) { |
| 208 base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner( | 212 base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner( |
| 209 this, from_here, object); | 213 this, from_here, object); |
| 210 } | 214 } |
| 211 | 215 |
| 216 // Helper class to Run a nested MessageLoop. Please do not use nested | |
| 217 // MessageLoops in production code! If you must, use this class instead of | |
| 218 // calling MessageLoop::Run/Quit directly. RunLoop::Run can only be called | |
| 219 // once per RunLoop lifetime. Create a RunLoop on the stack and call Run/Stop | |
| 220 // to run a nested MessageLoop. | |
| 221 class RunLoop : public base::SupportsWeakPtr<RunLoop> { | |
|
darin (slow to review)
2012/06/22 04:42:23
this can be a top-level type in the base:: namespa
jbates
2012/06/22 23:21:01
Done.
| |
| 222 public: | |
| 223 RunLoop(); | |
| 224 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
| 225 explicit RunLoop(Dispatcher* dispatcher); | |
|
darin (slow to review)
2012/06/22 04:42:23
cool, i had the same idea to just make the dispatc
| |
| 226 #endif | |
| 227 ~RunLoop(); | |
| 228 | |
| 229 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
| 230 void set_dispatcher(Dispatcher* dispatcher) { dispatcher_ = dispatcher; } | |
| 231 #endif | |
| 232 | |
| 233 // Run the current MessageLoop. This blocks until Stop is called. Before | |
| 234 // calling Run, be sure to grab an AsWeakPtr or the StopClosure in order to | |
| 235 // stop the MessageLoop asynchronously. MessageLoop::Quit and QuitNow will | |
| 236 // also trigger a return from Run, but those are deprecated. | |
| 237 void Run(); | |
| 238 | |
| 239 // Run the current MessageLoop until it doesn't find any tasks or messages | |
| 240 // in the queue (it goes idle). WARNING: This may never return! Only use | |
| 241 // this when repeating tasks such as animated web pages have been shut down. | |
| 242 void RunUntilIdle(); | |
| 243 | |
| 244 // Stop an earlier call to this->Run(). Nested RunLoops (and deprecated | |
| 245 // MessageLoop::Run*) are unaffected and continue to run until they are | |
| 246 // stopped by other means. This call stops processing tasks immediately | |
| 247 // (when there are no nested RunLoops running), leaving any pending tasks | |
|
darin (slow to review)
2012/06/22 04:42:23
i think you can just define this in terms of quitt
jbates
2012/06/22 23:21:01
Done.
| |
| 248 // unexecuted. Stop can be called before, during or after Run. If called | |
| 249 // before Run, Run will return immediately when called. | |
| 250 // | |
| 251 // WARNING: You must NEVER assume that a call to Stop will terminate the | |
| 252 // targetted message loop. If a nested message loop continues running, the | |
| 253 // target may NEVER terminate. It is very easy to livelock (run forever) in | |
| 254 // such a case. | |
| 255 void Stop(); | |
|
darin (slow to review)
2012/06/22 04:42:23
probably should go back to calling this Quit. but
jbates
2012/06/22 23:21:01
Done.
| |
| 256 | |
| 257 // Hand this closure off to code that asynchronously notifies of completion. | |
| 258 // The returned Closure is safe to run after the RunLoop has been | |
| 259 // destructed. Example: | |
| 260 // RunLoop run_loop; | |
| 261 // kick_off_some_procedure(run_loop.StopClosure()); | |
| 262 // run_loop.Run(); | |
| 263 base::Closure StopClosure(); | |
| 264 | |
| 265 private: | |
| 266 friend class MessageLoop; | |
| 267 #if defined(OS_ANDROID) | |
| 268 // Android doesn't support the blocking MessageLoop::Run, so it calls | |
| 269 // BeforeRun and AfterRun directly. | |
| 270 friend class base::MessagePumpForUI; | |
| 271 #endif | |
| 272 | |
| 273 // Return false to abort the Run. | |
| 274 bool BeforeRun(); | |
| 275 void AfterRun(); | |
| 276 | |
| 277 MessageLoop* loop_; | |
| 278 | |
| 279 base::WeakPtr<RunLoop> previous_run_loop_; | |
| 280 | |
| 281 bool run_called_; | |
| 282 bool stop_called_; | |
| 283 bool running_; | |
| 284 | |
| 285 // Used to count how many nested Run() invocations are on the stack. | |
| 286 int run_depth_; | |
| 287 | |
| 288 // Used to record that Quit() was called on the MessageLoop, meaning that we | |
| 289 // should quit Run once it becomes idle. | |
| 290 bool quit_when_idle_received_; | |
| 291 | |
| 292 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
| 293 Dispatcher* dispatcher_; | |
| 294 #endif | |
| 295 | |
| 296 DISALLOW_COPY_AND_ASSIGN(RunLoop); | |
| 297 }; | |
| 298 | |
| 299 // Deprecated: use RunLoop instead. | |
| 212 // Run the message loop. | 300 // Run the message loop. |
| 213 void Run(); | 301 void Run(); |
| 214 | 302 |
| 215 // Process all pending tasks, windows messages, etc., but don't wait/sleep. | 303 // Process all pending tasks, windows messages, etc., but don't wait/sleep. |
| 216 // Return as soon as all items that can be run are taken care of. | 304 // Return as soon as all items that can be run are taken care of. |
| 217 void RunAllPending(); | 305 void RunAllPending(); |
| 218 | 306 |
| 219 // Signals the Run method to return after it is done processing all pending | 307 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdle(). |
| 220 // messages. This method may only be called on the same thread that called | 308 void Quit() { QuitWhenIdle(); } |
| 221 // Run, and Run must still be on the call stack. | 309 |
| 310 // Deprecated: use RunLoop or RunAllPending instead. | |
| 222 // | 311 // |
| 223 // Use QuitClosure if you need to Quit another thread's MessageLoop, but note | 312 // Signals the Run method to return when it becomes idle. It will continue to |
| 224 // that doing so is fairly dangerous if the target thread makes nested calls | 313 // process pending messages and future messages as long as they are enqueued. |
| 225 // to MessageLoop::Run. The problem being that you won't know which nested | 314 // Warning: if the MessageLoop remains busy, it may never quit. Only use this |
| 226 // run loop you are quitting, so be careful! | 315 // Quit method when looping procedures (such as web pages) have been shut |
| 227 void Quit(); | 316 // down. |
| 317 // | |
| 318 // This method may only be called on the same thread that called Run, and Run | |
| 319 // must still be on the call stack. | |
| 320 // | |
| 321 // Use QuitClosure variants if you need to Quit another thread's MessageLoop, | |
| 322 // but note that doing so is fairly dangerous if the target thread makes | |
| 323 // nested calls to MessageLoop::Run. The problem being that you won't know | |
| 324 // which nested run loop you are quitting, so be careful! | |
| 325 void QuitWhenIdle(); | |
|
darin (slow to review)
2012/06/22 04:42:23
hmm... thinking about names again. RunUntilIdle()
jbates
2012/06/22 23:21:01
I'm not too partial. I guess I prefer "Idle" becau
| |
| 228 | 326 |
| 327 // Deprecated: use RunLoop instead. | |
| 328 // | |
| 229 // This method is a variant of Quit, that does not wait for pending messages | 329 // This method is a variant of Quit, that does not wait for pending messages |
| 230 // to be processed before returning from Run. | 330 // to be processed before returning from Run. |
| 231 void QuitNow(); | 331 void QuitNow(); |
| 232 | 332 |
| 233 // Invokes Quit on the current MessageLoop when run. Useful to schedule an | 333 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure(). |
| 234 // arbitrary MessageLoop to Quit. | 334 static base::Closure QuitClosure() { return QuitWhenIdleClosure(); } |
| 235 static base::Closure QuitClosure(); | 335 |
| 336 // Deprecated: use RunLoop instead. | |
| 337 // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an | |
| 338 // arbitrary MessageLoop to QuitWhenIdle. | |
| 339 static base::Closure QuitWhenIdleClosure(); | |
| 236 | 340 |
| 237 // Returns the type passed to the constructor. | 341 // Returns the type passed to the constructor. |
| 238 Type type() const { return type_; } | 342 Type type() const { return type_; } |
| 239 | 343 |
| 240 // Optional call to connect the thread name with this loop. | 344 // Optional call to connect the thread name with this loop. |
| 241 void set_thread_name(const std::string& thread_name) { | 345 void set_thread_name(const std::string& thread_name) { |
| 242 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; | 346 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; |
| 243 thread_name_ = thread_name; | 347 thread_name_ = thread_name; |
| 244 } | 348 } |
| 245 const std::string& thread_name() const { return thread_name_; } | 349 const std::string& thread_name() const { return thread_name_; } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 347 bool os_modal_loop() const { | 451 bool os_modal_loop() const { |
| 348 return os_modal_loop_; | 452 return os_modal_loop_; |
| 349 } | 453 } |
| 350 #endif // OS_WIN | 454 #endif // OS_WIN |
| 351 | 455 |
| 352 // Can only be called from the thread that owns the MessageLoop. | 456 // Can only be called from the thread that owns the MessageLoop. |
| 353 bool is_running() const; | 457 bool is_running() const; |
| 354 | 458 |
| 355 //---------------------------------------------------------------------------- | 459 //---------------------------------------------------------------------------- |
| 356 protected: | 460 protected: |
| 357 struct RunState { | 461 friend class RunLoop; |
| 358 // Used to count how many Run() invocations are on the stack. | |
| 359 int run_depth; | |
| 360 | |
| 361 // Used to record that Quit() was called, or that we should quit the pump | |
| 362 // once it becomes idle. | |
| 363 bool quit_received; | |
| 364 | |
| 365 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
| 366 Dispatcher* dispatcher; | |
| 367 #endif | |
| 368 }; | |
| 369 | |
| 370 #if defined(OS_ANDROID) | |
| 371 // Android Java process manages the UI thread message loop. So its | |
| 372 // MessagePumpForUI needs to keep the RunState. | |
| 373 public: | |
| 374 #endif | |
| 375 class BASE_EXPORT AutoRunState : RunState { | |
| 376 public: | |
| 377 explicit AutoRunState(MessageLoop* loop); | |
| 378 ~AutoRunState(); | |
| 379 private: | |
| 380 MessageLoop* loop_; | |
| 381 RunState* previous_state_; | |
| 382 }; | |
| 383 #if defined(OS_ANDROID) | |
| 384 protected: | |
| 385 #endif | |
| 386 | 462 |
| 387 #if defined(OS_WIN) | 463 #if defined(OS_WIN) |
| 388 base::MessagePumpWin* pump_win() { | 464 base::MessagePumpWin* pump_win() { |
| 389 return static_cast<base::MessagePumpWin*>(pump_.get()); | 465 return static_cast<base::MessagePumpWin*>(pump_.get()); |
| 390 } | 466 } |
| 391 #elif defined(OS_POSIX) | 467 #elif defined(OS_POSIX) |
| 392 base::MessagePumpLibevent* pump_libevent() { | 468 base::MessagePumpLibevent* pump_libevent() { |
| 393 return static_cast<base::MessagePumpLibevent*>(pump_.get()); | 469 return static_cast<base::MessagePumpLibevent*>(pump_.get()); |
| 394 } | 470 } |
| 395 #endif | 471 #endif |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 489 base::Histogram* message_histogram_; | 565 base::Histogram* message_histogram_; |
| 490 | 566 |
| 491 // A null terminated list which creates an incoming_queue of tasks that are | 567 // A null terminated list which creates an incoming_queue of tasks that are |
| 492 // acquired under a mutex for processing on this instance's thread. These | 568 // acquired under a mutex for processing on this instance's thread. These |
| 493 // tasks have not yet been sorted out into items for our work_queue_ vs items | 569 // tasks have not yet been sorted out into items for our work_queue_ vs items |
| 494 // that will be handled by the TimerManager. | 570 // that will be handled by the TimerManager. |
| 495 base::TaskQueue incoming_queue_; | 571 base::TaskQueue incoming_queue_; |
| 496 // Protect access to incoming_queue_. | 572 // Protect access to incoming_queue_. |
| 497 mutable base::Lock incoming_queue_lock_; | 573 mutable base::Lock incoming_queue_lock_; |
| 498 | 574 |
| 499 RunState* state_; | 575 base::WeakPtr<RunLoop> run_loop_; |
| 500 | 576 |
| 501 #if defined(OS_WIN) | 577 #if defined(OS_WIN) |
| 502 base::TimeTicks high_resolution_timer_expiration_; | 578 base::TimeTicks high_resolution_timer_expiration_; |
| 503 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc | 579 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc |
| 504 // which enter a modal message loop. | 580 // which enter a modal message loop. |
| 505 bool os_modal_loop_; | 581 bool os_modal_loop_; |
| 506 #endif | 582 #endif |
| 507 | 583 |
| 508 // The next sequence number to use for delayed tasks. | 584 // The next sequence number to use for delayed tasks. |
| 509 int next_sequence_num_; | 585 int next_sequence_num_; |
| 510 | 586 |
| 511 ObserverList<TaskObserver> task_observers_; | 587 ObserverList<TaskObserver> task_observers_; |
| 512 | 588 |
| 513 // The message loop proxy associated with this message loop, if one exists. | 589 // The message loop proxy associated with this message loop, if one exists. |
| 514 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | 590 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; |
| 515 scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_; | 591 scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_; |
| 516 | 592 |
| 517 private: | 593 private: |
| 518 template <class T, class R> friend class base::subtle::DeleteHelperInternal; | 594 template <class T, class R> friend class base::subtle::DeleteHelperInternal; |
| 519 template <class T, class R> friend class base::subtle::ReleaseHelperInternal; | 595 template <class T, class R> friend class base::subtle::ReleaseHelperInternal; |
| 520 | 596 |
| 521 void DeleteSoonInternal(const tracked_objects::Location& from_here, | 597 void DeleteSoonInternal(const tracked_objects::Location& from_here, |
| 522 void(*deleter)(const void*), | 598 void(*deleter)(const void*), |
| 523 const void* object); | 599 const void* object); |
| 524 void ReleaseSoonInternal(const tracked_objects::Location& from_here, | 600 void ReleaseSoonInternal(const tracked_objects::Location& from_here, |
| 525 void(*releaser)(const void*), | 601 void(*releaser)(const void*), |
| 526 const void* object); | 602 const void* object); |
| 527 | 603 |
| 528 | |
| 529 DISALLOW_COPY_AND_ASSIGN(MessageLoop); | 604 DISALLOW_COPY_AND_ASSIGN(MessageLoop); |
| 530 }; | 605 }; |
| 531 | 606 |
| 532 //----------------------------------------------------------------------------- | 607 //----------------------------------------------------------------------------- |
| 533 // MessageLoopForUI extends MessageLoop with methods that are particular to a | 608 // MessageLoopForUI extends MessageLoop with methods that are particular to a |
| 534 // MessageLoop instantiated with TYPE_UI. | 609 // MessageLoop instantiated with TYPE_UI. |
| 535 // | 610 // |
| 536 // This class is typically used like so: | 611 // This class is typically used like so: |
| 537 // MessageLoopForUI::current()->...call some method... | 612 // MessageLoopForUI::current()->...call some method... |
| 538 // | 613 // |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 #endif // defined(OS_POSIX) | 726 #endif // defined(OS_POSIX) |
| 652 }; | 727 }; |
| 653 | 728 |
| 654 // Do not add any member variables to MessageLoopForIO! This is important b/c | 729 // Do not add any member variables to MessageLoopForIO! This is important b/c |
| 655 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 730 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
| 656 // data that you need should be stored on the MessageLoop's pump_ instance. | 731 // data that you need should be stored on the MessageLoop's pump_ instance. |
| 657 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 732 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
| 658 MessageLoopForIO_should_not_have_extra_member_variables); | 733 MessageLoopForIO_should_not_have_extra_member_variables); |
| 659 | 734 |
| 660 #endif // BASE_MESSAGE_LOOP_H_ | 735 #endif // BASE_MESSAGE_LOOP_H_ |
| OLD | NEW |