Home | History | Annotate | Download | only in base
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_RUN_LOOP_H_
      6 #define BASE_RUN_LOOP_H_
      7 
      8 #include "base/base_export.h"
      9 #include "base/callback.h"
     10 #include "base/macros.h"
     11 #include "base/memory/weak_ptr.h"
     12 #include "base/message_loop/message_loop.h"
     13 #include "base/threading/thread_checker.h"
     14 #include "build/build_config.h"
     15 
     16 namespace base {
     17 #if defined(OS_ANDROID)
     18 class MessagePumpForUI;
     19 #endif
     20 
     21 #if defined(OS_IOS)
     22 class MessagePumpUIApplication;
     23 #endif
     24 
     25 // Helper class to Run a nested MessageLoop. Please do not use nested
     26 // MessageLoops in production code! If you must, use this class instead of
     27 // calling MessageLoop::Run/Quit directly. RunLoop::Run can only be called once
     28 // per RunLoop lifetime. Create a RunLoop on the stack and call Run/Quit to run
     29 // a nested MessageLoop.
     30 class BASE_EXPORT RunLoop {
     31  public:
     32   RunLoop();
     33   ~RunLoop();
     34 
     35   // Run the current MessageLoop. This blocks until Quit is called. Before
     36   // calling Run, be sure to grab the QuitClosure in order to stop the
     37   // MessageLoop asynchronously. MessageLoop::QuitWhenIdle and QuitNow will also
     38   // trigger a return from Run, but those are deprecated.
     39   void Run();
     40 
     41   // Run the current MessageLoop until it doesn't find any tasks or messages in
     42   // the queue (it goes idle). WARNING: This may never return! Only use this
     43   // when repeating tasks such as animated web pages have been shut down.
     44   void RunUntilIdle();
     45 
     46   bool running() const { return running_; }
     47 
     48   // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an
     49   // earlier call to Run() when there aren't any tasks or messages in the queue.
     50   //
     51   // There can be other nested RunLoops servicing the same task queue
     52   // (MessageLoop); Quitting one RunLoop has no bearing on the others. Quit()
     53   // and QuitWhenIdle() can be called before, during or after Run(). If called
     54   // before Run(), Run() will return immediately when called. Calling Quit() or
     55   // QuitWhenIdle() after the RunLoop has already finished running has no
     56   // effect.
     57   //
     58   // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will
     59   // terminate the targetted message loop. If a nested message loop continues
     60   // running, the target may NEVER terminate. It is very easy to livelock (run
     61   // forever) in such a case.
     62   void Quit();
     63   void QuitWhenIdle();
     64 
     65   // Convenience methods to get a closure that safely calls Quit() or
     66   // QuitWhenIdle() (has no effect if the RunLoop instance is gone).
     67   //
     68   // Example:
     69   //   RunLoop run_loop;
     70   //   PostTask(run_loop.QuitClosure());
     71   //   run_loop.Run();
     72   base::Closure QuitClosure();
     73   base::Closure QuitWhenIdleClosure();
     74 
     75  private:
     76   friend class MessageLoop;
     77 #if defined(OS_ANDROID)
     78   // Android doesn't support the blocking MessageLoop::Run, so it calls
     79   // BeforeRun and AfterRun directly.
     80   friend class base::MessagePumpForUI;
     81 #endif
     82 
     83 #if defined(OS_IOS)
     84   // iOS doesn't support the blocking MessageLoop::Run, so it calls
     85   // BeforeRun directly.
     86   friend class base::MessagePumpUIApplication;
     87 #endif
     88 
     89   // Return false to abort the Run.
     90   bool BeforeRun();
     91   void AfterRun();
     92 
     93   MessageLoop* loop_;
     94 
     95   // Parent RunLoop or NULL if this is the top-most RunLoop.
     96   RunLoop* previous_run_loop_;
     97 
     98   // Used to count how many nested Run() invocations are on the stack.
     99   int run_depth_;
    100 
    101   bool run_called_;
    102   bool quit_called_;
    103   bool running_;
    104 
    105   // Used to record that QuitWhenIdle() was called on the MessageLoop, meaning
    106   // that we should quit Run once it becomes idle.
    107   bool quit_when_idle_received_;
    108 
    109   base::ThreadChecker thread_checker_;
    110 
    111   // WeakPtrFactory for QuitClosure safety.
    112   base::WeakPtrFactory<RunLoop> weak_factory_;
    113 
    114   DISALLOW_COPY_AND_ASSIGN(RunLoop);
    115 };
    116 
    117 }  // namespace base
    118 
    119 #endif  // BASE_RUN_LOOP_H_
    120