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> |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 // MessageLoop::Run(). If this is not the same as the thread that calls | 210 // MessageLoop::Run(). If this is not the same as the thread that calls |
| 211 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from | 211 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from |
| 212 // RefCountedThreadSafe<T>! | 212 // RefCountedThreadSafe<T>! |
| 213 template <class T> | 213 template <class T> |
| 214 void ReleaseSoon(const tracked_objects::Location& from_here, | 214 void ReleaseSoon(const tracked_objects::Location& from_here, |
| 215 const T* object) { | 215 const T* object) { |
| 216 base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner( | 216 base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner( |
| 217 this, from_here, object); | 217 this, from_here, object); |
| 218 } | 218 } |
| 219 | 219 |
| 220 protected: | |
| 221 class RunState; | |
| 222 | |
| 223 // RunIDObject is used by Run and QuitNowWithID to quit a particular nested | |
| 224 // call to MessageLoop::Run. Call GetRunID to get a RunIDObject for use with | |
| 225 // one pair of Run/Quit calls. You can not reuse a RunIDObject. | |
| 226 class RunIDObject : public base::RefCounted<RunIDObject> { | |
| 227 private: | |
| 228 friend class base::RefCounted<RunIDObject>; | |
| 229 friend class MessageLoop; | |
| 230 | |
| 231 RunIDObject() : run_state_(NULL), used_(false), quit_now_received_(false) {} | |
| 232 ~RunIDObject() {} | |
| 233 | |
| 234 RunState* run_state_; | |
| 235 bool used_; | |
| 236 | |
| 237 // Used to record that QuitNowWithID() was called at this run_depth. | |
| 238 bool quit_now_received_; | |
|
jar (doing other things)
2012/06/18 19:43:21
Why not use the bool in the run_state?
I later
jbates
2012/06/18 23:14:03
Added this use case to the QuitNowWithID comments.
| |
| 239 | |
| 240 DISALLOW_COPY_AND_ASSIGN(RunIDObject); | |
| 241 }; | |
| 242 | |
| 243 public: | |
| 244 | |
| 245 typedef scoped_refptr<RunIDObject> RunID; | |
| 246 | |
| 220 // Run the message loop. | 247 // Run the message loop. |
| 221 void Run(); | 248 void Run(); |
| 222 | 249 |
| 250 // Run the message loop with the given |run_id|. |run_id| must be retrieved by | |
| 251 // an earlier call to GetRunID. | |
| 252 void RunWithID(const RunID& run_id); | |
| 253 | |
| 223 // Process all pending tasks, windows messages, etc., but don't wait/sleep. | 254 // Process all pending tasks, windows messages, etc., but don't wait/sleep. |
| 224 // Return as soon as all items that can be run are taken care of. | 255 // Return as soon as all items that can be run are taken care of. |
| 225 void RunAllPending(); | 256 void RunAllPending(); |
| 226 | 257 |
| 227 // Signals the Run method to return after it is done processing all pending | 258 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdle(). |
| 228 // messages. This method may only be called on the same thread that called | 259 void Quit() { QuitWhenIdle(); } |
| 229 // Run, and Run must still be on the call stack. | 260 |
| 261 // Signals the Run method to return when it becomes idle. It will continue to | |
| 262 // process pending messages and future messages as long as they are enqueued. | |
| 263 // Warning: if the MessageLoop remains busy, it may never quit. Only use this | |
| 264 // Quit method when looping procedures (such as web pages) have been shut | |
| 265 // down. | |
| 230 // | 266 // |
| 231 // Use QuitClosure if you need to Quit another thread's MessageLoop, but note | 267 // This method may only be called on the same thread that called Run, and Run |
| 232 // that doing so is fairly dangerous if the target thread makes nested calls | 268 // must still be on the call stack. |
| 233 // to MessageLoop::Run. The problem being that you won't know which nested | 269 // |
| 234 // run loop you are quitting, so be careful! | 270 // Use Quit*Closure variants if you need to Quit another thread's MessageLoop, |
| 235 void Quit(); | 271 // but note that doing so is fairly dangerous if the target thread makes |
| 272 // nested calls to MessageLoop::Run. The problem being that you won't know | |
| 273 // which nested run loop you are quitting, so be careful! | |
| 274 void QuitWhenIdle(); | |
| 236 | 275 |
| 237 // This method is a variant of Quit, that does not wait for pending messages | 276 // This method is a variant of Quit, that does not wait for pending messages |
| 238 // to be processed before returning from Run. | 277 // to be processed before returning from Run. |
| 239 void QuitNow(); | 278 void QuitNow(); |
| 240 | 279 |
| 241 // Invokes Quit on the current MessageLoop when run. Useful to schedule an | 280 // This method is a variant of QuitNow that applies to a specific nested call |
| 242 // arbitrary MessageLoop to Quit. | 281 // to MessageLoop::Run(). Although nesting is strongly discouraged, it can be |
| 243 static base::Closure QuitClosure(); | 282 // handy for tests. Use QuitNowWithID to make nesting and quit behavior more |
| 283 // predictable. |run_id| is returned by an earlier call to | |
| 284 // GetRunID(). If the corresponding MessageLoop::Run call has already | |
| 285 // completed, nothing happens. If there are one or more nested calls to | |
| 286 // MessageLoop::Run inside the target Run call, the QuitNow is deferred until | |
| 287 // all nested Run calls have completed. | |
|
jar (doing other things)
2012/06/18 19:43:21
Please add the following additional warning. I do
jbates
2012/06/18 23:14:03
Done.
| |
| 288 void QuitNowWithID(const RunID& run_id); | |
| 289 | |
| 290 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure(). | |
| 291 static base::Closure QuitClosure() { return QuitWhenIdleClosure(); } | |
| 292 | |
| 293 // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an | |
| 294 // arbitrary MessageLoop to QuitWhenIdle. | |
| 295 static base::Closure QuitWhenIdleClosure(); | |
| 296 | |
| 297 // Construct a Closure that will call QuitNow(). Useful to schedule an | |
| 298 // arbitrary MessageLoop to QuitNow. | |
| 299 static base::Closure QuitNowClosure(); | |
| 300 | |
| 301 // Construct a Closure that will call QuitNowWithID(run_id). Useful to | |
| 302 // schedule an arbitrary MessageLoop to QuitNowWithID. | |
| 303 static base::Closure QuitNowWithIDClosure(const RunID& run_id); | |
| 304 | |
| 305 // Get a run id for use with MessageLoop::Run and MessageLoop::QuitNowWithID. | |
| 306 // Use this value to quit a specific nested call to MessageLoop::Run. The | |
| 307 // value returned by GetRunID is only for use on the same MessageLoop | |
| 308 // instance. For example: | |
| 309 // | |
| 310 // // Record GetRunID before running the MessageLoop: | |
| 311 // run_id_ = MessageLoop::current()->GetRunID(); | |
| 312 // MessageLoop::current()->RunWithID(run_id_); | |
| 313 // | |
| 314 // // Then, during a task or callback during the above call to Run: | |
| 315 // MessageLoop::current()->QuitNowWithID(run_id_); | |
| 316 RunID GetRunID(); | |
| 244 | 317 |
| 245 // Returns the type passed to the constructor. | 318 // Returns the type passed to the constructor. |
| 246 Type type() const { return type_; } | 319 Type type() const { return type_; } |
| 247 | 320 |
| 248 // Optional call to connect the thread name with this loop. | 321 // Optional call to connect the thread name with this loop. |
| 249 void set_thread_name(const std::string& thread_name) { | 322 void set_thread_name(const std::string& thread_name) { |
| 250 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; | 323 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; |
| 251 thread_name_ = thread_name; | 324 thread_name_ = thread_name; |
| 252 } | 325 } |
| 253 const std::string& thread_name() const { return thread_name_; } | 326 const std::string& thread_name() const { return thread_name_; } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 bool os_modal_loop() const { | 428 bool os_modal_loop() const { |
| 356 return os_modal_loop_; | 429 return os_modal_loop_; |
| 357 } | 430 } |
| 358 #endif // OS_WIN | 431 #endif // OS_WIN |
| 359 | 432 |
| 360 // Can only be called from the thread that owns the MessageLoop. | 433 // Can only be called from the thread that owns the MessageLoop. |
| 361 bool is_running() const; | 434 bool is_running() const; |
| 362 | 435 |
| 363 //---------------------------------------------------------------------------- | 436 //---------------------------------------------------------------------------- |
| 364 protected: | 437 protected: |
| 365 struct RunState { | 438 class BASE_EXPORT RunState { |
| 439 public: | |
| 440 RunState(); | |
| 441 | |
| 442 // Used to distinguish this RunState from other nested RunStates. | |
| 443 RunID run_state_id; | |
|
jar (doing other things)
2012/06/18 19:43:21
nit: member names need a trailing underscore.
jbates
2012/06/18 23:14:03
Done.
| |
| 444 | |
| 366 // Used to count how many Run() invocations are on the stack. | 445 // Used to count how many Run() invocations are on the stack. |
| 367 int run_depth; | 446 int run_depth; |
| 368 | 447 |
| 369 // Used to record that Quit() was called, or that we should quit the pump | 448 // Used to record that Quit() was called, or that we should quit the pump |
| 370 // once it becomes idle. | 449 // once it becomes idle. |
| 371 bool quit_received; | 450 bool quit_received; |
| 372 | 451 |
| 373 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | 452 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 374 Dispatcher* dispatcher; | 453 Dispatcher* dispatcher; |
| 375 #endif | 454 #endif |
| 455 protected: | |
| 456 ~RunState(); | |
| 376 }; | 457 }; |
| 377 | 458 |
| 378 #if defined(OS_ANDROID) | 459 #if defined(OS_ANDROID) |
| 379 // Android Java process manages the UI thread message loop. So its | 460 // Android Java process manages the UI thread message loop. So its |
| 380 // MessagePumpForUI needs to keep the RunState. | 461 // MessagePumpForUI needs to keep the RunState. |
| 381 public: | 462 public: |
| 382 #endif | 463 #endif |
| 383 class BASE_EXPORT AutoRunState : RunState { | 464 class BASE_EXPORT AutoRunState : RunState { |
| 384 public: | 465 public: |
| 385 explicit AutoRunState(MessageLoop* loop); | 466 AutoRunState(MessageLoop* loop, const RunID& run_id); |
| 386 ~AutoRunState(); | 467 ~AutoRunState(); |
| 387 private: | 468 private: |
| 388 MessageLoop* loop_; | 469 MessageLoop* loop_; |
| 389 RunState* previous_state_; | 470 RunState* previous_state_; |
| 390 }; | 471 }; |
| 391 #if defined(OS_ANDROID) | 472 #if defined(OS_ANDROID) |
| 392 protected: | 473 protected: |
| 393 #endif | 474 #endif |
| 394 | 475 |
| 395 #if defined(OS_WIN) | 476 #if defined(OS_WIN) |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 // On Android, the UI message loop is handled by Java side. So Run() should | 646 // On Android, the UI message loop is handled by Java side. So Run() should |
| 566 // never be called. Instead use Start(), which will forward all the native UI | 647 // never be called. Instead use Start(), which will forward all the native UI |
| 567 // events to the Java message loop. | 648 // events to the Java message loop. |
| 568 void Start(); | 649 void Start(); |
| 569 #elif !defined(OS_MACOSX) | 650 #elif !defined(OS_MACOSX) |
| 570 // Please see message_pump_win/message_pump_glib for definitions of these | 651 // Please see message_pump_win/message_pump_glib for definitions of these |
| 571 // methods. | 652 // methods. |
| 572 void AddObserver(Observer* observer); | 653 void AddObserver(Observer* observer); |
| 573 void RemoveObserver(Observer* observer); | 654 void RemoveObserver(Observer* observer); |
| 574 void RunWithDispatcher(Dispatcher* dispatcher); | 655 void RunWithDispatcher(Dispatcher* dispatcher); |
| 656 void RunWithDispatcher(Dispatcher* dispatcher, const RunID& run_id); | |
| 575 void RunAllPendingWithDispatcher(Dispatcher* dispatcher); | 657 void RunAllPendingWithDispatcher(Dispatcher* dispatcher); |
| 576 | 658 |
| 577 protected: | 659 protected: |
| 578 // TODO(rvargas): Make this platform independent. | 660 // TODO(rvargas): Make this platform independent. |
| 579 base::MessagePumpForUI* pump_ui() { | 661 base::MessagePumpForUI* pump_ui() { |
| 580 return static_cast<base::MessagePumpForUI*>(pump_.get()); | 662 return static_cast<base::MessagePumpForUI*>(pump_.get()); |
| 581 } | 663 } |
| 582 #endif // !defined(OS_MACOSX) | 664 #endif // !defined(OS_MACOSX) |
| 583 }; | 665 }; |
| 584 | 666 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 659 #endif // defined(OS_POSIX) | 741 #endif // defined(OS_POSIX) |
| 660 }; | 742 }; |
| 661 | 743 |
| 662 // Do not add any member variables to MessageLoopForIO! This is important b/c | 744 // Do not add any member variables to MessageLoopForIO! This is important b/c |
| 663 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 745 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
| 664 // data that you need should be stored on the MessageLoop's pump_ instance. | 746 // data that you need should be stored on the MessageLoop's pump_ instance. |
| 665 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 747 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
| 666 MessageLoopForIO_should_not_have_extra_member_variables); | 748 MessageLoopForIO_should_not_have_extra_member_variables); |
| 667 | 749 |
| 668 #endif // BASE_MESSAGE_LOOP_H_ | 750 #endif // BASE_MESSAGE_LOOP_H_ |
| OLD | NEW |