// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_RUN_LOOP_H_
#define BASE_RUN_LOOP_H_

#include <utility>
#include <vector>

#include "base/base_export.h"
#include "base/callback.h"
#include "base/containers/stack.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "build/build_config.h"

namespace base {
#if defined(OS_ANDROID)
class MessagePumpForUI;
#endif

#if defined(OS_IOS)
class MessagePumpUIApplication;
#endif

class SingleThreadTaskRunner;

// Helper class to run the RunLoop::Delegate associated with the current thread.
// A RunLoop::Delegate must have been bound to this thread (ref.
// RunLoop::RegisterDelegateForCurrentThread()) prior to using any of RunLoop's
// member and static methods unless explicitly indicated otherwise (e.g.
// IsRunning/IsNestedOnCurrentThread()). RunLoop::Run can only be called once
// per RunLoop lifetime. Create a RunLoop on the stack and call Run/Quit to run
// a nested RunLoop but please do not use nested loops in production code!
class BASE_EXPORT RunLoop {
 public:
  // The type of RunLoop: a kDefault RunLoop at the top-level (non-nested) will
  // process system and application tasks assigned to its Delegate. When nested
  // however a kDefault RunLoop will only process system tasks while a
  // kNestableTasksAllowed RunLoop will continue to process application tasks
  // even if nested.
  //
  // This is relevant in the case of recursive RunLoops. Some unwanted run loops
  // may occur when using common controls or printer functions. By default,
  // recursive task processing is disabled.
  //
  // In general, nestable RunLoops are to be avoided. They are dangerous and
  // difficult to get right, so please use with extreme caution.
  //
  // A specific example where this makes a difference is:
  // - The thread is running a RunLoop.
  // - It receives a task #1 and executes it.
  // - The task #1 implicitly starts a RunLoop, like a MessageBox in the unit
  //   test. This can also be StartDoc or GetSaveFileName.
  // - The thread receives a task #2 before or while in this second RunLoop.
  // - With a kNestableTasksAllowed RunLoop, the task #2 will run right away.
  //   Otherwise, it will get executed right after task #1 completes in the main
  //   RunLoop.
  enum class Type {
    kDefault,
    kNestableTasksAllowed,
  };

  RunLoop(Type type = Type::kDefault);
  ~RunLoop();

  // Run the current RunLoop::Delegate. This blocks until Quit is called. Before
  // calling Run, be sure to grab the QuitClosure in order to stop the
  // RunLoop::Delegate asynchronously.
  void Run();

  // Run the current RunLoop::Delegate until it doesn't find any tasks or
  // messages in its queue (it goes idle). WARNING: This may never return! Only
  // use this when repeating tasks such as animated web pages have been shut
  // down.
  void RunUntilIdle();

  bool running() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return running_;
  }

  // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an
  // earlier call to Run() when there aren't any tasks or messages in the queue.
  //
  // These methods are thread-safe but note that Quit() is best-effort when
  // called from another thread (will quit soon but tasks that were already
  // queued on this RunLoop will get to run first).
  //
  // There can be other nested RunLoops servicing the same task queue. Quitting
  // one RunLoop has no bearing on the others. Quit() and QuitWhenIdle() can be
  // called before, during or after Run(). If called before Run(), Run() will
  // return immediately when called. Calling Quit() or QuitWhenIdle() after the
  // RunLoop has already finished running has no effect.
  //
  // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will
  // terminate the targetted message loop. If a nested RunLoop continues
  // running, the target may NEVER terminate. It is very easy to livelock (run
  // forever) in such a case.
  void Quit();
  void QuitWhenIdle();

  // Convenience methods to get a closure that safely calls Quit() or
  // QuitWhenIdle() (has no effect if the RunLoop instance is gone).
  //
  // The resulting Closure is thread-safe (note however that invoking the
  // QuitClosure() from another thread than this RunLoop's will result in an
  // asynchronous rather than immediate Quit()).
  //
  // Example:
  //   RunLoop run_loop;
  //   PostTask(run_loop.QuitClosure());
  //   run_loop.Run();
  Closure QuitClosure();
  Closure QuitWhenIdleClosure();

  // Returns true if there is an active RunLoop on this thread.
  // Safe to call before RegisterDelegateForCurrentThread().
  static bool IsRunningOnCurrentThread();

  // Returns true if there is an active RunLoop on this thread and it's nested
  // within another active RunLoop.
  // Safe to call before RegisterDelegateForCurrentThread().
  static bool IsNestedOnCurrentThread();

  // A NestingObserver is notified when a nested RunLoop begins and ends.
  class BASE_EXPORT NestingObserver {
   public:
    // Notified before a nested loop starts running work on the current thread.
    virtual void OnBeginNestedRunLoop() = 0;
    // Notified after a nested loop is done running work on the current thread.
    virtual void OnExitNestedRunLoop() {}

   protected:
    virtual ~NestingObserver() = default;
  };

  static void AddNestingObserverOnCurrentThread(NestingObserver* observer);
  static void RemoveNestingObserverOnCurrentThread(NestingObserver* observer);

  // A RunLoop::Delegate is a generic interface that allows RunLoop to be
  // separate from the underlying implementation of the message loop for this
  // thread. It holds private state used by RunLoops on its associated thread.
  // One and only one RunLoop::Delegate must be registered on a given thread
  // via RunLoop::RegisterDelegateForCurrentThread() before RunLoop instances
  // and RunLoop static methods can be used on it.
  class BASE_EXPORT Delegate {
   public:
    Delegate();
    virtual ~Delegate();

    // Used by RunLoop to inform its Delegate to Run/Quit. Implementations are
    // expected to keep on running synchronously from the Run() call until the
    // eventual matching Quit() call. Upon receiving a Quit() call it should
    // return from the Run() call as soon as possible without executing
    // remaining tasks/messages. Run() calls can nest in which case each Quit()
    // call should result in the topmost active Run() call returning. The only
    // other trigger for Run() to return is the
    // |should_quit_when_idle_callback_| which the Delegate should probe before
    // sleeping when it becomes idle. |application_tasks_allowed| is true if
    // this is the first Run() call on the stack or it was made from a nested
    // RunLoop of Type::kNestableTasksAllowed (otherwise this Run() level should
    // only process system tasks).
    virtual void Run(bool application_tasks_allowed) = 0;
    virtual void Quit() = 0;

    // Invoked right before a RunLoop enters a nested Run() call on this
    // Delegate iff this RunLoop is of type kNestableTasksAllowed. The Delegate
    // should ensure that the upcoming Run() call will result in processing
    // application tasks queued ahead of it without further probing. e.g.
    // message pumps on some platforms, like Mac, need an explicit request to
    // process application tasks when nested, otherwise they'll only wait for
    // system messages.
    virtual void EnsureWorkScheduled() = 0;

   protected:
    // Returns the result of this Delegate's |should_quit_when_idle_callback_|.
    // "protected" so it can be invoked only by the Delegate itself.
    bool ShouldQuitWhenIdle();

   private:
    // While the state is owned by the Delegate subclass, only RunLoop can use
    // it.
    friend class RunLoop;

    // A vector-based stack is more memory efficient than the default
    // deque-based stack as the active RunLoop stack isn't expected to ever
    // have more than a few entries.
    using RunLoopStack = stack<RunLoop*, std::vector<RunLoop*>>;

    RunLoopStack active_run_loops_;
    ObserverList<RunLoop::NestingObserver>::Unchecked nesting_observers_;

#if DCHECK_IS_ON()
    bool allow_running_for_testing_ = true;
#endif

    // True once this Delegate is bound to a thread via
    // RegisterDelegateForCurrentThread().
    bool bound_ = false;

    // Thread-affine per its use of TLS.
    THREAD_CHECKER(bound_thread_checker_);

    DISALLOW_COPY_AND_ASSIGN(Delegate);
  };

  // Registers |delegate| on the current thread. Must be called once and only
  // once per thread before using RunLoop methods on it. |delegate| is from then
  // on forever bound to that thread (including its destruction).
  static void RegisterDelegateForCurrentThread(Delegate* delegate);

  // Quits the active RunLoop (when idle) -- there must be one. These were
  // introduced as prefered temporary replacements to the long deprecated
  // MessageLoop::Quit(WhenIdle)(Closure) methods. Callers should properly plumb
  // a reference to the appropriate RunLoop instance (or its QuitClosure)
  // instead of using these in order to link Run()/Quit() to a single RunLoop
  // instance and increase readability.
  static void QuitCurrentDeprecated();
  static void QuitCurrentWhenIdleDeprecated();
  static Closure QuitCurrentWhenIdleClosureDeprecated();

  // Configures all RunLoop::Run() calls on the current thread to run the
  // supplied |on_timeout| callback if they run for longer than |timeout|.
  //
  // Specifying Run() timeouts per-thread avoids the need to cope with Run()s
  // executing concurrently with ScopedRunTimeoutForTest initialization or
  // teardown, and allows "default" timeouts to be specified by suites, rather
  // than explicitly configuring them for every RunLoop, in each test.
  //
  // Tests can temporarily override any currently-active Run() timeout, e.g. to
  // allow a step to Run() for longer than the suite's default timeout, by
  // creating a new ScopedRunTimeoutForTest on their stack, e.g:
  //
  //   ScopedRunTimeoutForTest default_timeout(kDefaultRunTimeout);
  //   ... do other test stuff ...
  //   RunLoop().Run(); // Run for up to kDefaultRunTimeout.
  //   ...
  //   {
  //     ScopedRunTimeoutForTest test_specific_timeout(kTestSpecificTimeout);
  //     RunLoop().Run(); // Run for up to kTestSpecificTimeout.
  //   }
  //   ...
  //   RunLoop().Run(); // Run for up to kDefaultRunTimeout.
  //
  // The currently-active timeout can be temporarily disabled by passing a zero
  // timeout e.g:
  //   ScopedRunTimeoutForTest disable_timeout(TimeDelta());
  //
  // ScopedTaskEnvironment applies a default Run() timeout after which a
  // LOG(FATAL) is performed, to dump a crash stack for diagnosis.
  class BASE_EXPORT ScopedRunTimeoutForTest {
   public:
    explicit ScopedRunTimeoutForTest(TimeDelta timeout);
    ScopedRunTimeoutForTest(TimeDelta timeout, RepeatingClosure on_timeout);
    ~ScopedRunTimeoutForTest();

    // Returns the active ScopedRunTimeoutForTest on the calling thread, if any,
    // or null otherwise.
    static const RunLoop::ScopedRunTimeoutForTest* Current();

    TimeDelta timeout() const { return timeout_; }
    const RepeatingClosure& on_timeout() const { return on_timeout_; }

   private:
    const TimeDelta timeout_;
    const RepeatingClosure on_timeout_;
    ScopedRunTimeoutForTest* const nested_timeout_;
    DISALLOW_COPY_AND_ASSIGN(ScopedRunTimeoutForTest);
  };

  // Run() will DCHECK if called while there's a ScopedDisallowRunningForTesting
  // in scope on its thread. This is useful to add safety to some test
  // constructs which allow multiple task runners to share the main thread in
  // unit tests. While the main thread can be shared by multiple runners to
  // deterministically fake multi threading, there can still only be a single
  // RunLoop::Delegate per thread and RunLoop::Run() should only be invoked from
  // it (or it would result in incorrectly driving TaskRunner A while in
  // TaskRunner B's context).
  class BASE_EXPORT ScopedDisallowRunningForTesting {
   public:
    ScopedDisallowRunningForTesting();
    ~ScopedDisallowRunningForTesting();

   private:
#if DCHECK_IS_ON()
    Delegate* current_delegate_;
    const bool previous_run_allowance_;
#endif  // DCHECK_IS_ON()

    DISALLOW_COPY_AND_ASSIGN(ScopedDisallowRunningForTesting);
  };

 private:
  FRIEND_TEST_ALL_PREFIXES(MessageLoopTypedTest, RunLoopQuitOrderAfter);

#if defined(OS_ANDROID)
  // Android doesn't support the blocking RunLoop::Run, so it calls
  // BeforeRun and AfterRun directly.
  friend class MessagePumpForUI;
#endif

#if defined(OS_IOS)
  // iOS doesn't support the blocking RunLoop::Run, so it calls
  // BeforeRun directly.
  friend class MessagePumpUIApplication;
#endif

  // Return false to abort the Run.
  bool BeforeRun();
  void AfterRun();

  // A copy of RunLoop::Delegate for the thread driven by tis RunLoop for quick
  // access without using TLS (also allows access to state from another sequence
  // during Run(), ref. |sequence_checker_| below).
  Delegate* delegate_;

  const Type type_;

#if DCHECK_IS_ON()
  bool run_called_ = false;
#endif

  bool quit_called_ = false;
  bool running_ = false;
  // Used to record that QuitWhenIdle() was called on this RunLoop, meaning that
  // the Delegate should quit Run() once it becomes idle (it's responsible for
  // probing this state via ShouldQuitWhenIdle()). This state is stored here
  // rather than pushed to Delegate to support nested RunLoops.
  bool quit_when_idle_received_ = false;

  // True if use of QuitCurrent*Deprecated() is allowed. Taking a Quit*Closure()
  // from a RunLoop implicitly sets this to false, so QuitCurrent*Deprecated()
  // cannot be used while that RunLoop is being Run().
  bool allow_quit_current_deprecated_ = true;

  // RunLoop is not thread-safe. Its state/methods, unless marked as such, may
  // not be accessed from any other sequence than the thread it was constructed
  // on. Exception: RunLoop can be safely accessed from one other sequence (or
  // single parallel task) during Run() -- e.g. to Quit() without having to
  // plumb ThreatTaskRunnerHandle::Get() throughout a test to repost QuitClosure
  // to origin thread.
  SEQUENCE_CHECKER(sequence_checker_);

  const scoped_refptr<SingleThreadTaskRunner> origin_task_runner_;

  // WeakPtrFactory for QuitClosure safety.
  WeakPtrFactory<RunLoop> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(RunLoop);
};

}  // namespace base

#endif  // BASE_RUN_LOOP_H_
