1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <algorithm>
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <ostream>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/debug/stack_trace.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_forward.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/lazy_instance.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ref.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/message_loop/message_pump.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/message_loop/message_pump_type.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/process/process.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/condition_variable.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/task/common/lazy_now.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/task/sequence_manager/sequence_manager.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/task/sequence_manager/sequence_manager_impl.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/task/sequence_manager/task_queue.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/task/sequence_manager/time_domain.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/task/thread_pool/thread_pool_impl.h"
35*6777b538SAndroid Build Coastguard Worker #include "base/task/thread_pool/thread_pool_instance.h"
36*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
37*6777b538SAndroid Build Coastguard Worker #include "base/test/test_mock_time_task_runner.h"
38*6777b538SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
39*6777b538SAndroid Build Coastguard Worker #include "base/thread_annotations.h"
40*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
41*6777b538SAndroid Build Coastguard Worker #include "base/threading/sequence_local_storage_map.h"
42*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_checker_impl.h"
43*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_local.h"
44*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
45*6777b538SAndroid Build Coastguard Worker #include "base/time/clock.h"
46*6777b538SAndroid Build Coastguard Worker #include "base/time/tick_clock.h"
47*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
48*6777b538SAndroid Build Coastguard Worker #include "base/time/time_override.h"
49*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
50*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
53*6777b538SAndroid Build Coastguard Worker #include <optional>
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Worker #include "base/files/file_descriptor_watcher_posix.h"
56*6777b538SAndroid Build Coastguard Worker #endif
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING)
59*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/trace_log.h" // nogncheck
60*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(ENABLE_BASE_TRACING)
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker namespace base {
63*6777b538SAndroid Build Coastguard Worker namespace test {
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker namespace {
66*6777b538SAndroid Build Coastguard Worker
GetDestructionObservers()67*6777b538SAndroid Build Coastguard Worker ObserverList<TaskEnvironment::DestructionObserver>& GetDestructionObservers() {
68*6777b538SAndroid Build Coastguard Worker static NoDestructor<ObserverList<TaskEnvironment::DestructionObserver>>
69*6777b538SAndroid Build Coastguard Worker instance;
70*6777b538SAndroid Build Coastguard Worker return *instance;
71*6777b538SAndroid Build Coastguard Worker }
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker // A pointer to the current TestTaskTracker, if any, constant throughout the
74*6777b538SAndroid Build Coastguard Worker // lifetime of a ThreadPoolInstance managed by a TaskEnvironment.
75*6777b538SAndroid Build Coastguard Worker TaskEnvironment::TestTaskTracker* g_task_tracker = nullptr;
76*6777b538SAndroid Build Coastguard Worker
GetMessagePumpTypeForMainThreadType(TaskEnvironment::MainThreadType main_thread_type)77*6777b538SAndroid Build Coastguard Worker base::MessagePumpType GetMessagePumpTypeForMainThreadType(
78*6777b538SAndroid Build Coastguard Worker TaskEnvironment::MainThreadType main_thread_type) {
79*6777b538SAndroid Build Coastguard Worker switch (main_thread_type) {
80*6777b538SAndroid Build Coastguard Worker case TaskEnvironment::MainThreadType::DEFAULT:
81*6777b538SAndroid Build Coastguard Worker return MessagePumpType::DEFAULT;
82*6777b538SAndroid Build Coastguard Worker case TaskEnvironment::MainThreadType::UI:
83*6777b538SAndroid Build Coastguard Worker return MessagePumpType::UI;
84*6777b538SAndroid Build Coastguard Worker case TaskEnvironment::MainThreadType::IO:
85*6777b538SAndroid Build Coastguard Worker return MessagePumpType::IO;
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker NOTREACHED();
88*6777b538SAndroid Build Coastguard Worker return MessagePumpType::DEFAULT;
89*6777b538SAndroid Build Coastguard Worker }
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker std::unique_ptr<sequence_manager::SequenceManager>
CreateSequenceManagerForMainThreadType(TaskEnvironment::MainThreadType main_thread_type,sequence_manager::SequenceManager::PrioritySettings priority_settings)92*6777b538SAndroid Build Coastguard Worker CreateSequenceManagerForMainThreadType(
93*6777b538SAndroid Build Coastguard Worker TaskEnvironment::MainThreadType main_thread_type,
94*6777b538SAndroid Build Coastguard Worker sequence_manager::SequenceManager::PrioritySettings priority_settings) {
95*6777b538SAndroid Build Coastguard Worker auto type = GetMessagePumpTypeForMainThreadType(main_thread_type);
96*6777b538SAndroid Build Coastguard Worker return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
97*6777b538SAndroid Build Coastguard Worker MessagePump::Create(type),
98*6777b538SAndroid Build Coastguard Worker base::sequence_manager::SequenceManager::Settings::Builder()
99*6777b538SAndroid Build Coastguard Worker .SetMessagePumpType(type)
100*6777b538SAndroid Build Coastguard Worker .SetPrioritySettings(std::move(priority_settings))
101*6777b538SAndroid Build Coastguard Worker .Build());
102*6777b538SAndroid Build Coastguard Worker }
103*6777b538SAndroid Build Coastguard Worker
104*6777b538SAndroid Build Coastguard Worker class TickClockBasedClock : public Clock {
105*6777b538SAndroid Build Coastguard Worker public:
TickClockBasedClock(const TickClock * tick_clock)106*6777b538SAndroid Build Coastguard Worker explicit TickClockBasedClock(const TickClock* tick_clock)
107*6777b538SAndroid Build Coastguard Worker : tick_clock_(*tick_clock),
108*6777b538SAndroid Build Coastguard Worker start_ticks_(tick_clock_->NowTicks()),
109*6777b538SAndroid Build Coastguard Worker start_time_(Time::UnixEpoch()) {}
110*6777b538SAndroid Build Coastguard Worker
Now() const111*6777b538SAndroid Build Coastguard Worker Time Now() const override {
112*6777b538SAndroid Build Coastguard Worker return start_time_ + (tick_clock_->NowTicks() - start_ticks_);
113*6777b538SAndroid Build Coastguard Worker }
114*6777b538SAndroid Build Coastguard Worker
115*6777b538SAndroid Build Coastguard Worker private:
116*6777b538SAndroid Build Coastguard Worker const raw_ref<const TickClock> tick_clock_;
117*6777b538SAndroid Build Coastguard Worker const TimeTicks start_ticks_;
118*6777b538SAndroid Build Coastguard Worker const Time start_time_;
119*6777b538SAndroid Build Coastguard Worker };
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard Worker } // namespace
122*6777b538SAndroid Build Coastguard Worker
123*6777b538SAndroid Build Coastguard Worker class TaskEnvironment::TestTaskTracker
124*6777b538SAndroid Build Coastguard Worker : public internal::ThreadPoolImpl::TaskTrackerImpl {
125*6777b538SAndroid Build Coastguard Worker public:
126*6777b538SAndroid Build Coastguard Worker TestTaskTracker();
127*6777b538SAndroid Build Coastguard Worker
128*6777b538SAndroid Build Coastguard Worker TestTaskTracker(const TestTaskTracker&) = delete;
129*6777b538SAndroid Build Coastguard Worker TestTaskTracker& operator=(const TestTaskTracker&) = delete;
130*6777b538SAndroid Build Coastguard Worker
131*6777b538SAndroid Build Coastguard Worker // Allow running tasks. Returns whether tasks were previously allowed to run.
132*6777b538SAndroid Build Coastguard Worker bool AllowRunTasks();
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard Worker // Disallow running tasks. Returns true on success; success requires there to
135*6777b538SAndroid Build Coastguard Worker // be no tasks currently running. Returns false if >0 tasks are currently
136*6777b538SAndroid Build Coastguard Worker // running. Prior to returning false, it will attempt to block until at least
137*6777b538SAndroid Build Coastguard Worker // one task has completed (in an attempt to avoid callers busy-looping
138*6777b538SAndroid Build Coastguard Worker // DisallowRunTasks() calls with the same set of slowly ongoing tasks).
139*6777b538SAndroid Build Coastguard Worker // Returns false if none of the ongoing tasks complete within |timeout| in an
140*6777b538SAndroid Build Coastguard Worker // attempt to prevent a deadlock in the event that the only task remaining is
141*6777b538SAndroid Build Coastguard Worker // blocked on the main thread.
142*6777b538SAndroid Build Coastguard Worker bool DisallowRunTasks(TimeDelta timeout = Milliseconds(1));
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker // Returns true if tasks are currently allowed to run.
145*6777b538SAndroid Build Coastguard Worker bool TasksAllowedToRun() const;
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard Worker // For debugging purposes. Returns a string with information about all the
148*6777b538SAndroid Build Coastguard Worker // currently running tasks on the thread pool.
149*6777b538SAndroid Build Coastguard Worker std::string DescribeRunningTasks() const;
150*6777b538SAndroid Build Coastguard Worker
151*6777b538SAndroid Build Coastguard Worker // Returns true if this is invoked on this TaskTracker's owning thread
152*6777b538SAndroid Build Coastguard Worker // (i.e. test main thread).
OnControllerThread() const153*6777b538SAndroid Build Coastguard Worker bool OnControllerThread() const {
154*6777b538SAndroid Build Coastguard Worker return controller_thread_checker_.CalledOnValidThread();
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker
157*6777b538SAndroid Build Coastguard Worker private:
158*6777b538SAndroid Build Coastguard Worker friend class TaskEnvironment;
159*6777b538SAndroid Build Coastguard Worker
160*6777b538SAndroid Build Coastguard Worker // internal::ThreadPoolImpl::TaskTrackerImpl:
161*6777b538SAndroid Build Coastguard Worker void RunTask(internal::Task task,
162*6777b538SAndroid Build Coastguard Worker internal::TaskSource* sequence,
163*6777b538SAndroid Build Coastguard Worker const TaskTraits& traits) override;
164*6777b538SAndroid Build Coastguard Worker void BeginCompleteShutdown(base::WaitableEvent& shutdown_event) override;
165*6777b538SAndroid Build Coastguard Worker void AssertFlushForTestingAllowed() override;
166*6777b538SAndroid Build Coastguard Worker
167*6777b538SAndroid Build Coastguard Worker // Synchronizes accesses to members below.
168*6777b538SAndroid Build Coastguard Worker mutable Lock lock_;
169*6777b538SAndroid Build Coastguard Worker
170*6777b538SAndroid Build Coastguard Worker // True if running tasks is allowed.
171*6777b538SAndroid Build Coastguard Worker bool can_run_tasks_ GUARDED_BY(lock_) = true;
172*6777b538SAndroid Build Coastguard Worker
173*6777b538SAndroid Build Coastguard Worker // Signaled when |can_run_tasks_| becomes true.
174*6777b538SAndroid Build Coastguard Worker ConditionVariable can_run_tasks_cv_ GUARDED_BY(lock_);
175*6777b538SAndroid Build Coastguard Worker
176*6777b538SAndroid Build Coastguard Worker // Signaled when a task is completed.
177*6777b538SAndroid Build Coastguard Worker ConditionVariable task_completed_cv_ GUARDED_BY(lock_);
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker // Next task number so that each task has some unique-ish id.
180*6777b538SAndroid Build Coastguard Worker int64_t next_task_number_ GUARDED_BY(lock_) = 1;
181*6777b538SAndroid Build Coastguard Worker // The set of tasks currently running, keyed by the id from
182*6777b538SAndroid Build Coastguard Worker // |next_task_number_|.
183*6777b538SAndroid Build Coastguard Worker base::flat_map<int64_t, Location> running_tasks_ GUARDED_BY(lock_);
184*6777b538SAndroid Build Coastguard Worker
185*6777b538SAndroid Build Coastguard Worker // Used to implement OnControllerThread().
186*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl controller_thread_checker_;
187*6777b538SAndroid Build Coastguard Worker };
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Worker class TaskEnvironment::MockTimeDomain : public sequence_manager::TimeDomain {
190*6777b538SAndroid Build Coastguard Worker public:
MockTimeDomain(sequence_manager::internal::SequenceManagerImpl * sequence_manager)191*6777b538SAndroid Build Coastguard Worker explicit MockTimeDomain(
192*6777b538SAndroid Build Coastguard Worker sequence_manager::internal::SequenceManagerImpl* sequence_manager)
193*6777b538SAndroid Build Coastguard Worker : sequence_manager_(sequence_manager) {
194*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(nullptr, current_mock_time_domain_);
195*6777b538SAndroid Build Coastguard Worker current_mock_time_domain_ = this;
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker
~MockTimeDomain()198*6777b538SAndroid Build Coastguard Worker ~MockTimeDomain() override {
199*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(this, current_mock_time_domain_);
200*6777b538SAndroid Build Coastguard Worker current_mock_time_domain_ = nullptr;
201*6777b538SAndroid Build Coastguard Worker }
202*6777b538SAndroid Build Coastguard Worker
203*6777b538SAndroid Build Coastguard Worker static MockTimeDomain* current_mock_time_domain_;
204*6777b538SAndroid Build Coastguard Worker
GetTime()205*6777b538SAndroid Build Coastguard Worker static Time GetTime() {
206*6777b538SAndroid Build Coastguard Worker return Time::UnixEpoch() +
207*6777b538SAndroid Build Coastguard Worker (current_mock_time_domain_->NowTicks() - TimeTicks());
208*6777b538SAndroid Build Coastguard Worker }
209*6777b538SAndroid Build Coastguard Worker
GetTimeTicks()210*6777b538SAndroid Build Coastguard Worker static TimeTicks GetTimeTicks() {
211*6777b538SAndroid Build Coastguard Worker return current_mock_time_domain_->NowTicks();
212*6777b538SAndroid Build Coastguard Worker }
213*6777b538SAndroid Build Coastguard Worker
GetLiveTicks()214*6777b538SAndroid Build Coastguard Worker static LiveTicks GetLiveTicks() {
215*6777b538SAndroid Build Coastguard Worker return current_mock_time_domain_->NowLiveTicks();
216*6777b538SAndroid Build Coastguard Worker }
217*6777b538SAndroid Build Coastguard Worker
AdvanceClock(TimeDelta delta)218*6777b538SAndroid Build Coastguard Worker void AdvanceClock(TimeDelta delta) {
219*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
220*6777b538SAndroid Build Coastguard Worker {
221*6777b538SAndroid Build Coastguard Worker AutoLock lock(now_ticks_lock_);
222*6777b538SAndroid Build Coastguard Worker now_ticks_ += delta;
223*6777b538SAndroid Build Coastguard Worker live_ticks_ += delta;
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker
226*6777b538SAndroid Build Coastguard Worker if (thread_pool_) {
227*6777b538SAndroid Build Coastguard Worker thread_pool_->ProcessRipeDelayedTasksForTesting();
228*6777b538SAndroid Build Coastguard Worker }
229*6777b538SAndroid Build Coastguard Worker }
230*6777b538SAndroid Build Coastguard Worker
SuspendedAdvanceClock(TimeDelta delta)231*6777b538SAndroid Build Coastguard Worker void SuspendedAdvanceClock(TimeDelta delta) {
232*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
233*6777b538SAndroid Build Coastguard Worker {
234*6777b538SAndroid Build Coastguard Worker AutoLock lock(now_ticks_lock_);
235*6777b538SAndroid Build Coastguard Worker now_ticks_ += delta;
236*6777b538SAndroid Build Coastguard Worker }
237*6777b538SAndroid Build Coastguard Worker
238*6777b538SAndroid Build Coastguard Worker if (thread_pool_) {
239*6777b538SAndroid Build Coastguard Worker thread_pool_->ProcessRipeDelayedTasksForTesting();
240*6777b538SAndroid Build Coastguard Worker }
241*6777b538SAndroid Build Coastguard Worker }
242*6777b538SAndroid Build Coastguard Worker
SetThreadPool(internal::ThreadPoolImpl * thread_pool,const TestTaskTracker * thread_pool_task_tracker)243*6777b538SAndroid Build Coastguard Worker void SetThreadPool(internal::ThreadPoolImpl* thread_pool,
244*6777b538SAndroid Build Coastguard Worker const TestTaskTracker* thread_pool_task_tracker) {
245*6777b538SAndroid Build Coastguard Worker DCHECK(!thread_pool_);
246*6777b538SAndroid Build Coastguard Worker DCHECK(!thread_pool_task_tracker_);
247*6777b538SAndroid Build Coastguard Worker thread_pool_ = thread_pool;
248*6777b538SAndroid Build Coastguard Worker thread_pool_task_tracker_ = thread_pool_task_tracker;
249*6777b538SAndroid Build Coastguard Worker }
250*6777b538SAndroid Build Coastguard Worker
251*6777b538SAndroid Build Coastguard Worker // sequence_manager::TimeDomain:
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Worker // This method is called when the underlying message pump has run out of
254*6777b538SAndroid Build Coastguard Worker // non-delayed work. Advances time to the next task unless
255*6777b538SAndroid Build Coastguard Worker // |quit_when_idle_requested| or TaskEnvironment controls mock time.
MaybeFastForwardToWakeUp(std::optional<sequence_manager::WakeUp> next_wake_up,bool quit_when_idle_requested)256*6777b538SAndroid Build Coastguard Worker bool MaybeFastForwardToWakeUp(
257*6777b538SAndroid Build Coastguard Worker std::optional<sequence_manager::WakeUp> next_wake_up,
258*6777b538SAndroid Build Coastguard Worker bool quit_when_idle_requested) override {
259*6777b538SAndroid Build Coastguard Worker if (quit_when_idle_requested) {
260*6777b538SAndroid Build Coastguard Worker return false;
261*6777b538SAndroid Build Coastguard Worker }
262*6777b538SAndroid Build Coastguard Worker
263*6777b538SAndroid Build Coastguard Worker return FastForwardToNextTaskOrCap(next_wake_up, TimeTicks::Max(),
264*6777b538SAndroid Build Coastguard Worker /*advance_live_ticks=*/true) ==
265*6777b538SAndroid Build Coastguard Worker NextTaskSource::kMainThreadHasWork;
266*6777b538SAndroid Build Coastguard Worker }
267*6777b538SAndroid Build Coastguard Worker
GetName() const268*6777b538SAndroid Build Coastguard Worker const char* GetName() const override { return "MockTimeDomain"; }
269*6777b538SAndroid Build Coastguard Worker
270*6777b538SAndroid Build Coastguard Worker // TickClock implementation:
NowTicks() const271*6777b538SAndroid Build Coastguard Worker TimeTicks NowTicks() const override {
272*6777b538SAndroid Build Coastguard Worker // This can be called from any thread.
273*6777b538SAndroid Build Coastguard Worker AutoLock lock(now_ticks_lock_);
274*6777b538SAndroid Build Coastguard Worker return now_ticks_;
275*6777b538SAndroid Build Coastguard Worker }
276*6777b538SAndroid Build Coastguard Worker
NowLiveTicks() const277*6777b538SAndroid Build Coastguard Worker LiveTicks NowLiveTicks() const {
278*6777b538SAndroid Build Coastguard Worker AutoLock lock(now_ticks_lock_);
279*6777b538SAndroid Build Coastguard Worker return live_ticks_;
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker
282*6777b538SAndroid Build Coastguard Worker // Used by FastForwardToNextTaskOrCap() to return which task source time was
283*6777b538SAndroid Build Coastguard Worker // advanced to.
284*6777b538SAndroid Build Coastguard Worker enum class NextTaskSource {
285*6777b538SAndroid Build Coastguard Worker // Out of tasks under |fast_forward_cap|.
286*6777b538SAndroid Build Coastguard Worker kNone,
287*6777b538SAndroid Build Coastguard Worker // There's now >=1 immediate task on the main thread (ThreadPool might have
288*6777b538SAndroid Build Coastguard Worker // some too).
289*6777b538SAndroid Build Coastguard Worker kMainThreadHasWork,
290*6777b538SAndroid Build Coastguard Worker // There's now >=1 immediate task in the thread pool.
291*6777b538SAndroid Build Coastguard Worker kThreadPoolOnly,
292*6777b538SAndroid Build Coastguard Worker };
293*6777b538SAndroid Build Coastguard Worker
AdvanceTimesToNextTaskTimeOrCap(TimeTicks next_task_time,bool advance_live_ticks)294*6777b538SAndroid Build Coastguard Worker void AdvanceTimesToNextTaskTimeOrCap(TimeTicks next_task_time,
295*6777b538SAndroid Build Coastguard Worker bool advance_live_ticks) {
296*6777b538SAndroid Build Coastguard Worker AutoLock lock(now_ticks_lock_);
297*6777b538SAndroid Build Coastguard Worker
298*6777b538SAndroid Build Coastguard Worker TimeTicks next_now = std::max(now_ticks_, next_task_time);
299*6777b538SAndroid Build Coastguard Worker if (advance_live_ticks) {
300*6777b538SAndroid Build Coastguard Worker live_ticks_ += (next_now - now_ticks_);
301*6777b538SAndroid Build Coastguard Worker }
302*6777b538SAndroid Build Coastguard Worker now_ticks_ = next_now;
303*6777b538SAndroid Build Coastguard Worker }
304*6777b538SAndroid Build Coastguard Worker
305*6777b538SAndroid Build Coastguard Worker // Advances time to the first of : next main thread delayed task, next thread
306*6777b538SAndroid Build Coastguard Worker // pool task, or |fast_forward_cap| (if it's not Max()). Ignores immediate
307*6777b538SAndroid Build Coastguard Worker // tasks, expected to be called after being just idle, racily scheduling
308*6777b538SAndroid Build Coastguard Worker // immediate tasks doesn't affect the outcome of this call.
309*6777b538SAndroid Build Coastguard Worker // If `advance_live_ticks` is true, the mock `LiveTicks` will also be advanced
310*6777b538SAndroid Build Coastguard Worker // by the same amount. If false, `LiveTicks` won't be advanced (behaving as if
311*6777b538SAndroid Build Coastguard Worker // the system was suspended).
FastForwardToNextTaskOrCap(std::optional<sequence_manager::WakeUp> next_main_thread_wake_up,TimeTicks fast_forward_cap,bool advance_live_ticks)312*6777b538SAndroid Build Coastguard Worker NextTaskSource FastForwardToNextTaskOrCap(
313*6777b538SAndroid Build Coastguard Worker std::optional<sequence_manager::WakeUp> next_main_thread_wake_up,
314*6777b538SAndroid Build Coastguard Worker TimeTicks fast_forward_cap,
315*6777b538SAndroid Build Coastguard Worker bool advance_live_ticks) {
316*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
317*6777b538SAndroid Build Coastguard Worker
318*6777b538SAndroid Build Coastguard Worker // Consider the next thread pool tasks iff they're running.
319*6777b538SAndroid Build Coastguard Worker std::optional<TimeTicks> next_thread_pool_task_time;
320*6777b538SAndroid Build Coastguard Worker if (thread_pool_ && thread_pool_task_tracker_->TasksAllowedToRun()) {
321*6777b538SAndroid Build Coastguard Worker next_thread_pool_task_time =
322*6777b538SAndroid Build Coastguard Worker thread_pool_->NextScheduledRunTimeForTesting();
323*6777b538SAndroid Build Coastguard Worker }
324*6777b538SAndroid Build Coastguard Worker
325*6777b538SAndroid Build Coastguard Worker // Custom comparison logic to consider nullopt the largest rather than
326*6777b538SAndroid Build Coastguard Worker // smallest value. Could consider using TimeTicks::Max() instead of nullopt
327*6777b538SAndroid Build Coastguard Worker // to represent out-of-tasks?
328*6777b538SAndroid Build Coastguard Worker std::optional<TimeTicks> next_task_time;
329*6777b538SAndroid Build Coastguard Worker if (!next_main_thread_wake_up) {
330*6777b538SAndroid Build Coastguard Worker next_task_time = next_thread_pool_task_time;
331*6777b538SAndroid Build Coastguard Worker } else if (!next_thread_pool_task_time) {
332*6777b538SAndroid Build Coastguard Worker next_task_time = next_main_thread_wake_up->time;
333*6777b538SAndroid Build Coastguard Worker } else {
334*6777b538SAndroid Build Coastguard Worker next_task_time =
335*6777b538SAndroid Build Coastguard Worker std::min(next_main_thread_wake_up->time, *next_thread_pool_task_time);
336*6777b538SAndroid Build Coastguard Worker }
337*6777b538SAndroid Build Coastguard Worker
338*6777b538SAndroid Build Coastguard Worker if (next_task_time && *next_task_time <= fast_forward_cap) {
339*6777b538SAndroid Build Coastguard Worker {
340*6777b538SAndroid Build Coastguard Worker // It's possible for |next_task_time| to be in the past in the following
341*6777b538SAndroid Build Coastguard Worker // scenario:
342*6777b538SAndroid Build Coastguard Worker // Start with Now() == 100ms
343*6777b538SAndroid Build Coastguard Worker // Thread A : Post 200ms delayed task T (construct and enqueue)
344*6777b538SAndroid Build Coastguard Worker // Thread B : Construct 20ms delayed task U
345*6777b538SAndroid Build Coastguard Worker // => |delayed_run_time| == 120ms.
346*6777b538SAndroid Build Coastguard Worker // Thread A : FastForwardToNextTaskOrCap() => fast-forwards to T @
347*6777b538SAndroid Build Coastguard Worker // 300ms (task U is not yet in queue).
348*6777b538SAndroid Build Coastguard Worker // Thread B : Complete enqueue of task U.
349*6777b538SAndroid Build Coastguard Worker // Thread A : FastForwardToNextTaskOrCap() => must stay at 300ms and run
350*6777b538SAndroid Build Coastguard Worker // U, not go back to 120ms.
351*6777b538SAndroid Build Coastguard Worker // Hence we need std::max() to protect against this because construction
352*6777b538SAndroid Build Coastguard Worker // and enqueuing isn't atomic in time (LazyNow support in
353*6777b538SAndroid Build Coastguard Worker // base/task/thread_pool could help).
354*6777b538SAndroid Build Coastguard Worker AdvanceTimesToNextTaskTimeOrCap(*next_task_time, advance_live_ticks);
355*6777b538SAndroid Build Coastguard Worker }
356*6777b538SAndroid Build Coastguard Worker
357*6777b538SAndroid Build Coastguard Worker if (next_task_time == next_thread_pool_task_time) {
358*6777b538SAndroid Build Coastguard Worker thread_pool_->ProcessRipeDelayedTasksForTesting();
359*6777b538SAndroid Build Coastguard Worker }
360*6777b538SAndroid Build Coastguard Worker
361*6777b538SAndroid Build Coastguard Worker if (next_main_thread_wake_up &&
362*6777b538SAndroid Build Coastguard Worker next_task_time == next_main_thread_wake_up->time) {
363*6777b538SAndroid Build Coastguard Worker return NextTaskSource::kMainThreadHasWork;
364*6777b538SAndroid Build Coastguard Worker }
365*6777b538SAndroid Build Coastguard Worker
366*6777b538SAndroid Build Coastguard Worker // The main thread doesn't have immediate work so it'll go to sleep after
367*6777b538SAndroid Build Coastguard Worker // returning from this call. We must make sure it wakes up when the
368*6777b538SAndroid Build Coastguard Worker // ThreadPool is done or the test may stall : crbug.com/1263149.
369*6777b538SAndroid Build Coastguard Worker //
370*6777b538SAndroid Build Coastguard Worker // Note: It is necessary to reach in SequenceManagerImpl to ScheduleWork
371*6777b538SAndroid Build Coastguard Worker // instead of alternatives to waking the main thread, like posting a
372*6777b538SAndroid Build Coastguard Worker // no-op task, as alternatives would prevent the main thread from
373*6777b538SAndroid Build Coastguard Worker // achieving quiescence (which some task monitoring tests verify).
374*6777b538SAndroid Build Coastguard Worker thread_pool_->FlushAsyncForTesting(BindOnce(
375*6777b538SAndroid Build Coastguard Worker &sequence_manager::internal::SequenceManagerImpl::ScheduleWork,
376*6777b538SAndroid Build Coastguard Worker Unretained(sequence_manager_)));
377*6777b538SAndroid Build Coastguard Worker return NextTaskSource::kThreadPoolOnly;
378*6777b538SAndroid Build Coastguard Worker }
379*6777b538SAndroid Build Coastguard Worker
380*6777b538SAndroid Build Coastguard Worker if (!fast_forward_cap.is_max()) {
381*6777b538SAndroid Build Coastguard Worker // It's possible that Now() is already beyond |fast_forward_cap| when the
382*6777b538SAndroid Build Coastguard Worker // caller nests multiple FastForwardBy() calls.
383*6777b538SAndroid Build Coastguard Worker AdvanceTimesToNextTaskTimeOrCap(fast_forward_cap, advance_live_ticks);
384*6777b538SAndroid Build Coastguard Worker }
385*6777b538SAndroid Build Coastguard Worker
386*6777b538SAndroid Build Coastguard Worker return NextTaskSource::kNone;
387*6777b538SAndroid Build Coastguard Worker }
388*6777b538SAndroid Build Coastguard Worker
389*6777b538SAndroid Build Coastguard Worker private:
390*6777b538SAndroid Build Coastguard Worker SEQUENCE_CHECKER(sequence_checker_);
391*6777b538SAndroid Build Coastguard Worker
392*6777b538SAndroid Build Coastguard Worker raw_ptr<internal::ThreadPoolImpl, DanglingUntriaged> thread_pool_ = nullptr;
393*6777b538SAndroid Build Coastguard Worker raw_ptr<const TestTaskTracker, DanglingUntriaged> thread_pool_task_tracker_ =
394*6777b538SAndroid Build Coastguard Worker nullptr;
395*6777b538SAndroid Build Coastguard Worker
396*6777b538SAndroid Build Coastguard Worker const raw_ptr<sequence_manager::internal::SequenceManagerImpl,
397*6777b538SAndroid Build Coastguard Worker DanglingUntriaged>
398*6777b538SAndroid Build Coastguard Worker sequence_manager_;
399*6777b538SAndroid Build Coastguard Worker
400*6777b538SAndroid Build Coastguard Worker // Protects `now_ticks_` and `live_ticks_`
401*6777b538SAndroid Build Coastguard Worker mutable Lock now_ticks_lock_;
402*6777b538SAndroid Build Coastguard Worker
403*6777b538SAndroid Build Coastguard Worker // Only ever written to from the main sequence. Start from real Now() instead
404*6777b538SAndroid Build Coastguard Worker // of zero to give a more realistic view to tests.
GUARDED_BY(now_ticks_lock_)405*6777b538SAndroid Build Coastguard Worker TimeTicks now_ticks_ GUARDED_BY(now_ticks_lock_){
406*6777b538SAndroid Build Coastguard Worker base::subtle::TimeTicksNowIgnoringOverride()
407*6777b538SAndroid Build Coastguard Worker .SnappedToNextTick(TimeTicks(), Milliseconds(1))};
408*6777b538SAndroid Build Coastguard Worker
409*6777b538SAndroid Build Coastguard Worker // Only ever written to from the main sequence. Start from real Now() instead
410*6777b538SAndroid Build Coastguard Worker // of zero to give a more realistic view to tests.
GUARDED_BY(now_ticks_lock_)411*6777b538SAndroid Build Coastguard Worker LiveTicks live_ticks_ GUARDED_BY(now_ticks_lock_){
412*6777b538SAndroid Build Coastguard Worker base::subtle::LiveTicksNowIgnoringOverride()};
413*6777b538SAndroid Build Coastguard Worker };
414*6777b538SAndroid Build Coastguard Worker
415*6777b538SAndroid Build Coastguard Worker TaskEnvironment::MockTimeDomain*
416*6777b538SAndroid Build Coastguard Worker TaskEnvironment::MockTimeDomain::current_mock_time_domain_ = nullptr;
417*6777b538SAndroid Build Coastguard Worker
TaskEnvironment(sequence_manager::SequenceManager::PrioritySettings priority_settings,TimeSource time_source,MainThreadType main_thread_type,ThreadPoolExecutionMode thread_pool_execution_mode,ThreadingMode threading_mode,ThreadPoolCOMEnvironment thread_pool_com_environment,bool subclass_creates_default_taskrunner,trait_helpers::NotATraitTag)418*6777b538SAndroid Build Coastguard Worker TaskEnvironment::TaskEnvironment(
419*6777b538SAndroid Build Coastguard Worker sequence_manager::SequenceManager::PrioritySettings priority_settings,
420*6777b538SAndroid Build Coastguard Worker TimeSource time_source,
421*6777b538SAndroid Build Coastguard Worker MainThreadType main_thread_type,
422*6777b538SAndroid Build Coastguard Worker ThreadPoolExecutionMode thread_pool_execution_mode,
423*6777b538SAndroid Build Coastguard Worker ThreadingMode threading_mode,
424*6777b538SAndroid Build Coastguard Worker ThreadPoolCOMEnvironment thread_pool_com_environment,
425*6777b538SAndroid Build Coastguard Worker bool subclass_creates_default_taskrunner,
426*6777b538SAndroid Build Coastguard Worker trait_helpers::NotATraitTag)
427*6777b538SAndroid Build Coastguard Worker : main_thread_type_(main_thread_type),
428*6777b538SAndroid Build Coastguard Worker thread_pool_execution_mode_(thread_pool_execution_mode),
429*6777b538SAndroid Build Coastguard Worker threading_mode_(threading_mode),
430*6777b538SAndroid Build Coastguard Worker thread_pool_com_environment_(thread_pool_com_environment),
431*6777b538SAndroid Build Coastguard Worker subclass_creates_default_taskrunner_(subclass_creates_default_taskrunner),
432*6777b538SAndroid Build Coastguard Worker sequence_manager_(
433*6777b538SAndroid Build Coastguard Worker CreateSequenceManagerForMainThreadType(main_thread_type,
434*6777b538SAndroid Build Coastguard Worker std::move(priority_settings))),
435*6777b538SAndroid Build Coastguard Worker mock_time_domain_(
436*6777b538SAndroid Build Coastguard Worker time_source != TimeSource::SYSTEM_TIME
437*6777b538SAndroid Build Coastguard Worker ? std::make_unique<TaskEnvironment::MockTimeDomain>(
438*6777b538SAndroid Build Coastguard Worker static_cast<
439*6777b538SAndroid Build Coastguard Worker sequence_manager::internal::SequenceManagerImpl*>(
440*6777b538SAndroid Build Coastguard Worker sequence_manager_.get()))
441*6777b538SAndroid Build Coastguard Worker : nullptr),
442*6777b538SAndroid Build Coastguard Worker time_overrides_(time_source == TimeSource::MOCK_TIME
443*6777b538SAndroid Build Coastguard Worker ? std::make_unique<subtle::ScopedTimeClockOverrides>(
444*6777b538SAndroid Build Coastguard Worker &MockTimeDomain::GetTime,
445*6777b538SAndroid Build Coastguard Worker &MockTimeDomain::GetTimeTicks,
446*6777b538SAndroid Build Coastguard Worker nullptr,
447*6777b538SAndroid Build Coastguard Worker &MockTimeDomain::GetLiveTicks)
448*6777b538SAndroid Build Coastguard Worker : nullptr),
449*6777b538SAndroid Build Coastguard Worker mock_clock_(mock_time_domain_ ? std::make_unique<TickClockBasedClock>(
450*6777b538SAndroid Build Coastguard Worker mock_time_domain_.get())
451*6777b538SAndroid Build Coastguard Worker : nullptr),
452*6777b538SAndroid Build Coastguard Worker scoped_lazy_task_runner_list_for_testing_(
453*6777b538SAndroid Build Coastguard Worker std::make_unique<internal::ScopedLazyTaskRunnerListForTesting>()),
454*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/922098): Enable Run() timeouts even for
455*6777b538SAndroid Build Coastguard Worker // instances created with TimeSource::MOCK_TIME.
456*6777b538SAndroid Build Coastguard Worker run_loop_timeout_(
457*6777b538SAndroid Build Coastguard Worker mock_time_domain_
458*6777b538SAndroid Build Coastguard Worker ? nullptr
459*6777b538SAndroid Build Coastguard Worker : std::make_unique<ScopedRunLoopTimeout>(
460*6777b538SAndroid Build Coastguard Worker FROM_HERE,
461*6777b538SAndroid Build Coastguard Worker TestTimeouts::action_timeout(),
462*6777b538SAndroid Build Coastguard Worker BindRepeating(&sequence_manager::SequenceManager::
463*6777b538SAndroid Build Coastguard Worker DescribeAllPendingTasks,
464*6777b538SAndroid Build Coastguard Worker Unretained(sequence_manager_.get())))) {
465*6777b538SAndroid Build Coastguard Worker CHECK(!base::SingleThreadTaskRunner::HasCurrentDefault());
466*6777b538SAndroid Build Coastguard Worker // If |subclass_creates_default_taskrunner| is true then initialization is
467*6777b538SAndroid Build Coastguard Worker // deferred until DeferredInitFromSubclass().
468*6777b538SAndroid Build Coastguard Worker if (!subclass_creates_default_taskrunner) {
469*6777b538SAndroid Build Coastguard Worker task_queue_ =
470*6777b538SAndroid Build Coastguard Worker sequence_manager_->CreateTaskQueue(sequence_manager::TaskQueue::Spec(
471*6777b538SAndroid Build Coastguard Worker sequence_manager::QueueName::TASK_ENVIRONMENT_DEFAULT_TQ));
472*6777b538SAndroid Build Coastguard Worker task_runner_ = task_queue_->task_runner();
473*6777b538SAndroid Build Coastguard Worker sequence_manager_->SetDefaultTaskRunner(task_runner_);
474*6777b538SAndroid Build Coastguard Worker if (mock_time_domain_) {
475*6777b538SAndroid Build Coastguard Worker sequence_manager_->SetTimeDomain(mock_time_domain_.get());
476*6777b538SAndroid Build Coastguard Worker }
477*6777b538SAndroid Build Coastguard Worker CHECK(base::SingleThreadTaskRunner::HasCurrentDefault())
478*6777b538SAndroid Build Coastguard Worker << "SingleThreadTaskRunner::CurrentDefaultHandle should've been set "
479*6777b538SAndroid Build Coastguard Worker "now.";
480*6777b538SAndroid Build Coastguard Worker CompleteInitialization();
481*6777b538SAndroid Build Coastguard Worker }
482*6777b538SAndroid Build Coastguard Worker
483*6777b538SAndroid Build Coastguard Worker if (threading_mode_ != ThreadingMode::MAIN_THREAD_ONLY) {
484*6777b538SAndroid Build Coastguard Worker InitializeThreadPool();
485*6777b538SAndroid Build Coastguard Worker }
486*6777b538SAndroid Build Coastguard Worker
487*6777b538SAndroid Build Coastguard Worker if (thread_pool_execution_mode_ == ThreadPoolExecutionMode::QUEUED &&
488*6777b538SAndroid Build Coastguard Worker task_tracker_) {
489*6777b538SAndroid Build Coastguard Worker CHECK(task_tracker_->DisallowRunTasks());
490*6777b538SAndroid Build Coastguard Worker }
491*6777b538SAndroid Build Coastguard Worker }
492*6777b538SAndroid Build Coastguard Worker
493*6777b538SAndroid Build Coastguard Worker // static
CreateThreadPool()494*6777b538SAndroid Build Coastguard Worker TaskEnvironment::TestTaskTracker* TaskEnvironment::CreateThreadPool() {
495*6777b538SAndroid Build Coastguard Worker CHECK(!ThreadPoolInstance::Get())
496*6777b538SAndroid Build Coastguard Worker << "Someone has already installed a ThreadPoolInstance. If nothing in "
497*6777b538SAndroid Build Coastguard Worker "your test does so, then a test that ran earlier may have installed "
498*6777b538SAndroid Build Coastguard Worker "one and leaked it. base::TestSuite will trap leaked globals, unless "
499*6777b538SAndroid Build Coastguard Worker "someone has explicitly disabled it with "
500*6777b538SAndroid Build Coastguard Worker "DisableCheckForLeakedGlobals().";
501*6777b538SAndroid Build Coastguard Worker
502*6777b538SAndroid Build Coastguard Worker auto task_tracker = std::make_unique<TestTaskTracker>();
503*6777b538SAndroid Build Coastguard Worker TestTaskTracker* raw_task_tracker = task_tracker.get();
504*6777b538SAndroid Build Coastguard Worker // Disable background threads to avoid hangs when flushing background tasks.
505*6777b538SAndroid Build Coastguard Worker auto thread_pool = std::make_unique<internal::ThreadPoolImpl>(
506*6777b538SAndroid Build Coastguard Worker std::string(), std::move(task_tracker),
507*6777b538SAndroid Build Coastguard Worker /*use_background_threads=*/false);
508*6777b538SAndroid Build Coastguard Worker ThreadPoolInstance::Set(std::move(thread_pool));
509*6777b538SAndroid Build Coastguard Worker DCHECK(!g_task_tracker);
510*6777b538SAndroid Build Coastguard Worker g_task_tracker = raw_task_tracker;
511*6777b538SAndroid Build Coastguard Worker return raw_task_tracker;
512*6777b538SAndroid Build Coastguard Worker }
513*6777b538SAndroid Build Coastguard Worker
InitializeThreadPool()514*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::InitializeThreadPool() {
515*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING)
516*6777b538SAndroid Build Coastguard Worker // Force the creation of TraceLog instance before starting ThreadPool and
517*6777b538SAndroid Build Coastguard Worker // creating additional threads to avoid race conditions.
518*6777b538SAndroid Build Coastguard Worker trace_event::TraceLog::GetInstance();
519*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(ENABLE_BASE_TRACING)
520*6777b538SAndroid Build Coastguard Worker
521*6777b538SAndroid Build Coastguard Worker task_tracker_ = CreateThreadPool();
522*6777b538SAndroid Build Coastguard Worker if (mock_time_domain_) {
523*6777b538SAndroid Build Coastguard Worker mock_time_domain_->SetThreadPool(
524*6777b538SAndroid Build Coastguard Worker static_cast<internal::ThreadPoolImpl*>(ThreadPoolInstance::Get()),
525*6777b538SAndroid Build Coastguard Worker task_tracker_);
526*6777b538SAndroid Build Coastguard Worker }
527*6777b538SAndroid Build Coastguard Worker
528*6777b538SAndroid Build Coastguard Worker ThreadPoolInstance::InitParams init_params(kNumForegroundThreadPoolThreads);
529*6777b538SAndroid Build Coastguard Worker init_params.suggested_reclaim_time = TimeDelta::Max();
530*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
531*6777b538SAndroid Build Coastguard Worker if (thread_pool_com_environment_ == ThreadPoolCOMEnvironment::COM_MTA) {
532*6777b538SAndroid Build Coastguard Worker init_params.common_thread_pool_environment =
533*6777b538SAndroid Build Coastguard Worker ThreadPoolInstance::InitParams::CommonThreadPoolEnvironment::COM_MTA;
534*6777b538SAndroid Build Coastguard Worker }
535*6777b538SAndroid Build Coastguard Worker #endif
536*6777b538SAndroid Build Coastguard Worker ThreadPoolInstance::Get()->Start(init_params);
537*6777b538SAndroid Build Coastguard Worker }
538*6777b538SAndroid Build Coastguard Worker
CompleteInitialization()539*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::CompleteInitialization() {
540*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
541*6777b538SAndroid Build Coastguard Worker
542*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
543*6777b538SAndroid Build Coastguard Worker if (main_thread_type() == MainThreadType::IO) {
544*6777b538SAndroid Build Coastguard Worker file_descriptor_watcher_ =
545*6777b538SAndroid Build Coastguard Worker std::make_unique<FileDescriptorWatcher>(GetMainThreadTaskRunner());
546*6777b538SAndroid Build Coastguard Worker }
547*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
548*6777b538SAndroid Build Coastguard Worker }
549*6777b538SAndroid Build Coastguard Worker
550*6777b538SAndroid Build Coastguard Worker TaskEnvironment::TaskEnvironment(TaskEnvironment&& other) = default;
551*6777b538SAndroid Build Coastguard Worker
~TaskEnvironment()552*6777b538SAndroid Build Coastguard Worker TaskEnvironment::~TaskEnvironment() {
553*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
554*6777b538SAndroid Build Coastguard Worker DestroyTaskEnvironment();
555*6777b538SAndroid Build Coastguard Worker }
556*6777b538SAndroid Build Coastguard Worker
DestroyTaskEnvironment()557*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::DestroyTaskEnvironment() {
558*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
559*6777b538SAndroid Build Coastguard Worker
560*6777b538SAndroid Build Coastguard Worker // If we've been moved or already destroyed (i.e. subclass invoked
561*6777b538SAndroid Build Coastguard Worker // DestroyTaskEnvironment() before ~TaskEnvironment()) then bail out.
562*6777b538SAndroid Build Coastguard Worker if (!owns_instance_) {
563*6777b538SAndroid Build Coastguard Worker return;
564*6777b538SAndroid Build Coastguard Worker }
565*6777b538SAndroid Build Coastguard Worker owns_instance_.reset();
566*6777b538SAndroid Build Coastguard Worker
567*6777b538SAndroid Build Coastguard Worker for (auto& observer : GetDestructionObservers()) {
568*6777b538SAndroid Build Coastguard Worker observer.WillDestroyCurrentTaskEnvironment();
569*6777b538SAndroid Build Coastguard Worker }
570*6777b538SAndroid Build Coastguard Worker
571*6777b538SAndroid Build Coastguard Worker ShutdownAndJoinThreadPool();
572*6777b538SAndroid Build Coastguard Worker task_queue_.reset();
573*6777b538SAndroid Build Coastguard Worker // SequenceManagerImpl must outlive the threads in the ThreadPoolInstance()
574*6777b538SAndroid Build Coastguard Worker // (ShutdownAndJoinThreadPool() above) as TaskEnvironment::MockTimeDomain can
575*6777b538SAndroid Build Coastguard Worker // invoke its SequenceManagerImpl* from worker threads.
576*6777b538SAndroid Build Coastguard Worker // Additionally, Tasks owned by `sequence_manager_` can have referencees to
577*6777b538SAndroid Build Coastguard Worker // PooledTaskRunnerDelegates. These are owned by the thread pool, so destroy
578*6777b538SAndroid Build Coastguard Worker // `sequence_manager` before the thread pool itself.
579*6777b538SAndroid Build Coastguard Worker sequence_manager_.reset();
580*6777b538SAndroid Build Coastguard Worker DestroyThreadPool();
581*6777b538SAndroid Build Coastguard Worker }
582*6777b538SAndroid Build Coastguard Worker
ShutdownAndJoinThreadPool()583*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::ShutdownAndJoinThreadPool() {
584*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
585*6777b538SAndroid Build Coastguard Worker
586*6777b538SAndroid Build Coastguard Worker if (threading_mode_ == ThreadingMode::MAIN_THREAD_ONLY) {
587*6777b538SAndroid Build Coastguard Worker return;
588*6777b538SAndroid Build Coastguard Worker }
589*6777b538SAndroid Build Coastguard Worker DCHECK(ThreadPoolInstance::Get());
590*6777b538SAndroid Build Coastguard Worker
591*6777b538SAndroid Build Coastguard Worker // Ideally this would RunLoop().RunUntilIdle() here to catch any errors or
592*6777b538SAndroid Build Coastguard Worker // infinite post loop in the remaining work but this isn't possible right now
593*6777b538SAndroid Build Coastguard Worker // because base::~MessageLoop() didn't use to do this and adding it here would
594*6777b538SAndroid Build Coastguard Worker // make the migration away from MessageLoop that much harder.
595*6777b538SAndroid Build Coastguard Worker
596*6777b538SAndroid Build Coastguard Worker // Without FlushForTesting(), DeleteSoon() and ReleaseSoon() tasks could be
597*6777b538SAndroid Build Coastguard Worker // skipped, resulting in memory leaks.
598*6777b538SAndroid Build Coastguard Worker task_tracker_->AllowRunTasks();
599*6777b538SAndroid Build Coastguard Worker ThreadPoolInstance::Get()->FlushForTesting();
600*6777b538SAndroid Build Coastguard Worker ThreadPoolInstance::Get()->Shutdown();
601*6777b538SAndroid Build Coastguard Worker ThreadPoolInstance::Get()->JoinForTesting();
602*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(g_task_tracker, task_tracker_);
603*6777b538SAndroid Build Coastguard Worker g_task_tracker = nullptr;
604*6777b538SAndroid Build Coastguard Worker }
605*6777b538SAndroid Build Coastguard Worker
DestroyThreadPool()606*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::DestroyThreadPool() {
607*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
608*6777b538SAndroid Build Coastguard Worker
609*6777b538SAndroid Build Coastguard Worker if (threading_mode_ == ThreadingMode::MAIN_THREAD_ONLY) {
610*6777b538SAndroid Build Coastguard Worker return;
611*6777b538SAndroid Build Coastguard Worker }
612*6777b538SAndroid Build Coastguard Worker DCHECK(ThreadPoolInstance::Get());
613*6777b538SAndroid Build Coastguard Worker
614*6777b538SAndroid Build Coastguard Worker // Task runner lists will be destroyed when resetting thread pool instance.
615*6777b538SAndroid Build Coastguard Worker scoped_lazy_task_runner_list_for_testing_.reset();
616*6777b538SAndroid Build Coastguard Worker
617*6777b538SAndroid Build Coastguard Worker // Destroying ThreadPoolInstance state can result in waiting on worker
618*6777b538SAndroid Build Coastguard Worker // threads. Make sure this is allowed to avoid flaking tests that have
619*6777b538SAndroid Build Coastguard Worker // disallowed waits on their main thread.
620*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitivesForTesting allow_waits_to_destroy_task_tracker;
621*6777b538SAndroid Build Coastguard Worker
622*6777b538SAndroid Build Coastguard Worker // Drop unowned resource before destroying thread pool which owns it.
623*6777b538SAndroid Build Coastguard Worker task_tracker_ = nullptr;
624*6777b538SAndroid Build Coastguard Worker ThreadPoolInstance::Set(nullptr);
625*6777b538SAndroid Build Coastguard Worker }
626*6777b538SAndroid Build Coastguard Worker
GetMockTimeDomain() const627*6777b538SAndroid Build Coastguard Worker sequence_manager::TimeDomain* TaskEnvironment::GetMockTimeDomain() const {
628*6777b538SAndroid Build Coastguard Worker return mock_time_domain_.get();
629*6777b538SAndroid Build Coastguard Worker }
630*6777b538SAndroid Build Coastguard Worker
sequence_manager() const631*6777b538SAndroid Build Coastguard Worker sequence_manager::SequenceManager* TaskEnvironment::sequence_manager() const {
632*6777b538SAndroid Build Coastguard Worker DCHECK(subclass_creates_default_taskrunner_);
633*6777b538SAndroid Build Coastguard Worker return sequence_manager_.get();
634*6777b538SAndroid Build Coastguard Worker }
635*6777b538SAndroid Build Coastguard Worker
DeferredInitFromSubclass(scoped_refptr<base::SingleThreadTaskRunner> task_runner)636*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::DeferredInitFromSubclass(
637*6777b538SAndroid Build Coastguard Worker scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
638*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
639*6777b538SAndroid Build Coastguard Worker
640*6777b538SAndroid Build Coastguard Worker task_runner_ = std::move(task_runner);
641*6777b538SAndroid Build Coastguard Worker sequence_manager_->SetDefaultTaskRunner(task_runner_);
642*6777b538SAndroid Build Coastguard Worker CompleteInitialization();
643*6777b538SAndroid Build Coastguard Worker }
644*6777b538SAndroid Build Coastguard Worker
645*6777b538SAndroid Build Coastguard Worker scoped_refptr<base::SingleThreadTaskRunner>
GetMainThreadTaskRunner()646*6777b538SAndroid Build Coastguard Worker TaskEnvironment::GetMainThreadTaskRunner() {
647*6777b538SAndroid Build Coastguard Worker DCHECK(task_runner_);
648*6777b538SAndroid Build Coastguard Worker return task_runner_;
649*6777b538SAndroid Build Coastguard Worker }
650*6777b538SAndroid Build Coastguard Worker
MainThreadIsIdle() const651*6777b538SAndroid Build Coastguard Worker bool TaskEnvironment::MainThreadIsIdle() const {
652*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
653*6777b538SAndroid Build Coastguard Worker
654*6777b538SAndroid Build Coastguard Worker sequence_manager::internal::SequenceManagerImpl* sequence_manager_impl =
655*6777b538SAndroid Build Coastguard Worker static_cast<sequence_manager::internal::SequenceManagerImpl*>(
656*6777b538SAndroid Build Coastguard Worker sequence_manager_.get());
657*6777b538SAndroid Build Coastguard Worker // ReclaimMemory sweeps canceled delayed tasks.
658*6777b538SAndroid Build Coastguard Worker sequence_manager_impl->ReclaimMemory();
659*6777b538SAndroid Build Coastguard Worker return sequence_manager_impl->IsIdleForTesting();
660*6777b538SAndroid Build Coastguard Worker }
661*6777b538SAndroid Build Coastguard Worker
QuitClosure()662*6777b538SAndroid Build Coastguard Worker RepeatingClosure TaskEnvironment::QuitClosure() {
663*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
664*6777b538SAndroid Build Coastguard Worker
665*6777b538SAndroid Build Coastguard Worker if (!run_until_quit_loop_) {
666*6777b538SAndroid Build Coastguard Worker run_until_quit_loop_ =
667*6777b538SAndroid Build Coastguard Worker std::make_unique<RunLoop>(RunLoop::Type::kNestableTasksAllowed);
668*6777b538SAndroid Build Coastguard Worker }
669*6777b538SAndroid Build Coastguard Worker
670*6777b538SAndroid Build Coastguard Worker return run_until_quit_loop_->QuitClosure();
671*6777b538SAndroid Build Coastguard Worker }
672*6777b538SAndroid Build Coastguard Worker
RunUntilQuit()673*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::RunUntilQuit() {
674*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
675*6777b538SAndroid Build Coastguard Worker DCHECK(run_until_quit_loop_)
676*6777b538SAndroid Build Coastguard Worker << "QuitClosure() not called before RunUntilQuit()";
677*6777b538SAndroid Build Coastguard Worker
678*6777b538SAndroid Build Coastguard Worker const bool could_run_tasks = task_tracker_->AllowRunTasks();
679*6777b538SAndroid Build Coastguard Worker
680*6777b538SAndroid Build Coastguard Worker run_until_quit_loop_->Run();
681*6777b538SAndroid Build Coastguard Worker // Make the next call to RunUntilQuit() use a new RunLoop. This also
682*6777b538SAndroid Build Coastguard Worker // invalidates all existing quit closures.
683*6777b538SAndroid Build Coastguard Worker run_until_quit_loop_.reset();
684*6777b538SAndroid Build Coastguard Worker
685*6777b538SAndroid Build Coastguard Worker if (!could_run_tasks) {
686*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
687*6777b538SAndroid Build Coastguard Worker task_tracker_->DisallowRunTasks(TestTimeouts::action_max_timeout()))
688*6777b538SAndroid Build Coastguard Worker << "Could not bring ThreadPool back to ThreadPoolExecutionMode::QUEUED "
689*6777b538SAndroid Build Coastguard Worker "after Quit() because some tasks were long running:\n"
690*6777b538SAndroid Build Coastguard Worker << task_tracker_->DescribeRunningTasks();
691*6777b538SAndroid Build Coastguard Worker }
692*6777b538SAndroid Build Coastguard Worker }
693*6777b538SAndroid Build Coastguard Worker
RunUntilIdle()694*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::RunUntilIdle() {
695*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
696*6777b538SAndroid Build Coastguard Worker
697*6777b538SAndroid Build Coastguard Worker if (threading_mode_ == ThreadingMode::MAIN_THREAD_ONLY) {
698*6777b538SAndroid Build Coastguard Worker RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
699*6777b538SAndroid Build Coastguard Worker return;
700*6777b538SAndroid Build Coastguard Worker }
701*6777b538SAndroid Build Coastguard Worker
702*6777b538SAndroid Build Coastguard Worker // TODO(gab): This can be heavily simplified to essentially:
703*6777b538SAndroid Build Coastguard Worker // bool HasMainThreadTasks() {
704*6777b538SAndroid Build Coastguard Worker // if (message_loop_)
705*6777b538SAndroid Build Coastguard Worker // return !message_loop_->IsIdleForTesting();
706*6777b538SAndroid Build Coastguard Worker // return mock_time_task_runner_->NextPendingTaskDelay().is_zero();
707*6777b538SAndroid Build Coastguard Worker // }
708*6777b538SAndroid Build Coastguard Worker // while (task_tracker_->HasIncompleteTasks() || HasMainThreadTasks()) {
709*6777b538SAndroid Build Coastguard Worker // base::RunLoop().RunUntilIdle();
710*6777b538SAndroid Build Coastguard Worker // // Avoid busy-looping.
711*6777b538SAndroid Build Coastguard Worker // if (task_tracker_->HasIncompleteTasks())
712*6777b538SAndroid Build Coastguard Worker // PlatformThread::Sleep(Milliseconds(1));
713*6777b538SAndroid Build Coastguard Worker // }
714*6777b538SAndroid Build Coastguard Worker // Update: This can likely be done now that MessageLoop::IsIdleForTesting()
715*6777b538SAndroid Build Coastguard Worker // checks all queues.
716*6777b538SAndroid Build Coastguard Worker //
717*6777b538SAndroid Build Coastguard Worker // Other than that it works because once |task_tracker_->HasIncompleteTasks()|
718*6777b538SAndroid Build Coastguard Worker // is false we know for sure that the only thing that can make it true is a
719*6777b538SAndroid Build Coastguard Worker // main thread task (TaskEnvironment owns all the threads). As such we can't
720*6777b538SAndroid Build Coastguard Worker // racily see it as false on the main thread and be wrong as if it the main
721*6777b538SAndroid Build Coastguard Worker // thread sees the atomic count at zero, it's the only one that can make it go
722*6777b538SAndroid Build Coastguard Worker // up. And the only thing that can make it go up on the main thread are main
723*6777b538SAndroid Build Coastguard Worker // thread tasks and therefore we're done if there aren't any left.
724*6777b538SAndroid Build Coastguard Worker //
725*6777b538SAndroid Build Coastguard Worker // This simplification further allows simplification of DisallowRunTasks().
726*6777b538SAndroid Build Coastguard Worker //
727*6777b538SAndroid Build Coastguard Worker // This can also be simplified even further once TaskTracker becomes directly
728*6777b538SAndroid Build Coastguard Worker // aware of main thread tasks. https://crbug.com/660078.
729*6777b538SAndroid Build Coastguard Worker
730*6777b538SAndroid Build Coastguard Worker const bool could_run_tasks = task_tracker_->AllowRunTasks();
731*6777b538SAndroid Build Coastguard Worker
732*6777b538SAndroid Build Coastguard Worker for (;;) {
733*6777b538SAndroid Build Coastguard Worker task_tracker_->AllowRunTasks();
734*6777b538SAndroid Build Coastguard Worker
735*6777b538SAndroid Build Coastguard Worker // First run as many tasks as possible on the main thread in parallel with
736*6777b538SAndroid Build Coastguard Worker // tasks in ThreadPool. This increases likelihood of TSAN catching
737*6777b538SAndroid Build Coastguard Worker // threading errors and eliminates possibility of hangs should a
738*6777b538SAndroid Build Coastguard Worker // ThreadPool task synchronously block on a main thread task
739*6777b538SAndroid Build Coastguard Worker // (ThreadPoolInstance::FlushForTesting() can't be used here for that
740*6777b538SAndroid Build Coastguard Worker // reason).
741*6777b538SAndroid Build Coastguard Worker RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
742*6777b538SAndroid Build Coastguard Worker
743*6777b538SAndroid Build Coastguard Worker // Then halt ThreadPool. DisallowRunTasks() failing indicates that there
744*6777b538SAndroid Build Coastguard Worker // were ThreadPool tasks currently running. In that case, try again from
745*6777b538SAndroid Build Coastguard Worker // top when DisallowRunTasks() yields control back to this thread as they
746*6777b538SAndroid Build Coastguard Worker // may have posted main thread tasks.
747*6777b538SAndroid Build Coastguard Worker if (!task_tracker_->DisallowRunTasks()) {
748*6777b538SAndroid Build Coastguard Worker continue;
749*6777b538SAndroid Build Coastguard Worker }
750*6777b538SAndroid Build Coastguard Worker
751*6777b538SAndroid Build Coastguard Worker // Once ThreadPool is halted. Run any remaining main thread tasks (which
752*6777b538SAndroid Build Coastguard Worker // may have been posted by ThreadPool tasks that completed between the
753*6777b538SAndroid Build Coastguard Worker // above main thread RunUntilIdle() and ThreadPool DisallowRunTasks()).
754*6777b538SAndroid Build Coastguard Worker // Note: this assumes that no main thread task synchronously blocks on a
755*6777b538SAndroid Build Coastguard Worker // ThreadPool tasks (it certainly shouldn't); this call could otherwise
756*6777b538SAndroid Build Coastguard Worker // hang.
757*6777b538SAndroid Build Coastguard Worker RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
758*6777b538SAndroid Build Coastguard Worker
759*6777b538SAndroid Build Coastguard Worker // The above RunUntilIdle() guarantees there are no remaining main thread
760*6777b538SAndroid Build Coastguard Worker // tasks (the ThreadPool being halted during the last RunUntilIdle() is
761*6777b538SAndroid Build Coastguard Worker // key as it prevents a task being posted to it racily with it determining
762*6777b538SAndroid Build Coastguard Worker // it had no work remaining). Therefore, we're done if there is no more work
763*6777b538SAndroid Build Coastguard Worker // on ThreadPool either (there can be ThreadPool work remaining if
764*6777b538SAndroid Build Coastguard Worker // DisallowRunTasks() preempted work and/or the last RunUntilIdle() posted
765*6777b538SAndroid Build Coastguard Worker // more ThreadPool tasks).
766*6777b538SAndroid Build Coastguard Worker // Note: this last |if| couldn't be turned into a |do {} while();|. A
767*6777b538SAndroid Build Coastguard Worker // conditional loop makes it such that |continue;| results in checking the
768*6777b538SAndroid Build Coastguard Worker // condition (not unconditionally loop again) which would be incorrect for
769*6777b538SAndroid Build Coastguard Worker // the above logic as it'd then be possible for a ThreadPool task to be
770*6777b538SAndroid Build Coastguard Worker // running during the DisallowRunTasks() test, causing it to fail, but then
771*6777b538SAndroid Build Coastguard Worker // post to the main thread and complete before the loop's condition is
772*6777b538SAndroid Build Coastguard Worker // verified which could result in HasIncompleteUndelayedTasksForTesting()
773*6777b538SAndroid Build Coastguard Worker // returning false and the loop erroneously exiting with a pending task on
774*6777b538SAndroid Build Coastguard Worker // the main thread.
775*6777b538SAndroid Build Coastguard Worker if (!task_tracker_->HasIncompleteTaskSourcesForTesting()) {
776*6777b538SAndroid Build Coastguard Worker break;
777*6777b538SAndroid Build Coastguard Worker }
778*6777b538SAndroid Build Coastguard Worker }
779*6777b538SAndroid Build Coastguard Worker
780*6777b538SAndroid Build Coastguard Worker // The above loop always ends with running tasks being disallowed. Re-enable
781*6777b538SAndroid Build Coastguard Worker // parallel execution before returning if it was allowed at the beginning of
782*6777b538SAndroid Build Coastguard Worker // this call.
783*6777b538SAndroid Build Coastguard Worker if (could_run_tasks) {
784*6777b538SAndroid Build Coastguard Worker task_tracker_->AllowRunTasks();
785*6777b538SAndroid Build Coastguard Worker }
786*6777b538SAndroid Build Coastguard Worker }
787*6777b538SAndroid Build Coastguard Worker
FastForwardBy(TimeDelta delta)788*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::FastForwardBy(TimeDelta delta) {
789*6777b538SAndroid Build Coastguard Worker FastForwardByInternal(delta, /*advance_live_ticks=*/true);
790*6777b538SAndroid Build Coastguard Worker }
791*6777b538SAndroid Build Coastguard Worker
SuspendedFastForwardBy(TimeDelta delta)792*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::SuspendedFastForwardBy(TimeDelta delta) {
793*6777b538SAndroid Build Coastguard Worker FastForwardByInternal(delta, /*advance_live_ticks=*/false);
794*6777b538SAndroid Build Coastguard Worker }
795*6777b538SAndroid Build Coastguard Worker
FastForwardByInternal(TimeDelta delta,bool advance_live_ticks)796*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::FastForwardByInternal(TimeDelta delta,
797*6777b538SAndroid Build Coastguard Worker bool advance_live_ticks) {
798*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
799*6777b538SAndroid Build Coastguard Worker DCHECK(mock_time_domain_);
800*6777b538SAndroid Build Coastguard Worker DCHECK_GE(delta, TimeDelta());
801*6777b538SAndroid Build Coastguard Worker
802*6777b538SAndroid Build Coastguard Worker const bool could_run_tasks = task_tracker_ && task_tracker_->AllowRunTasks();
803*6777b538SAndroid Build Coastguard Worker
804*6777b538SAndroid Build Coastguard Worker const TimeTicks fast_forward_until = mock_time_domain_->NowTicks() + delta;
805*6777b538SAndroid Build Coastguard Worker do {
806*6777b538SAndroid Build Coastguard Worker RunUntilIdle();
807*6777b538SAndroid Build Coastguard Worker // ReclaimMemory sweeps canceled delayed tasks, making sure
808*6777b538SAndroid Build Coastguard Worker // FastForwardToNextTaskOrCap isn't affected by canceled tasks.
809*6777b538SAndroid Build Coastguard Worker sequence_manager_->ReclaimMemory();
810*6777b538SAndroid Build Coastguard Worker } while (mock_time_domain_->FastForwardToNextTaskOrCap(
811*6777b538SAndroid Build Coastguard Worker sequence_manager_->GetNextDelayedWakeUp(), fast_forward_until,
812*6777b538SAndroid Build Coastguard Worker advance_live_ticks) != MockTimeDomain::NextTaskSource::kNone);
813*6777b538SAndroid Build Coastguard Worker
814*6777b538SAndroid Build Coastguard Worker if (task_tracker_ && !could_run_tasks) {
815*6777b538SAndroid Build Coastguard Worker task_tracker_->DisallowRunTasks();
816*6777b538SAndroid Build Coastguard Worker }
817*6777b538SAndroid Build Coastguard Worker }
818*6777b538SAndroid Build Coastguard Worker
FastForwardUntilNoTasksRemain()819*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::FastForwardUntilNoTasksRemain() {
820*6777b538SAndroid Build Coastguard Worker // TimeTicks::operator+(TimeDelta) uses saturated arithmetic so it's safe to
821*6777b538SAndroid Build Coastguard Worker // pass in TimeDelta::Max().
822*6777b538SAndroid Build Coastguard Worker FastForwardBy(TimeDelta::Max());
823*6777b538SAndroid Build Coastguard Worker }
824*6777b538SAndroid Build Coastguard Worker
AdvanceClock(TimeDelta delta)825*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::AdvanceClock(TimeDelta delta) {
826*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
827*6777b538SAndroid Build Coastguard Worker DCHECK(mock_time_domain_);
828*6777b538SAndroid Build Coastguard Worker DCHECK_GE(delta, TimeDelta());
829*6777b538SAndroid Build Coastguard Worker mock_time_domain_->AdvanceClock(delta);
830*6777b538SAndroid Build Coastguard Worker }
831*6777b538SAndroid Build Coastguard Worker
SuspendedAdvanceClock(TimeDelta delta)832*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::SuspendedAdvanceClock(TimeDelta delta) {
833*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
834*6777b538SAndroid Build Coastguard Worker DCHECK(mock_time_domain_);
835*6777b538SAndroid Build Coastguard Worker DCHECK_GE(delta, TimeDelta());
836*6777b538SAndroid Build Coastguard Worker mock_time_domain_->SuspendedAdvanceClock(delta);
837*6777b538SAndroid Build Coastguard Worker }
838*6777b538SAndroid Build Coastguard Worker
GetMockTickClock() const839*6777b538SAndroid Build Coastguard Worker const TickClock* TaskEnvironment::GetMockTickClock() const {
840*6777b538SAndroid Build Coastguard Worker DCHECK(mock_time_domain_);
841*6777b538SAndroid Build Coastguard Worker return mock_time_domain_.get();
842*6777b538SAndroid Build Coastguard Worker }
843*6777b538SAndroid Build Coastguard Worker
NowTicks() const844*6777b538SAndroid Build Coastguard Worker base::TimeTicks TaskEnvironment::NowTicks() const {
845*6777b538SAndroid Build Coastguard Worker DCHECK(mock_time_domain_);
846*6777b538SAndroid Build Coastguard Worker return mock_time_domain_->NowTicks();
847*6777b538SAndroid Build Coastguard Worker }
848*6777b538SAndroid Build Coastguard Worker
NowLiveTicks() const849*6777b538SAndroid Build Coastguard Worker base::LiveTicks TaskEnvironment::NowLiveTicks() const {
850*6777b538SAndroid Build Coastguard Worker DCHECK(mock_time_domain_);
851*6777b538SAndroid Build Coastguard Worker return mock_time_domain_->NowLiveTicks();
852*6777b538SAndroid Build Coastguard Worker }
853*6777b538SAndroid Build Coastguard Worker
GetMockClock() const854*6777b538SAndroid Build Coastguard Worker const Clock* TaskEnvironment::GetMockClock() const {
855*6777b538SAndroid Build Coastguard Worker DCHECK(mock_clock_);
856*6777b538SAndroid Build Coastguard Worker return mock_clock_.get();
857*6777b538SAndroid Build Coastguard Worker }
858*6777b538SAndroid Build Coastguard Worker
GetPendingMainThreadTaskCount() const859*6777b538SAndroid Build Coastguard Worker size_t TaskEnvironment::GetPendingMainThreadTaskCount() const {
860*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
861*6777b538SAndroid Build Coastguard Worker
862*6777b538SAndroid Build Coastguard Worker // ReclaimMemory sweeps canceled delayed tasks.
863*6777b538SAndroid Build Coastguard Worker sequence_manager_->ReclaimMemory();
864*6777b538SAndroid Build Coastguard Worker return sequence_manager_->GetPendingTaskCountForTesting();
865*6777b538SAndroid Build Coastguard Worker }
866*6777b538SAndroid Build Coastguard Worker
NextMainThreadPendingTaskDelay() const867*6777b538SAndroid Build Coastguard Worker TimeDelta TaskEnvironment::NextMainThreadPendingTaskDelay() const {
868*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
869*6777b538SAndroid Build Coastguard Worker
870*6777b538SAndroid Build Coastguard Worker // ReclaimMemory sweeps canceled delayed tasks.
871*6777b538SAndroid Build Coastguard Worker sequence_manager_->ReclaimMemory();
872*6777b538SAndroid Build Coastguard Worker DCHECK(mock_time_domain_);
873*6777b538SAndroid Build Coastguard Worker LazyNow lazy_now(mock_time_domain_->NowTicks());
874*6777b538SAndroid Build Coastguard Worker if (!sequence_manager_->IsIdleForTesting()) {
875*6777b538SAndroid Build Coastguard Worker return TimeDelta();
876*6777b538SAndroid Build Coastguard Worker }
877*6777b538SAndroid Build Coastguard Worker std::optional<sequence_manager::WakeUp> wake_up =
878*6777b538SAndroid Build Coastguard Worker sequence_manager_->GetNextDelayedWakeUp();
879*6777b538SAndroid Build Coastguard Worker return wake_up ? wake_up->time - lazy_now.Now() : TimeDelta::Max();
880*6777b538SAndroid Build Coastguard Worker }
881*6777b538SAndroid Build Coastguard Worker
NextTaskIsDelayed() const882*6777b538SAndroid Build Coastguard Worker bool TaskEnvironment::NextTaskIsDelayed() const {
883*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
884*6777b538SAndroid Build Coastguard Worker
885*6777b538SAndroid Build Coastguard Worker TimeDelta delay = NextMainThreadPendingTaskDelay();
886*6777b538SAndroid Build Coastguard Worker return !delay.is_zero() && !delay.is_max();
887*6777b538SAndroid Build Coastguard Worker }
888*6777b538SAndroid Build Coastguard Worker
DescribeCurrentTasks() const889*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::DescribeCurrentTasks() const {
890*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
891*6777b538SAndroid Build Coastguard Worker LOG(INFO) << task_tracker_->DescribeRunningTasks();
892*6777b538SAndroid Build Coastguard Worker LOG(INFO) << sequence_manager_->DescribeAllPendingTasks();
893*6777b538SAndroid Build Coastguard Worker }
894*6777b538SAndroid Build Coastguard Worker
DetachFromThread()895*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::DetachFromThread() {
896*6777b538SAndroid Build Coastguard Worker DETACH_FROM_THREAD(main_thread_checker_);
897*6777b538SAndroid Build Coastguard Worker if (task_tracker_) {
898*6777b538SAndroid Build Coastguard Worker task_tracker_->controller_thread_checker_.DetachFromThread();
899*6777b538SAndroid Build Coastguard Worker }
900*6777b538SAndroid Build Coastguard Worker }
901*6777b538SAndroid Build Coastguard Worker
902*6777b538SAndroid Build Coastguard Worker // static
AddDestructionObserver(DestructionObserver * observer)903*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::AddDestructionObserver(DestructionObserver* observer) {
904*6777b538SAndroid Build Coastguard Worker GetDestructionObservers().AddObserver(observer);
905*6777b538SAndroid Build Coastguard Worker }
906*6777b538SAndroid Build Coastguard Worker
907*6777b538SAndroid Build Coastguard Worker // static
RemoveDestructionObserver(DestructionObserver * observer)908*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::RemoveDestructionObserver(DestructionObserver* observer) {
909*6777b538SAndroid Build Coastguard Worker GetDestructionObservers().RemoveObserver(observer);
910*6777b538SAndroid Build Coastguard Worker }
911*6777b538SAndroid Build Coastguard Worker
ParallelExecutionFence(const char * error_message)912*6777b538SAndroid Build Coastguard Worker TaskEnvironment::ParallelExecutionFence::ParallelExecutionFence(
913*6777b538SAndroid Build Coastguard Worker const char* error_message) {
914*6777b538SAndroid Build Coastguard Worker CHECK(!g_task_tracker || g_task_tracker->OnControllerThread())
915*6777b538SAndroid Build Coastguard Worker << error_message;
916*6777b538SAndroid Build Coastguard Worker if (g_task_tracker) {
917*6777b538SAndroid Build Coastguard Worker // Do not attempt to install a fence post shutdown, the only remaining tasks
918*6777b538SAndroid Build Coastguard Worker // at that point are CONTINUE_ON_SHUTDOWN and attempting to wait for them
919*6777b538SAndroid Build Coastguard Worker // causes more issues (test timeouts) than the fence solves (data races on
920*6777b538SAndroid Build Coastguard Worker // global state). CONTINUE_ON_SHUTDOWN tasks should generally not be
921*6777b538SAndroid Build Coastguard Worker // touching global state and while not all users of ParallelExecutionFence
922*6777b538SAndroid Build Coastguard Worker // (FeatureList) guard against access from CONTINUE_ON_SHUTDOWN tasks, any
923*6777b538SAndroid Build Coastguard Worker // such tasks abusing this would be flagged by TSAN and have to be fixed
924*6777b538SAndroid Build Coastguard Worker // manually. Note: this is only relevant in browser tests as unit tests
925*6777b538SAndroid Build Coastguard Worker // already go through a full join in TaskEnvironment::DestroyThreadPool().
926*6777b538SAndroid Build Coastguard Worker previously_allowed_to_run_ = g_task_tracker->TasksAllowedToRun() &&
927*6777b538SAndroid Build Coastguard Worker !g_task_tracker->IsShutdownComplete();
928*6777b538SAndroid Build Coastguard Worker
929*6777b538SAndroid Build Coastguard Worker // DisallowRunTasks typically yields back if it fails to reach quiescence
930*6777b538SAndroid Build Coastguard Worker // within 1ms. This is typically done to let the main thread run tasks that
931*6777b538SAndroid Build Coastguard Worker // could potentially be blocking main thread tasks. In this case however,
932*6777b538SAndroid Build Coastguard Worker // main thread making progress while installing the fence would be more
933*6777b538SAndroid Build Coastguard Worker // surprising. So allow more time but report errors after a while.
934*6777b538SAndroid Build Coastguard Worker while (previously_allowed_to_run_ &&
935*6777b538SAndroid Build Coastguard Worker !g_task_tracker->DisallowRunTasks(Seconds(5))) {
936*6777b538SAndroid Build Coastguard Worker LOG(WARNING) << "Installing ParallelExecutionFence is slow because of "
937*6777b538SAndroid Build Coastguard Worker "these running tasks:\n"
938*6777b538SAndroid Build Coastguard Worker << g_task_tracker->DescribeRunningTasks()
939*6777b538SAndroid Build Coastguard Worker << "\nParallelExecutionFence requested by:\n"
940*6777b538SAndroid Build Coastguard Worker << debug::StackTrace();
941*6777b538SAndroid Build Coastguard Worker }
942*6777b538SAndroid Build Coastguard Worker } else if (ThreadPoolInstance::Get()) {
943*6777b538SAndroid Build Coastguard Worker LOG(WARNING)
944*6777b538SAndroid Build Coastguard Worker << "ParallelExecutionFence is ineffective when ThreadPoolInstance is "
945*6777b538SAndroid Build Coastguard Worker "not managed by a TaskEnvironment.\n"
946*6777b538SAndroid Build Coastguard Worker "Test fixtures should use a TaskEnvironment member or statically "
947*6777b538SAndroid Build Coastguard Worker "invoke TaskEnvironment::CreateThreadPool() + "
948*6777b538SAndroid Build Coastguard Worker "ThreadPoolInstance::Get()->StartWithDefaultParams() when the "
949*6777b538SAndroid Build Coastguard Worker "former is not possible.";
950*6777b538SAndroid Build Coastguard Worker }
951*6777b538SAndroid Build Coastguard Worker }
952*6777b538SAndroid Build Coastguard Worker
~ParallelExecutionFence()953*6777b538SAndroid Build Coastguard Worker TaskEnvironment::ParallelExecutionFence::~ParallelExecutionFence() {
954*6777b538SAndroid Build Coastguard Worker if (previously_allowed_to_run_) {
955*6777b538SAndroid Build Coastguard Worker g_task_tracker->AllowRunTasks();
956*6777b538SAndroid Build Coastguard Worker }
957*6777b538SAndroid Build Coastguard Worker }
958*6777b538SAndroid Build Coastguard Worker
TestTaskTracker()959*6777b538SAndroid Build Coastguard Worker TaskEnvironment::TestTaskTracker::TestTaskTracker()
960*6777b538SAndroid Build Coastguard Worker : can_run_tasks_cv_(&lock_), task_completed_cv_(&lock_) {
961*6777b538SAndroid Build Coastguard Worker // Consider threads blocked on these as idle (avoids instantiating
962*6777b538SAndroid Build Coastguard Worker // ScopedBlockingCalls and confusing some //base internals tests).
963*6777b538SAndroid Build Coastguard Worker can_run_tasks_cv_.declare_only_used_while_idle();
964*6777b538SAndroid Build Coastguard Worker task_completed_cv_.declare_only_used_while_idle();
965*6777b538SAndroid Build Coastguard Worker }
966*6777b538SAndroid Build Coastguard Worker
AllowRunTasks()967*6777b538SAndroid Build Coastguard Worker bool TaskEnvironment::TestTaskTracker::AllowRunTasks() {
968*6777b538SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
969*6777b538SAndroid Build Coastguard Worker const bool could_run_tasks = can_run_tasks_;
970*6777b538SAndroid Build Coastguard Worker can_run_tasks_ = true;
971*6777b538SAndroid Build Coastguard Worker can_run_tasks_cv_.Broadcast();
972*6777b538SAndroid Build Coastguard Worker return could_run_tasks;
973*6777b538SAndroid Build Coastguard Worker }
974*6777b538SAndroid Build Coastguard Worker
TasksAllowedToRun() const975*6777b538SAndroid Build Coastguard Worker bool TaskEnvironment::TestTaskTracker::TasksAllowedToRun() const {
976*6777b538SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
977*6777b538SAndroid Build Coastguard Worker return can_run_tasks_;
978*6777b538SAndroid Build Coastguard Worker }
979*6777b538SAndroid Build Coastguard Worker
DisallowRunTasks(TimeDelta timeout)980*6777b538SAndroid Build Coastguard Worker bool TaskEnvironment::TestTaskTracker::DisallowRunTasks(TimeDelta timeout) {
981*6777b538SAndroid Build Coastguard Worker // Disallowing task running should only be done from the main thread to avoid
982*6777b538SAndroid Build Coastguard Worker // racing with shutdown.
983*6777b538SAndroid Build Coastguard Worker DCHECK(OnControllerThread());
984*6777b538SAndroid Build Coastguard Worker
985*6777b538SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
986*6777b538SAndroid Build Coastguard Worker
987*6777b538SAndroid Build Coastguard Worker // Can't disallow run task if there are tasks running.
988*6777b538SAndroid Build Coastguard Worker for (TimeTicks now = subtle::TimeTicksNowIgnoringOverride(),
989*6777b538SAndroid Build Coastguard Worker end = now + timeout;
990*6777b538SAndroid Build Coastguard Worker !running_tasks_.empty() && now < end;
991*6777b538SAndroid Build Coastguard Worker now = subtle::TimeTicksNowIgnoringOverride()) {
992*6777b538SAndroid Build Coastguard Worker task_completed_cv_.TimedWait(end - now);
993*6777b538SAndroid Build Coastguard Worker }
994*6777b538SAndroid Build Coastguard Worker // Timed out waiting for running tasks, yield to caller.
995*6777b538SAndroid Build Coastguard Worker if (!running_tasks_.empty()) {
996*6777b538SAndroid Build Coastguard Worker // This condition should never be sought after shutdown and this call
997*6777b538SAndroid Build Coastguard Worker // shouldn't be racing shutdown either per the above `OnControllerThread()`
998*6777b538SAndroid Build Coastguard Worker // contract.
999*6777b538SAndroid Build Coastguard Worker DCHECK(!IsShutdownComplete());
1000*6777b538SAndroid Build Coastguard Worker return false;
1001*6777b538SAndroid Build Coastguard Worker }
1002*6777b538SAndroid Build Coastguard Worker
1003*6777b538SAndroid Build Coastguard Worker can_run_tasks_ = false;
1004*6777b538SAndroid Build Coastguard Worker return true;
1005*6777b538SAndroid Build Coastguard Worker }
1006*6777b538SAndroid Build Coastguard Worker
RunTask(internal::Task task,internal::TaskSource * sequence,const TaskTraits & traits)1007*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::TestTaskTracker::RunTask(internal::Task task,
1008*6777b538SAndroid Build Coastguard Worker internal::TaskSource* sequence,
1009*6777b538SAndroid Build Coastguard Worker const TaskTraits& traits) {
1010*6777b538SAndroid Build Coastguard Worker const Location posted_from = task.posted_from;
1011*6777b538SAndroid Build Coastguard Worker int task_number;
1012*6777b538SAndroid Build Coastguard Worker {
1013*6777b538SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
1014*6777b538SAndroid Build Coastguard Worker
1015*6777b538SAndroid Build Coastguard Worker while (!can_run_tasks_) {
1016*6777b538SAndroid Build Coastguard Worker can_run_tasks_cv_.Wait();
1017*6777b538SAndroid Build Coastguard Worker }
1018*6777b538SAndroid Build Coastguard Worker
1019*6777b538SAndroid Build Coastguard Worker task_number = next_task_number_++;
1020*6777b538SAndroid Build Coastguard Worker auto pair = running_tasks_.emplace(task_number, posted_from);
1021*6777b538SAndroid Build Coastguard Worker CHECK(pair.second); // If false, the |task_number| was already present.
1022*6777b538SAndroid Build Coastguard Worker }
1023*6777b538SAndroid Build Coastguard Worker
1024*6777b538SAndroid Build Coastguard Worker // Using TimeTicksNowIgnoringOverride() because in tests that mock time,
1025*6777b538SAndroid Build Coastguard Worker // Now() can advance very far very fast, and that's not a problem. This is
1026*6777b538SAndroid Build Coastguard Worker // watching for tests that have actually long running tasks which cause our
1027*6777b538SAndroid Build Coastguard Worker // test suites to run slowly.
1028*6777b538SAndroid Build Coastguard Worker base::TimeTicks before = base::subtle::TimeTicksNowIgnoringOverride();
1029*6777b538SAndroid Build Coastguard Worker internal::ThreadPoolImpl::TaskTrackerImpl::RunTask(std::move(task), sequence,
1030*6777b538SAndroid Build Coastguard Worker traits);
1031*6777b538SAndroid Build Coastguard Worker base::TimeTicks after = base::subtle::TimeTicksNowIgnoringOverride();
1032*6777b538SAndroid Build Coastguard Worker
1033*6777b538SAndroid Build Coastguard Worker const TimeDelta kTimeout = TestTimeouts::action_max_timeout();
1034*6777b538SAndroid Build Coastguard Worker if ((after - before) > kTimeout) {
1035*6777b538SAndroid Build Coastguard Worker ADD_FAILURE() << "TaskEnvironment: RunTask took more than "
1036*6777b538SAndroid Build Coastguard Worker << kTimeout.InSeconds() << " seconds. Posted from "
1037*6777b538SAndroid Build Coastguard Worker << posted_from.ToString();
1038*6777b538SAndroid Build Coastguard Worker }
1039*6777b538SAndroid Build Coastguard Worker
1040*6777b538SAndroid Build Coastguard Worker {
1041*6777b538SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
1042*6777b538SAndroid Build Coastguard Worker CHECK(can_run_tasks_);
1043*6777b538SAndroid Build Coastguard Worker size_t found = running_tasks_.erase(task_number);
1044*6777b538SAndroid Build Coastguard Worker CHECK_EQ(1u, found);
1045*6777b538SAndroid Build Coastguard Worker
1046*6777b538SAndroid Build Coastguard Worker task_completed_cv_.Broadcast();
1047*6777b538SAndroid Build Coastguard Worker }
1048*6777b538SAndroid Build Coastguard Worker }
1049*6777b538SAndroid Build Coastguard Worker
DescribeRunningTasks() const1050*6777b538SAndroid Build Coastguard Worker std::string TaskEnvironment::TestTaskTracker::DescribeRunningTasks() const {
1051*6777b538SAndroid Build Coastguard Worker base::flat_map<int64_t, Location> running_tasks_copy;
1052*6777b538SAndroid Build Coastguard Worker {
1053*6777b538SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
1054*6777b538SAndroid Build Coastguard Worker running_tasks_copy = running_tasks_;
1055*6777b538SAndroid Build Coastguard Worker }
1056*6777b538SAndroid Build Coastguard Worker std::string running_tasks_str = "ThreadPool currently running tasks:";
1057*6777b538SAndroid Build Coastguard Worker if (running_tasks_copy.empty()) {
1058*6777b538SAndroid Build Coastguard Worker running_tasks_str += " none.";
1059*6777b538SAndroid Build Coastguard Worker } else {
1060*6777b538SAndroid Build Coastguard Worker for (auto& pair : running_tasks_copy) {
1061*6777b538SAndroid Build Coastguard Worker running_tasks_str += "\n Task posted from: " + pair.second.ToString();
1062*6777b538SAndroid Build Coastguard Worker }
1063*6777b538SAndroid Build Coastguard Worker }
1064*6777b538SAndroid Build Coastguard Worker return running_tasks_str;
1065*6777b538SAndroid Build Coastguard Worker }
1066*6777b538SAndroid Build Coastguard Worker
BeginCompleteShutdown(base::WaitableEvent & shutdown_event)1067*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::TestTaskTracker::BeginCompleteShutdown(
1068*6777b538SAndroid Build Coastguard Worker base::WaitableEvent& shutdown_event) {
1069*6777b538SAndroid Build Coastguard Worker const TimeDelta kTimeout = TestTimeouts::action_max_timeout();
1070*6777b538SAndroid Build Coastguard Worker if (shutdown_event.TimedWait(kTimeout)) {
1071*6777b538SAndroid Build Coastguard Worker return; // All tasks completed in time, yay! Yield back to shutdown.
1072*6777b538SAndroid Build Coastguard Worker }
1073*6777b538SAndroid Build Coastguard Worker
1074*6777b538SAndroid Build Coastguard Worker // If we had to wait too long for the shutdown tasks to complete, then we
1075*6777b538SAndroid Build Coastguard Worker // should fail the test and report which tasks are currently running.
1076*6777b538SAndroid Build Coastguard Worker std::string failure_tasks = DescribeRunningTasks();
1077*6777b538SAndroid Build Coastguard Worker
1078*6777b538SAndroid Build Coastguard Worker ADD_FAILURE() << "TaskEnvironment: CompleteShutdown took more than "
1079*6777b538SAndroid Build Coastguard Worker << kTimeout.InSeconds() << " seconds.\n"
1080*6777b538SAndroid Build Coastguard Worker << failure_tasks;
1081*6777b538SAndroid Build Coastguard Worker base::Process::TerminateCurrentProcessImmediately(-1);
1082*6777b538SAndroid Build Coastguard Worker }
1083*6777b538SAndroid Build Coastguard Worker
AssertFlushForTestingAllowed()1084*6777b538SAndroid Build Coastguard Worker void TaskEnvironment::TestTaskTracker::AssertFlushForTestingAllowed() {
1085*6777b538SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
1086*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(can_run_tasks_)
1087*6777b538SAndroid Build Coastguard Worker << "FlushForTesting() requires ThreadPool tasks to be allowed to run or "
1088*6777b538SAndroid Build Coastguard Worker "it will hang. Note: DisallowRunTasks happens implicitly on-and-off "
1089*6777b538SAndroid Build Coastguard Worker "during TaskEnvironment::RunUntilIdle and main thread tasks running "
1090*6777b538SAndroid Build Coastguard Worker "under it should thus never FlushForTesting().";
1091*6777b538SAndroid Build Coastguard Worker }
1092*6777b538SAndroid Build Coastguard Worker
1093*6777b538SAndroid Build Coastguard Worker } // namespace test
1094*6777b538SAndroid Build Coastguard Worker } // namespace base
1095