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

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: fetch/merge, no change 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') | base/message_loop.cc » ('J')
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)
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // MessageLoop::Run(). If this is not the same as the thread that calls 203 // MessageLoop::Run(). If this is not the same as the thread that calls
203 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from 204 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from
204 // RefCountedThreadSafe<T>! 205 // RefCountedThreadSafe<T>!
205 template <class T> 206 template <class T>
206 void ReleaseSoon(const tracked_objects::Location& from_here, 207 void ReleaseSoon(const tracked_objects::Location& from_here,
207 const T* object) { 208 const T* object) {
208 base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner( 209 base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner(
209 this, from_here, object); 210 this, from_here, object);
210 } 211 }
211 212
213 // Helper class to Run a nested MessageLoop. Please do not use nested
214 // MessageLoops in production code! If you must, use this class instead of
215 // calling MessageLoop::Run/Quit directly. RunLoop::Run can only be called
216 // once per RunLoop lifetime. Create a RunLoop on the stack and call Run/Stop
217 // to run a nested MessageLoop.
218 class RunLoop : public base::SupportsWeakPtr<RunLoop> {
219 public:
220 RunLoop();
221 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
222 explicit RunLoop(Dispatcher* dispatcher);
223 #endif
224 ~RunLoop();
225
226 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
227 void set_dispatcher(Dispatcher* dispatcher) { dispatcher_ = dispatcher; }
228 #endif
229
230 // Run the current MessageLoop. This blocks until Stop is called. Before
231 // calling Run, be sure to grab an AsWeakPtr or the StopClosure in order to
232 // stop the MessageLoop asynchronously. MessageLoop::Quit and QuitNow will
233 // also trigger a return from Run, but those are deprecated.
234 void Run();
235
236 // Run the current MessageLoop until it doesn't find any tasks or messages
237 // to handle (it goes idle). WARNING: This may never return! Only use this
238 // when repeating tasks such as animated web pages have been shut down.
239 void RunUntilIdle();
240
241 // Quit an earlier call to this->Run(). Nested RunLoops (and deprecated
242 // MessageLoop::Run*) are unaffected and continue to run until they are
243 // stopped by other means. This call stops processing tasks immediately if
244 // (when there are no nested RunLoops running), leaving any pending tasks
245 // unexecuted. WARNING: You must NEVER assume that a call to Stop will
246 // terminate the targetted message loop. If a nested message loop continues
247 // running, the target may NEVER terminate. It is very easy to livelock (run
248 // forever) in such a case.
249 void Stop();
250
251 // Hand this closure off to code that uses asynchronously notifies of
252 // completion. The returned Closure is safe to run after the RunLoop has
253 // been destructed. However, it is not allowed to run the StopClosure before
254 // Run has been called. Example:
255 // RunLoop run_loop;
256 // kick_off_some_procedure(run_loop.StopClosure());
257 // run_loop.Run();
258 base::Closure StopClosure();
259
260 private:
261 friend class MessageLoop;
262
263 MessageLoop* loop_;
264
265 bool run_called_;
266 bool stop_called_;
267 bool running_;
268
269 // Used to count how many nested Run() invocations are on the stack.
270 int run_depth_;
271
272 // Used to record that Quit() was called on the MessageLoop, meaning that we
273 // should quit Run once it becomes idle.
274 bool quit_when_idle_received_;
275
276 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
277 Dispatcher* dispatcher_;
278 #endif
279
280 DISALLOW_COPY_AND_ASSIGN(RunLoop);
281 };
282
283 // Deprecated: use RunLoop instead.
212 // Run the message loop. 284 // Run the message loop.
213 void Run(); 285 void Run();
214 286
215 // Process all pending tasks, windows messages, etc., but don't wait/sleep. 287 // 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. 288 // Return as soon as all items that can be run are taken care of.
217 void RunAllPending(); 289 void RunAllPending();
218 290
219 // Signals the Run method to return after it is done processing all pending 291 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdle().
220 // messages. This method may only be called on the same thread that called 292 void Quit() { QuitWhenIdle(); }
221 // Run, and Run must still be on the call stack. 293
294 // Deprecated: use RunLoop or RunAllPending instead.
222 // 295 //
223 // Use QuitClosure if you need to Quit another thread's MessageLoop, but note 296 // 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 297 // 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 298 // Warning: if the MessageLoop remains busy, it may never quit. Only use this
226 // run loop you are quitting, so be careful! 299 // Quit method when looping procedures (such as web pages) have been shut
227 void Quit(); 300 // down.
301 //
302 // This method may only be called on the same thread that called Run, and Run
303 // must still be on the call stack.
304 //
305 // Use QuitClosure variants if you need to Quit another thread's MessageLoop,
306 // but note that doing so is fairly dangerous if the target thread makes
307 // nested calls to MessageLoop::Run. The problem being that you won't know
308 // which nested run loop you are quitting, so be careful!
309 void QuitWhenIdle();
228 310
311 // Deprecated: use RunLoop instead.
312 //
229 // This method is a variant of Quit, that does not wait for pending messages 313 // This method is a variant of Quit, that does not wait for pending messages
230 // to be processed before returning from Run. 314 // to be processed before returning from Run.
231 void QuitNow(); 315 void QuitNow();
232 316
233 // Invokes Quit on the current MessageLoop when run. Useful to schedule an 317 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure().
234 // arbitrary MessageLoop to Quit. 318 static base::Closure QuitClosure() { return QuitWhenIdleClosure(); }
235 static base::Closure QuitClosure(); 319
320 // Deprecated: use RunLoop instead.
321 // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an
322 // arbitrary MessageLoop to QuitWhenIdle.
323 static base::Closure QuitWhenIdleClosure();
236 324
237 // Returns the type passed to the constructor. 325 // Returns the type passed to the constructor.
238 Type type() const { return type_; } 326 Type type() const { return type_; }
239 327
240 // Optional call to connect the thread name with this loop. 328 // Optional call to connect the thread name with this loop.
241 void set_thread_name(const std::string& thread_name) { 329 void set_thread_name(const std::string& thread_name) {
242 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; 330 DCHECK(thread_name_.empty()) << "Should not rename this thread!";
243 thread_name_ = thread_name; 331 thread_name_ = thread_name;
244 } 332 }
245 const std::string& thread_name() const { return thread_name_; } 333 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 { 435 bool os_modal_loop() const {
348 return os_modal_loop_; 436 return os_modal_loop_;
349 } 437 }
350 #endif // OS_WIN 438 #endif // OS_WIN
351 439
352 // Can only be called from the thread that owns the MessageLoop. 440 // Can only be called from the thread that owns the MessageLoop.
353 bool is_running() const; 441 bool is_running() const;
354 442
355 //---------------------------------------------------------------------------- 443 //----------------------------------------------------------------------------
356 protected: 444 protected:
357 struct RunState { 445 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 446
387 #if defined(OS_WIN) 447 #if defined(OS_WIN)
388 base::MessagePumpWin* pump_win() { 448 base::MessagePumpWin* pump_win() {
389 return static_cast<base::MessagePumpWin*>(pump_.get()); 449 return static_cast<base::MessagePumpWin*>(pump_.get());
390 } 450 }
391 #elif defined(OS_POSIX) 451 #elif defined(OS_POSIX)
392 base::MessagePumpLibevent* pump_libevent() { 452 base::MessagePumpLibevent* pump_libevent() {
393 return static_cast<base::MessagePumpLibevent*>(pump_.get()); 453 return static_cast<base::MessagePumpLibevent*>(pump_.get());
394 } 454 }
395 #endif 455 #endif
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 base::Histogram* message_histogram_; 549 base::Histogram* message_histogram_;
490 550
491 // A null terminated list which creates an incoming_queue of tasks that are 551 // 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 552 // 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 553 // tasks have not yet been sorted out into items for our work_queue_ vs items
494 // that will be handled by the TimerManager. 554 // that will be handled by the TimerManager.
495 base::TaskQueue incoming_queue_; 555 base::TaskQueue incoming_queue_;
496 // Protect access to incoming_queue_. 556 // Protect access to incoming_queue_.
497 mutable base::Lock incoming_queue_lock_; 557 mutable base::Lock incoming_queue_lock_;
498 558
499 RunState* state_; 559 base::WeakPtr<RunLoop> run_loop_;
500 560
501 #if defined(OS_WIN) 561 #if defined(OS_WIN)
502 base::TimeTicks high_resolution_timer_expiration_; 562 base::TimeTicks high_resolution_timer_expiration_;
503 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc 563 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
504 // which enter a modal message loop. 564 // which enter a modal message loop.
505 bool os_modal_loop_; 565 bool os_modal_loop_;
506 #endif 566 #endif
507 567
508 // The next sequence number to use for delayed tasks. 568 // The next sequence number to use for delayed tasks.
509 int next_sequence_num_; 569 int next_sequence_num_;
510 570
511 ObserverList<TaskObserver> task_observers_; 571 ObserverList<TaskObserver> task_observers_;
512 572
513 // The message loop proxy associated with this message loop, if one exists. 573 // The message loop proxy associated with this message loop, if one exists.
514 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; 574 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
515 scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_; 575 scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_;
516 576
517 private: 577 private:
518 template <class T, class R> friend class base::subtle::DeleteHelperInternal; 578 template <class T, class R> friend class base::subtle::DeleteHelperInternal;
519 template <class T, class R> friend class base::subtle::ReleaseHelperInternal; 579 template <class T, class R> friend class base::subtle::ReleaseHelperInternal;
520 580
521 void DeleteSoonInternal(const tracked_objects::Location& from_here, 581 void DeleteSoonInternal(const tracked_objects::Location& from_here,
522 void(*deleter)(const void*), 582 void(*deleter)(const void*),
523 const void* object); 583 const void* object);
524 void ReleaseSoonInternal(const tracked_objects::Location& from_here, 584 void ReleaseSoonInternal(const tracked_objects::Location& from_here,
525 void(*releaser)(const void*), 585 void(*releaser)(const void*),
526 const void* object); 586 const void* object);
527 587
528
529 DISALLOW_COPY_AND_ASSIGN(MessageLoop); 588 DISALLOW_COPY_AND_ASSIGN(MessageLoop);
530 }; 589 };
531 590
532 //----------------------------------------------------------------------------- 591 //-----------------------------------------------------------------------------
533 // MessageLoopForUI extends MessageLoop with methods that are particular to a 592 // MessageLoopForUI extends MessageLoop with methods that are particular to a
534 // MessageLoop instantiated with TYPE_UI. 593 // MessageLoop instantiated with TYPE_UI.
535 // 594 //
536 // This class is typically used like so: 595 // This class is typically used like so:
537 // MessageLoopForUI::current()->...call some method... 596 // MessageLoopForUI::current()->...call some method...
538 // 597 //
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 #endif // defined(OS_POSIX) 710 #endif // defined(OS_POSIX)
652 }; 711 };
653 712
654 // Do not add any member variables to MessageLoopForIO! This is important b/c 713 // Do not add any member variables to MessageLoopForIO! This is important b/c
655 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra 714 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra
656 // data that you need should be stored on the MessageLoop's pump_ instance. 715 // data that you need should be stored on the MessageLoop's pump_ instance.
657 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), 716 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
658 MessageLoopForIO_should_not_have_extra_member_variables); 717 MessageLoopForIO_should_not_have_extra_member_variables);
659 718
660 #endif // BASE_MESSAGE_LOOP_H_ 719 #endif // BASE_MESSAGE_LOOP_H_
OLDNEW
« no previous file with comments | « no previous file | base/message_loop.cc » ('j') | base/message_loop.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698