44
55#include " base/task/sequenced_task_runner.h"
66
7+ #include < array>
78#include < utility>
89
10+ #include " base/barrier_closure.h"
911#include " base/functional/bind.h"
1012#include " base/functional/callback.h"
1113#include " base/functional/callback_helpers.h"
1618#include " base/run_loop.h"
1719#include " base/sequence_checker_impl.h"
1820#include " base/task/sequenced_task_runner.h"
21+ #include " base/task/single_thread_task_runner.h"
22+ #include " base/task/task_traits.h"
1923#include " base/task/thread_pool.h"
2024#include " base/test/bind.h"
2125#include " base/test/gtest_util.h"
@@ -215,6 +219,9 @@ class SequencedTaskRunnerCurrentDefaultHandleTest : public ::testing::Test {
215219 test::TaskEnvironment task_environment_;
216220};
217221
222+ using SequencedTaskRunnerCurrentDefaultHandleDeathTest =
223+ SequencedTaskRunnerCurrentDefaultHandleTest;
224+
218225} // namespace
219226
220227TEST_F (SequencedTaskRunnerCurrentDefaultHandleTest, FromTaskEnvironment) {
@@ -239,7 +246,7 @@ TEST_F(SequencedTaskRunnerCurrentDefaultHandleTest,
239246
240247// Verify that `CurrentDefaultHandle` can be used to set the current default
241248// `SequencedTaskRunner` to null in a scope that already has a default.
242- TEST_F (SequencedTaskRunnerCurrentDefaultHandleTest , OverrideWithNull) {
249+ TEST_F (SequencedTaskRunnerCurrentDefaultHandleDeathTest , OverrideWithNull) {
243250 EXPECT_TRUE (SequencedTaskRunner::HasCurrentDefault ());
244251 auto tr1 = SequencedTaskRunner::GetCurrentDefault ();
245252 EXPECT_TRUE (tr1);
@@ -292,4 +299,167 @@ TEST(SequencedTaskRunnerCurrentDefaultHandleTestWithoutTaskEnvironment,
292299 EXPECT_FALSE (SingleThreadTaskRunner::HasCurrentDefault ());
293300}
294301
302+ TEST (SequencedTaskRunnerCurrentBestEffortTest, SequenceManagerSingleQueue) {
303+ // TaskEnvironment wraps a SequenceManager with a single default task queue.
304+ test::TaskEnvironment task_env;
305+ EXPECT_FALSE (SequencedTaskRunner::HasCurrentBestEffort ());
306+ ASSERT_TRUE (SequencedTaskRunner::HasCurrentDefault ());
307+
308+ // Should fall back to returning the default task runner when no best-effort
309+ // task runner is set.
310+ EXPECT_EQ (SequencedTaskRunner::GetCurrentBestEffort (),
311+ SequencedTaskRunner::GetCurrentDefault ());
312+ }
313+
314+ TEST (SequencedTaskRunnerCurrentBestEffortTest, SequenceManagerManyQueues) {
315+ // TaskEnvironmentWithMainThreadPriorities wraps a SequenceManager with
316+ // several task queues.
317+ test::TaskEnvironmentWithMainThreadPriorities task_env;
318+ EXPECT_TRUE (SequencedTaskRunner::HasCurrentBestEffort ());
319+ ASSERT_TRUE (SequencedTaskRunner::HasCurrentDefault ());
320+ ASSERT_TRUE (SequencedTaskRunner::GetCurrentBestEffort ());
321+
322+ // The best-effort task runner should NOT be the default.
323+ EXPECT_NE (SequencedTaskRunner::GetCurrentBestEffort (),
324+ SequencedTaskRunner::GetCurrentDefault ());
325+
326+ // All should run tasks on the same sequence. They differ only in priority.
327+
328+ // Use SequenceCheckerImpl to make sure it's not a no-op in Release builds.
329+ SequenceCheckerImpl sequence_checker;
330+
331+ RunLoop run_loop;
332+ auto quit_closure = BarrierClosure (2 , run_loop.QuitClosure ());
333+ SequencedTaskRunner::GetCurrentBestEffort ()->PostTask (
334+ FROM_HERE, BindLambdaForTesting ([&] {
335+ EXPECT_TRUE (sequence_checker.CalledOnValidSequence ())
336+ << " GetCurrentBestEffort" ;
337+ }).Then (quit_closure));
338+ SequencedTaskRunner::GetCurrentDefault ()->PostTask (
339+ FROM_HERE, BindLambdaForTesting ([&] {
340+ EXPECT_TRUE (sequence_checker.CalledOnValidSequence ())
341+ << " GetCurrentDefault" ;
342+ }).Then (quit_closure));
343+ run_loop.Run ();
344+ }
345+
346+ TEST (SequencedTaskRunnerCurrentBestEffortTest, ThreadPoolSingleThreadTask) {
347+ test::TaskEnvironmentWithMainThreadPriorities task_env;
348+
349+ EXPECT_TRUE (SequencedTaskRunner::HasCurrentBestEffort ());
350+ auto task_env_best_effort_task_runner =
351+ SequencedTaskRunner::GetCurrentBestEffort ();
352+
353+ // Use SequenceCheckerImpl to make sure it's not a no-op in Release builds.
354+ SequenceCheckerImpl sequence_checker;
355+
356+ // Test GetCurrentBestEffort() from a default-priority task and a BEST_EFFORT
357+ // task.
358+ constexpr auto kPriorities =
359+ std::to_array ({TaskPriority::USER_BLOCKING, TaskPriority::BEST_EFFORT});
360+
361+ for (auto priority : kPriorities ) {
362+ ThreadPool::CreateSingleThreadTaskRunner ({priority})
363+ ->PostTask (FROM_HERE,
364+ BindLambdaForTesting ([&] {
365+ SCOPED_TRACE (priority);
366+
367+ // TODO(crbug.com/441949788): Even if this is on a
368+ // BEST_EFFORT task runner, HasCurrentBestEffort() returns
369+ // false because it only supports SequenceManager task
370+ // queues.
371+ EXPECT_FALSE (SequencedTaskRunner::HasCurrentBestEffort ());
372+ ASSERT_TRUE (SequencedTaskRunner::HasCurrentDefault ());
373+
374+ // Should fall back to returning the default task runner
375+ // when no best-effort task runner is set.
376+ EXPECT_EQ (SequencedTaskRunner::GetCurrentBestEffort (),
377+ SequencedTaskRunner::GetCurrentDefault ());
378+
379+ // It should NOT be the TaskEnvironment's best-effort task
380+ // runner.
381+ EXPECT_NE (SequencedTaskRunner::GetCurrentBestEffort (),
382+ task_env_best_effort_task_runner);
383+ EXPECT_FALSE (sequence_checker.CalledOnValidSequence ());
384+ }).Then (task_env.QuitClosure ()));
385+ task_env.RunUntilQuit ();
386+ }
387+ }
388+
389+ TEST (SequencedTaskRunnerCurrentBestEffortTest, ThreadPoolSequencedTask) {
390+ test::TaskEnvironmentWithMainThreadPriorities task_env;
391+
392+ EXPECT_TRUE (SequencedTaskRunner::HasCurrentBestEffort ());
393+ auto task_env_best_effort_task_runner =
394+ SequencedTaskRunner::GetCurrentBestEffort ();
395+
396+ // Use SequenceCheckerImpl to make sure it's not a no-op in Release builds.
397+ SequenceCheckerImpl sequence_checker;
398+
399+ // Test GetCurrentBestEffort() from a default-priority task and a BEST_EFFORT
400+ // task.
401+ constexpr auto kPriorities =
402+ std::to_array ({TaskPriority::USER_BLOCKING, TaskPriority::BEST_EFFORT});
403+
404+ for (auto priority : kPriorities ) {
405+ ThreadPool::CreateSequencedTaskRunner ({priority})
406+ ->PostTask (FROM_HERE,
407+ BindLambdaForTesting ([&] {
408+ SCOPED_TRACE (priority);
409+
410+ // TODO(crbug.com/441949788): Even if this is on a
411+ // BEST_EFFORT task runner, HasCurrentBestEffort() returns
412+ // false because it only supports SequenceManager task
413+ // queues.
414+ EXPECT_FALSE (SequencedTaskRunner::HasCurrentBestEffort ());
415+ ASSERT_TRUE (SequencedTaskRunner::HasCurrentDefault ());
416+
417+ // Should fall back to returning the default task runner
418+ // when no best-effort task runner is set.
419+ EXPECT_EQ (SequencedTaskRunner::GetCurrentBestEffort (),
420+ SequencedTaskRunner::GetCurrentDefault ());
421+
422+ // It should NOT be the TaskEnvironment's best-effort task
423+ // runner.
424+ EXPECT_NE (SequencedTaskRunner::GetCurrentBestEffort (),
425+ task_env_best_effort_task_runner);
426+ EXPECT_FALSE (sequence_checker.CalledOnValidSequence ());
427+ }).Then (task_env.QuitClosure ()));
428+ task_env.RunUntilQuit ();
429+ }
430+ }
431+
432+ TEST (SequencedTaskRunnerCurrentBestEffortTest, ThreadPoolUnsequencedTask) {
433+ test::TaskEnvironmentWithMainThreadPriorities task_env;
434+
435+ EXPECT_TRUE (SequencedTaskRunner::HasCurrentBestEffort ());
436+
437+ // Test GetCurrentBestEffort() from a default-priority task and a BEST_EFFORT
438+ // task.
439+ constexpr auto kPriorities =
440+ std::to_array ({TaskPriority::USER_BLOCKING, TaskPriority::BEST_EFFORT});
441+
442+ for (auto priority : kPriorities ) {
443+ ThreadPool::PostTask (
444+ FROM_HERE, {priority},
445+ BindLambdaForTesting ([&] {
446+ SCOPED_TRACE (priority);
447+
448+ // The current task isn't bound to a sequence.
449+ EXPECT_FALSE (SequencedTaskRunner::HasCurrentBestEffort ());
450+ EXPECT_FALSE (SequencedTaskRunner::HasCurrentDefault ());
451+ }).Then (task_env.QuitClosure ()));
452+ task_env.RunUntilQuit ();
453+ }
454+ }
455+
456+ TEST (SequencedTaskRunnerCurrentBestEffortDeathTest, NoContext) {
457+ EXPECT_FALSE (SequencedTaskRunner::HasCurrentBestEffort ());
458+ EXPECT_FALSE (SequencedTaskRunner::HasCurrentDefault ());
459+ // Ensure that GetCurrentBestEffort() doesn't return a value when
460+ // HasCurrentDefault() is false.
461+ EXPECT_CHECK_DEATH (
462+ { auto task_runner = SequencedTaskRunner::GetCurrentBestEffort (); });
463+ }
464+
295465} // namespace base
0 commit comments