chromium/base/run_loop.h

// Copyright 2012 The Chromium Authors
// 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 <stack>
#include <utility>
#include <vector>

#include "base/base_export.h"
#include "base/containers/stack.h"
#include "base/dcheck_is_on.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/location.h"
#include "base/memory/raw_ptr.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 {

namespace test {
class ScopedRunLoopTimeout;
class ScopedDisableRunLoopTimeout;
}  // namespace test

#if BUILDFLAG(IS_ANDROID)
class MessagePumpAndroid;
#endif

#if BUILDFLAG(IS_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 avoid nested loops in production code!
class BASE_EXPORT RunLoop {};

// RunLoop::Run() will DCHECK if called while there's a
// ScopedDisallowRunningRunLoop 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 [[maybe_unused, nodiscard]] ScopedDisallowRunningRunLoop {};

}  // namespace base

#endif  // BASE_RUN_LOOP_H_