blob: d8849defa9a7bf02e4bdf457adf374a747e6c759 [file] [log] [blame]
fdoray03181a72016-10-28 01:19:08 +09001// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/task_scheduler/task_tracker_posix.h"
6
7#include <unistd.h>
8
9#include <utility>
10
11#include "base/bind.h"
Peter Kasting88430fa2018-02-13 15:22:40 +090012#include "base/bind_helpers.h"
fdoray03181a72016-10-28 01:19:08 +090013#include "base/files/file_descriptor_watcher_posix.h"
Francois Doraya9b608b2017-08-04 23:56:22 +090014#include "base/macros.h"
fdoray03181a72016-10-28 01:19:08 +090015#include "base/memory/ptr_util.h"
Francois Doraya9b608b2017-08-04 23:56:22 +090016#include "base/memory/ref_counted.h"
fdoray03181a72016-10-28 01:19:08 +090017#include "base/message_loop/message_loop.h"
18#include "base/posix/eintr_wrapper.h"
19#include "base/run_loop.h"
20#include "base/sequence_token.h"
21#include "base/task_scheduler/task.h"
22#include "base/task_scheduler/task_traits.h"
Jeffrey He5b18cb92017-06-07 00:36:03 +090023#include "base/task_scheduler/test_utils.h"
Francois Doraya9b608b2017-08-04 23:56:22 +090024#include "base/test/null_task_runner.h"
25#include "base/threading/thread.h"
fdoray03181a72016-10-28 01:19:08 +090026#include "base/time/time.h"
27#include "testing/gtest/include/gtest/gtest.h"
28
29namespace base {
30namespace internal {
31
Francois Doraya9b608b2017-08-04 23:56:22 +090032namespace {
33
34class TaskSchedulerTaskTrackerPosixTest : public testing::Test {
35 public:
36 TaskSchedulerTaskTrackerPosixTest() : service_thread_("ServiceThread") {
37 Thread::Options service_thread_options;
38 service_thread_options.message_loop_type = MessageLoop::TYPE_IO;
39 service_thread_.StartWithOptions(service_thread_options);
40 tracker_.set_watch_file_descriptor_message_loop(
41 static_cast<MessageLoopForIO*>(service_thread_.message_loop()));
42 }
43
44 protected:
45 Thread service_thread_;
Gabriel Charette19075392018-01-19 20:00:53 +090046 TaskTrackerPosix tracker_ = {"Test"};
Francois Doraya9b608b2017-08-04 23:56:22 +090047
48 private:
49 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerTaskTrackerPosixTest);
50};
51
52} // namespace
53
fdoray03181a72016-10-28 01:19:08 +090054// Verify that TaskTrackerPosix runs a Task it receives.
Francois Doraya9b608b2017-08-04 23:56:22 +090055TEST_F(TaskSchedulerTaskTrackerPosixTest, RunTask) {
fdoray03181a72016-10-28 01:19:08 +090056 bool did_run = false;
Robert Liao6ce6b3c2017-12-18 10:38:07 +090057 Task task(FROM_HERE,
58 Bind([](bool* did_run) { *did_run = true; }, Unretained(&did_run)),
59 TaskTraits(), TimeDelta());
fdoray03181a72016-10-28 01:19:08 +090060
Robert Liao6ce6b3c2017-12-18 10:38:07 +090061 EXPECT_TRUE(tracker_.WillPostTask(task));
Jeffrey He5b18cb92017-06-07 00:36:03 +090062
Francois Doraycfa05a82017-10-13 03:10:17 +090063 auto sequence = test::CreateSequenceWithTask(std::move(task));
64 EXPECT_EQ(sequence, tracker_.WillScheduleSequence(sequence, nullptr));
Robert Liao72b27712018-02-17 04:27:45 +090065 // Expect RunAndPopNextTask to return nullptr since |sequence| is empty after
Francois Doraycfa05a82017-10-13 03:10:17 +090066 // popping a task from it.
Robert Liao72b27712018-02-17 04:27:45 +090067 EXPECT_FALSE(tracker_.RunAndPopNextTask(sequence, nullptr));
Jeffrey He5b18cb92017-06-07 00:36:03 +090068
fdoray03181a72016-10-28 01:19:08 +090069 EXPECT_TRUE(did_run);
70}
71
72// Verify that FileDescriptorWatcher::WatchReadable() can be called from a task
73// running in TaskTrackerPosix without a crash.
Francois Doraya9b608b2017-08-04 23:56:22 +090074TEST_F(TaskSchedulerTaskTrackerPosixTest, FileDescriptorWatcher) {
fdoray03181a72016-10-28 01:19:08 +090075 int fds[2];
76 ASSERT_EQ(0, pipe(fds));
Robert Liao6ce6b3c2017-12-18 10:38:07 +090077 Task task(FROM_HERE,
78 Bind(IgnoreResult(&FileDescriptorWatcher::WatchReadable), fds[0],
Peter Kasting24efe5e2018-02-24 09:03:01 +090079 DoNothing()),
Robert Liao6ce6b3c2017-12-18 10:38:07 +090080 TaskTraits(), TimeDelta());
Francois Doraya9b608b2017-08-04 23:56:22 +090081 // FileDescriptorWatcher::WatchReadable needs a SequencedTaskRunnerHandle.
Robert Liao6ce6b3c2017-12-18 10:38:07 +090082 task.sequenced_task_runner_ref = MakeRefCounted<NullTaskRunner>();
fdoray03181a72016-10-28 01:19:08 +090083
Robert Liao6ce6b3c2017-12-18 10:38:07 +090084 EXPECT_TRUE(tracker_.WillPostTask(task));
Jeffrey He5b18cb92017-06-07 00:36:03 +090085
Francois Doraycfa05a82017-10-13 03:10:17 +090086 auto sequence = test::CreateSequenceWithTask(std::move(task));
87 EXPECT_EQ(sequence, tracker_.WillScheduleSequence(sequence, nullptr));
Robert Liao72b27712018-02-17 04:27:45 +090088 // Expect RunAndPopNextTask to return nullptr since |sequence| is empty after
Francois Doraycfa05a82017-10-13 03:10:17 +090089 // popping a task from it.
Robert Liao72b27712018-02-17 04:27:45 +090090 EXPECT_FALSE(tracker_.RunAndPopNextTask(sequence, nullptr));
fdoray03181a72016-10-28 01:19:08 +090091
Francois Doraya9b608b2017-08-04 23:56:22 +090092 // Join the service thread to make sure that the read watch is registered and
93 // unregistered before file descriptors are closed.
94 service_thread_.Stop();
fdoray03181a72016-10-28 01:19:08 +090095
96 EXPECT_EQ(0, IGNORE_EINTR(close(fds[0])));
97 EXPECT_EQ(0, IGNORE_EINTR(close(fds[1])));
98}
99
100} // namespace internal
101} // namespace base