Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(811)

Side by Side Diff: base/message_loop.h

Issue 10479018: Add base::RunLoop and update ui_test_utils to use it to reduce flakiness (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: android compile Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | base/message_loop.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | base/message_loop.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698