OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/deferred_sequenced_task_runner.h" | 5 #include "base/deferred_sequenced_task_runner.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/location.h" | |
11 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
12 #include "base/single_thread_task_runner.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/message_loop/message_loop_proxy.h" |
13 #include "base/threading/non_thread_safe.h" | 13 #include "base/threading/non_thread_safe.h" |
14 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
15 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 class DeferredSequencedTaskRunnerTest : public testing::Test, | 20 class DeferredSequencedTaskRunnerTest : public testing::Test, |
21 public base::NonThreadSafe { | 21 public base::NonThreadSafe { |
22 public: | 22 public: |
(...skipping 28 matching lines...) Expand all Loading... |
51 } | 51 } |
52 | 52 |
53 void StartRunner() { | 53 void StartRunner() { |
54 runner_->Start(); | 54 runner_->Start(); |
55 } | 55 } |
56 | 56 |
57 void DoNothing(ExecuteTaskOnDestructor* object) { | 57 void DoNothing(ExecuteTaskOnDestructor* object) { |
58 } | 58 } |
59 | 59 |
60 protected: | 60 protected: |
61 DeferredSequencedTaskRunnerTest() | 61 DeferredSequencedTaskRunnerTest() : |
62 : loop_(), | 62 loop_(), |
63 runner_(new base::DeferredSequencedTaskRunner(loop_.task_runner())) {} | 63 runner_( |
| 64 new base::DeferredSequencedTaskRunner(loop_.message_loop_proxy())) { |
| 65 } |
64 | 66 |
65 base::MessageLoop loop_; | 67 base::MessageLoop loop_; |
66 scoped_refptr<base::DeferredSequencedTaskRunner> runner_; | 68 scoped_refptr<base::DeferredSequencedTaskRunner> runner_; |
67 mutable base::Lock lock_; | 69 mutable base::Lock lock_; |
68 std::vector<int> executed_task_ids_; | 70 std::vector<int> executed_task_ids_; |
69 }; | 71 }; |
70 | 72 |
71 TEST_F(DeferredSequencedTaskRunnerTest, Stopped) { | 73 TEST_F(DeferredSequencedTaskRunnerTest, Stopped) { |
72 PostExecuteTask(1); | 74 PostExecuteTask(1); |
73 loop_.RunUntilIdle(); | 75 loop_.RunUntilIdle(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8)); | 119 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8)); |
118 } | 120 } |
119 | 121 |
120 TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleThreads) { | 122 TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleThreads) { |
121 { | 123 { |
122 base::Thread thread1("DeferredSequencedTaskRunnerTestThread1"); | 124 base::Thread thread1("DeferredSequencedTaskRunnerTestThread1"); |
123 base::Thread thread2("DeferredSequencedTaskRunnerTestThread2"); | 125 base::Thread thread2("DeferredSequencedTaskRunnerTestThread2"); |
124 thread1.Start(); | 126 thread1.Start(); |
125 thread2.Start(); | 127 thread2.Start(); |
126 for (int i = 0; i < 5; ++i) { | 128 for (int i = 0; i < 5; ++i) { |
127 thread1.task_runner()->PostTask( | 129 thread1.message_loop()->PostTask( |
128 FROM_HERE, | 130 FROM_HERE, |
129 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask, | 131 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask, |
130 base::Unretained(this), 2 * i)); | 132 base::Unretained(this), |
131 thread2.task_runner()->PostTask( | 133 2 * i)); |
| 134 thread2.message_loop()->PostTask( |
132 FROM_HERE, | 135 FROM_HERE, |
133 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask, | 136 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask, |
134 base::Unretained(this), 2 * i + 1)); | 137 base::Unretained(this), |
| 138 2 * i + 1)); |
135 if (i == 2) { | 139 if (i == 2) { |
136 thread1.task_runner()->PostTask( | 140 thread1.message_loop()->PostTask( |
137 FROM_HERE, base::Bind(&DeferredSequencedTaskRunnerTest::StartRunner, | 141 FROM_HERE, |
138 base::Unretained(this))); | 142 base::Bind(&DeferredSequencedTaskRunnerTest::StartRunner, |
| 143 base::Unretained(this))); |
139 } | 144 } |
140 } | 145 } |
141 } | 146 } |
142 | 147 |
143 loop_.RunUntilIdle(); | 148 loop_.RunUntilIdle(); |
144 EXPECT_THAT(executed_task_ids_, | 149 EXPECT_THAT(executed_task_ids_, |
145 testing::WhenSorted(testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); | 150 testing::WhenSorted(testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); |
146 } | 151 } |
147 | 152 |
148 TEST_F(DeferredSequencedTaskRunnerTest, ObjectDestructionOrder) { | 153 TEST_F(DeferredSequencedTaskRunnerTest, ObjectDestructionOrder) { |
149 { | 154 { |
150 base::Thread thread("DeferredSequencedTaskRunnerTestThread"); | 155 base::Thread thread("DeferredSequencedTaskRunnerTestThread"); |
151 thread.Start(); | 156 thread.Start(); |
152 runner_ = new base::DeferredSequencedTaskRunner(thread.task_runner()); | 157 runner_ = |
| 158 new base::DeferredSequencedTaskRunner(thread.message_loop_proxy()); |
153 for (int i = 0; i < 5; ++i) { | 159 for (int i = 0; i < 5; ++i) { |
154 { | 160 { |
155 // Use a block to ensure that no reference to |short_lived_object| | 161 // Use a block to ensure that no reference to |short_lived_object| |
156 // is kept on the main thread after it is posted to |runner_|. | 162 // is kept on the main thread after it is posted to |runner_|. |
157 scoped_refptr<ExecuteTaskOnDestructor> short_lived_object = | 163 scoped_refptr<ExecuteTaskOnDestructor> short_lived_object = |
158 new ExecuteTaskOnDestructor(this, 2 * i); | 164 new ExecuteTaskOnDestructor(this, 2 * i); |
159 runner_->PostTask( | 165 runner_->PostTask( |
160 FROM_HERE, | 166 FROM_HERE, |
161 base::Bind(&DeferredSequencedTaskRunnerTest::DoNothing, | 167 base::Bind(&DeferredSequencedTaskRunnerTest::DoNothing, |
162 base::Unretained(this), | 168 base::Unretained(this), |
163 short_lived_object)); | 169 short_lived_object)); |
164 } | 170 } |
165 // |short_lived_object| with id |2 * i| should be destroyed before the | 171 // |short_lived_object| with id |2 * i| should be destroyed before the |
166 // task |2 * i + 1| is executed. | 172 // task |2 * i + 1| is executed. |
167 PostExecuteTask(2 * i + 1); | 173 PostExecuteTask(2 * i + 1); |
168 } | 174 } |
169 StartRunner(); | 175 StartRunner(); |
170 } | 176 } |
171 | 177 |
172 // All |short_lived_object| with id |2 * i| are destroyed before the task | 178 // All |short_lived_object| with id |2 * i| are destroyed before the task |
173 // |2 * i + 1| is executed. | 179 // |2 * i + 1| is executed. |
174 EXPECT_THAT(executed_task_ids_, | 180 EXPECT_THAT(executed_task_ids_, |
175 testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); | 181 testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); |
176 } | 182 } |
177 | 183 |
178 } // namespace | 184 } // namespace |
OLD | NEW |