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_; | |
| 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); | |
|
darin (slow to review)
2012/06/19 17:55:51
[Sorry, detour incoming!!]
I think it would be he
jbates
2012/06/22 02:12:51
RunLoop done with some slight semantic changes.
I
| |
| 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(). QuitWithID has the following behavior: | |
| 285 // - If the corresponding MessageLoop::RunWithID call has already completed, | |
| 286 // nothing happens. | |
| 287 // - If the corresponding MessageLoop::RunWithID has not been called yet, it | |
| 288 // will become a no-op when it is eventually called. | |
| 289 // - If there are one or more nested calls to MessageLoop::Run inside the | |
| 290 // target RunWithID call, the QuitNow is deferred until all nested Run calls | |
| 291 // have completed. | |
| 292 // WARNING: You must NEVER assume that a call to QuitNowWithID will terminate | |
| 293 // the targetted message loop. If a nested message loop continues running, the | |
| 294 // target may NEVER terminate. It is very easy to livelock (run forever) in | |
| 295 // such a case. | |
| 296 void QuitNowWithID(const RunID& run_id); | |
| 297 | |
| 298 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure(). | |
| 299 static base::Closure QuitClosure() { return QuitWhenIdleClosure(); } | |
| 300 | |
| 301 // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an | |
| 302 // arbitrary MessageLoop to QuitWhenIdle. | |
| 303 static base::Closure QuitWhenIdleClosure(); | |
| 304 | |
| 305 // Construct a Closure that will call QuitNow(). Useful to schedule an | |
| 306 // arbitrary MessageLoop to QuitNow. | |
| 307 static base::Closure QuitNowClosure(); | |
| 308 | |
| 309 // Construct a Closure that will call QuitNowWithID(run_id). Useful to | |
| 310 // schedule an arbitrary MessageLoop to QuitNowWithID. | |
| 311 static base::Closure QuitNowWithIDClosure(const RunID& run_id); | |
| 312 | |
| 313 // Get a run id for use with MessageLoop::Run and MessageLoop::QuitNowWithID. | |
| 314 // Use this value to quit a specific nested call to MessageLoop::Run. The | |
| 315 // value returned by GetRunID is only for use on the same MessageLoop | |
| 316 // instance. For example: | |
| 317 // | |
| 318 // // Record GetRunID before running the MessageLoop: | |
| 319 // run_id_ = MessageLoop::current()->GetRunID(); | |
| 320 // MessageLoop::current()->RunWithID(run_id_); | |
| 321 // | |
| 322 // // Then, during a task or callback during the above call to Run: | |
| 323 // MessageLoop::current()->QuitNowWithID(run_id_); | |
| 324 RunID GetRunID(); | |
| 244 | 325 |
| 245 // Returns the type passed to the constructor. | 326 // Returns the type passed to the constructor. |
| 246 Type type() const { return type_; } | 327 Type type() const { return type_; } |
| 247 | 328 |
| 248 // Optional call to connect the thread name with this loop. | 329 // Optional call to connect the thread name with this loop. |
| 249 void set_thread_name(const std::string& thread_name) { | 330 void set_thread_name(const std::string& thread_name) { |
| 250 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; | 331 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; |
| 251 thread_name_ = thread_name; | 332 thread_name_ = thread_name; |
| 252 } | 333 } |
| 253 const std::string& thread_name() const { return thread_name_; } | 334 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 { | 436 bool os_modal_loop() const { |
| 356 return os_modal_loop_; | 437 return os_modal_loop_; |
| 357 } | 438 } |
| 358 #endif // OS_WIN | 439 #endif // OS_WIN |
| 359 | 440 |
| 360 // Can only be called from the thread that owns the MessageLoop. | 441 // Can only be called from the thread that owns the MessageLoop. |
| 361 bool is_running() const; | 442 bool is_running() const; |
| 362 | 443 |
| 363 //---------------------------------------------------------------------------- | 444 //---------------------------------------------------------------------------- |
| 364 protected: | 445 protected: |
| 365 struct RunState { | 446 class BASE_EXPORT RunState { |
| 447 public: | |
| 448 RunState(); | |
| 449 | |
| 450 // Used to distinguish this RunState from other nested RunStates. | |
| 451 RunID run_state_id_; | |
| 452 | |
| 366 // Used to count how many Run() invocations are on the stack. | 453 // Used to count how many Run() invocations are on the stack. |
| 367 int run_depth; | 454 int run_depth_; |
| 368 | 455 |
| 369 // Used to record that Quit() was called, or that we should quit the pump | 456 // Used to record that Quit() was called, or that we should quit the pump |
| 370 // once it becomes idle. | 457 // once it becomes idle. |
| 371 bool quit_received; | 458 bool quit_received_; |
| 372 | 459 |
| 373 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | 460 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 374 Dispatcher* dispatcher; | 461 Dispatcher* dispatcher_; |
| 375 #endif | 462 #endif |
| 463 protected: | |
| 464 ~RunState(); | |
| 376 }; | 465 }; |
| 377 | 466 |
| 378 #if defined(OS_ANDROID) | 467 #if defined(OS_ANDROID) |
| 379 // Android Java process manages the UI thread message loop. So its | 468 // Android Java process manages the UI thread message loop. So its |
| 380 // MessagePumpForUI needs to keep the RunState. | 469 // MessagePumpForUI needs to keep the RunState. |
| 381 public: | 470 public: |
| 382 #endif | 471 #endif |
| 383 class BASE_EXPORT AutoRunState : RunState { | 472 class BASE_EXPORT AutoRunState : RunState { |
| 384 public: | 473 public: |
| 385 explicit AutoRunState(MessageLoop* loop); | 474 AutoRunState(MessageLoop* loop, const RunID& run_id); |
| 386 ~AutoRunState(); | 475 ~AutoRunState(); |
| 387 private: | 476 private: |
| 388 MessageLoop* loop_; | 477 MessageLoop* loop_; |
| 389 RunState* previous_state_; | 478 RunState* previous_state_; |
| 390 }; | 479 }; |
| 391 #if defined(OS_ANDROID) | 480 #if defined(OS_ANDROID) |
| 392 protected: | 481 protected: |
| 393 #endif | 482 #endif |
| 394 | 483 |
| 395 #if defined(OS_WIN) | 484 #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 | 654 // 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 | 655 // never be called. Instead use Start(), which will forward all the native UI |
| 567 // events to the Java message loop. | 656 // events to the Java message loop. |
| 568 void Start(); | 657 void Start(); |
| 569 #elif !defined(OS_MACOSX) | 658 #elif !defined(OS_MACOSX) |
| 570 // Please see message_pump_win/message_pump_glib for definitions of these | 659 // Please see message_pump_win/message_pump_glib for definitions of these |
| 571 // methods. | 660 // methods. |
| 572 void AddObserver(Observer* observer); | 661 void AddObserver(Observer* observer); |
| 573 void RemoveObserver(Observer* observer); | 662 void RemoveObserver(Observer* observer); |
| 574 void RunWithDispatcher(Dispatcher* dispatcher); | 663 void RunWithDispatcher(Dispatcher* dispatcher); |
| 664 void RunWithDispatcher(Dispatcher* dispatcher, const RunID& run_id); | |
| 575 void RunAllPendingWithDispatcher(Dispatcher* dispatcher); | 665 void RunAllPendingWithDispatcher(Dispatcher* dispatcher); |
| 576 | 666 |
| 577 protected: | 667 protected: |
| 578 // TODO(rvargas): Make this platform independent. | 668 // TODO(rvargas): Make this platform independent. |
| 579 base::MessagePumpForUI* pump_ui() { | 669 base::MessagePumpForUI* pump_ui() { |
| 580 return static_cast<base::MessagePumpForUI*>(pump_.get()); | 670 return static_cast<base::MessagePumpForUI*>(pump_.get()); |
| 581 } | 671 } |
| 582 #endif // !defined(OS_MACOSX) | 672 #endif // !defined(OS_MACOSX) |
| 583 }; | 673 }; |
| 584 | 674 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 659 #endif // defined(OS_POSIX) | 749 #endif // defined(OS_POSIX) |
| 660 }; | 750 }; |
| 661 | 751 |
| 662 // Do not add any member variables to MessageLoopForIO! This is important b/c | 752 // Do not add any member variables to MessageLoopForIO! This is important b/c |
| 663 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 753 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
| 664 // data that you need should be stored on the MessageLoop's pump_ instance. | 754 // data that you need should be stored on the MessageLoop's pump_ instance. |
| 665 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 755 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
| 666 MessageLoopForIO_should_not_have_extra_member_variables); | 756 MessageLoopForIO_should_not_have_extra_member_variables); |
| 667 | 757 |
| 668 #endif // BASE_MESSAGE_LOOP_H_ | 758 #endif // BASE_MESSAGE_LOOP_H_ |
| OLD | NEW |