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" |
10 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
11 #include "base/message_loop/message_loop.h" | 12 #include "base/single_thread_task_runner.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_( | 63 runner_(new base::DeferredSequencedTaskRunner(loop_.task_runner())) {} |
64 new base::DeferredSequencedTaskRunner(loop_.message_loop_proxy())) { | |
65 } | |
66 | 64 |
67 base::MessageLoop loop_; | 65 base::MessageLoop loop_; |
68 scoped_refptr<base::DeferredSequencedTaskRunner> runner_; | 66 scoped_refptr<base::DeferredSequencedTaskRunner> runner_; |
69 mutable base::Lock lock_; | 67 mutable base::Lock lock_; |
70 std::vector<int> executed_task_ids_; | 68 std::vector<int> executed_task_ids_; |
71 }; | 69 }; |
72 | 70 |
73 TEST_F(DeferredSequencedTaskRunnerTest, Stopped) { | 71 TEST_F(DeferredSequencedTaskRunnerTest, Stopped) { |
74 PostExecuteTask(1); | 72 PostExecuteTask(1); |
75 loop_.RunUntilIdle(); | 73 loop_.RunUntilIdle(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8)); | 117 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8)); |
120 } | 118 } |
121 | 119 |
122 TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleThreads) { | 120 TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleThreads) { |
123 { | 121 { |
124 base::Thread thread1("DeferredSequencedTaskRunnerTestThread1"); | 122 base::Thread thread1("DeferredSequencedTaskRunnerTestThread1"); |
125 base::Thread thread2("DeferredSequencedTaskRunnerTestThread2"); | 123 base::Thread thread2("DeferredSequencedTaskRunnerTestThread2"); |
126 thread1.Start(); | 124 thread1.Start(); |
127 thread2.Start(); | 125 thread2.Start(); |
128 for (int i = 0; i < 5; ++i) { | 126 for (int i = 0; i < 5; ++i) { |
129 thread1.message_loop()->PostTask( | 127 thread1.task_runner()->PostTask( |
130 FROM_HERE, | 128 FROM_HERE, |
131 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask, | 129 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask, |
132 base::Unretained(this), | 130 base::Unretained(this), 2 * i)); |
133 2 * i)); | 131 thread2.task_runner()->PostTask( |
134 thread2.message_loop()->PostTask( | |
135 FROM_HERE, | 132 FROM_HERE, |
136 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask, | 133 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask, |
137 base::Unretained(this), | 134 base::Unretained(this), 2 * i + 1)); |
138 2 * i + 1)); | |
139 if (i == 2) { | 135 if (i == 2) { |
140 thread1.message_loop()->PostTask( | 136 thread1.task_runner()->PostTask( |
141 FROM_HERE, | 137 FROM_HERE, base::Bind(&DeferredSequencedTaskRunnerTest::StartRunner, |
142 base::Bind(&DeferredSequencedTaskRunnerTest::StartRunner, | 138 base::Unretained(this))); |
143 base::Unretained(this))); | |
144 } | 139 } |
145 } | 140 } |
146 } | 141 } |
147 | 142 |
148 loop_.RunUntilIdle(); | 143 loop_.RunUntilIdle(); |
149 EXPECT_THAT(executed_task_ids_, | 144 EXPECT_THAT(executed_task_ids_, |
150 testing::WhenSorted(testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); | 145 testing::WhenSorted(testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); |
151 } | 146 } |
152 | 147 |
153 TEST_F(DeferredSequencedTaskRunnerTest, ObjectDestructionOrder) { | 148 TEST_F(DeferredSequencedTaskRunnerTest, ObjectDestructionOrder) { |
154 { | 149 { |
155 base::Thread thread("DeferredSequencedTaskRunnerTestThread"); | 150 base::Thread thread("DeferredSequencedTaskRunnerTestThread"); |
156 thread.Start(); | 151 thread.Start(); |
157 runner_ = | 152 runner_ = new base::DeferredSequencedTaskRunner(thread.task_runner()); |
158 new base::DeferredSequencedTaskRunner(thread.message_loop_proxy()); | |
159 for (int i = 0; i < 5; ++i) { | 153 for (int i = 0; i < 5; ++i) { |
160 { | 154 { |
161 // Use a block to ensure that no reference to |short_lived_object| | 155 // Use a block to ensure that no reference to |short_lived_object| |
162 // is kept on the main thread after it is posted to |runner_|. | 156 // is kept on the main thread after it is posted to |runner_|. |
163 scoped_refptr<ExecuteTaskOnDestructor> short_lived_object = | 157 scoped_refptr<ExecuteTaskOnDestructor> short_lived_object = |
164 new ExecuteTaskOnDestructor(this, 2 * i); | 158 new ExecuteTaskOnDestructor(this, 2 * i); |
165 runner_->PostTask( | 159 runner_->PostTask( |
166 FROM_HERE, | 160 FROM_HERE, |
167 base::Bind(&DeferredSequencedTaskRunnerTest::DoNothing, | 161 base::Bind(&DeferredSequencedTaskRunnerTest::DoNothing, |
168 base::Unretained(this), | 162 base::Unretained(this), |
169 short_lived_object)); | 163 short_lived_object)); |
170 } | 164 } |
171 // |short_lived_object| with id |2 * i| should be destroyed before the | 165 // |short_lived_object| with id |2 * i| should be destroyed before the |
172 // task |2 * i + 1| is executed. | 166 // task |2 * i + 1| is executed. |
173 PostExecuteTask(2 * i + 1); | 167 PostExecuteTask(2 * i + 1); |
174 } | 168 } |
175 StartRunner(); | 169 StartRunner(); |
176 } | 170 } |
177 | 171 |
178 // All |short_lived_object| with id |2 * i| are destroyed before the task | 172 // All |short_lived_object| with id |2 * i| are destroyed before the task |
179 // |2 * i + 1| is executed. | 173 // |2 * i + 1| is executed. |
180 EXPECT_THAT(executed_task_ids_, | 174 EXPECT_THAT(executed_task_ids_, |
181 testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); | 175 testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); |
182 } | 176 } |
183 | 177 |
184 } // namespace | 178 } // namespace |
OLD | NEW |