OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/message_loop/message_loop_task_runner.h" | 5 #include "base/message_loop/message_loop_task_runner.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/atomic_sequence_num.h" | 9 #include "base/atomic_sequence_num.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // Die if base::Bind doesn't retain a reference to the recorders. | 120 // Die if base::Bind doesn't retain a reference to the recorders. |
121 task_recorder = NULL; | 121 task_recorder = NULL; |
122 reply_recorder = NULL; | 122 reply_recorder = NULL; |
123 ASSERT_FALSE(task_deleted_on); | 123 ASSERT_FALSE(task_deleted_on); |
124 ASSERT_FALSE(reply_deleted_on); | 124 ASSERT_FALSE(reply_deleted_on); |
125 | 125 |
126 UnblockTaskThread(); | 126 UnblockTaskThread(); |
127 RunLoop().Run(); | 127 RunLoop().Run(); |
128 | 128 |
129 EXPECT_EQ(task_thread_.message_loop(), task_run_on); | 129 EXPECT_EQ(task_thread_.message_loop(), task_run_on); |
130 EXPECT_EQ(current_loop_.get(), task_deleted_on); | 130 EXPECT_EQ(task_thread_.message_loop(), task_deleted_on); |
131 EXPECT_EQ(current_loop_.get(), reply_run_on); | 131 EXPECT_EQ(current_loop_.get(), reply_run_on); |
132 EXPECT_EQ(current_loop_.get(), reply_deleted_on); | 132 EXPECT_EQ(current_loop_.get(), reply_deleted_on); |
133 EXPECT_LT(task_delete_order, reply_delete_order); | 133 EXPECT_LT(task_delete_order, reply_delete_order); |
134 } | 134 } |
135 | 135 |
136 TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReplyOnDeletedThreadDoesNotLeak) { | 136 TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReplyOnDeletedThreadDoesNotLeak) { |
137 MessageLoop* task_run_on = NULL; | 137 MessageLoop* task_run_on = NULL; |
138 MessageLoop* task_deleted_on = NULL; | 138 MessageLoop* task_deleted_on = NULL; |
139 int task_delete_order = -1; | 139 int task_delete_order = -1; |
140 MessageLoop* reply_run_on = NULL; | 140 MessageLoop* reply_run_on = NULL; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 | 193 |
194 RunLoop().Run(); | 194 RunLoop().Run(); |
195 | 195 |
196 EXPECT_EQ(current_loop_.get(), task_run_on); | 196 EXPECT_EQ(current_loop_.get(), task_run_on); |
197 EXPECT_EQ(current_loop_.get(), task_deleted_on); | 197 EXPECT_EQ(current_loop_.get(), task_deleted_on); |
198 EXPECT_EQ(current_loop_.get(), reply_run_on); | 198 EXPECT_EQ(current_loop_.get(), reply_run_on); |
199 EXPECT_EQ(current_loop_.get(), reply_deleted_on); | 199 EXPECT_EQ(current_loop_.get(), reply_deleted_on); |
200 EXPECT_LT(task_delete_order, reply_delete_order); | 200 EXPECT_LT(task_delete_order, reply_delete_order); |
201 } | 201 } |
202 | 202 |
203 TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReply_DeadReplyLoopDoesNotDelete) { | 203 TEST_F(MessageLoopTaskRunnerTest, |
| 204 PostTaskAndReply_DeadReplyTaskRunnerBehavior) { |
204 // Annotate the scope as having memory leaks to suppress heapchecker reports. | 205 // Annotate the scope as having memory leaks to suppress heapchecker reports. |
205 ANNOTATE_SCOPED_MEMORY_LEAK; | 206 ANNOTATE_SCOPED_MEMORY_LEAK; |
206 MessageLoop* task_run_on = NULL; | 207 MessageLoop* task_run_on = NULL; |
207 MessageLoop* task_deleted_on = NULL; | 208 MessageLoop* task_deleted_on = NULL; |
208 int task_delete_order = -1; | 209 int task_delete_order = -1; |
209 MessageLoop* reply_run_on = NULL; | 210 MessageLoop* reply_run_on = NULL; |
210 MessageLoop* reply_deleted_on = NULL; | 211 MessageLoop* reply_deleted_on = NULL; |
211 int reply_delete_order = -1; | 212 int reply_delete_order = -1; |
212 | 213 |
213 scoped_refptr<LoopRecorder> task_recorder = | 214 scoped_refptr<LoopRecorder> task_recorder = |
(...skipping 16 matching lines...) Expand all Loading... |
230 | 231 |
231 // Mercilessly whack the current loop before |reply| gets to run. | 232 // Mercilessly whack the current loop before |reply| gets to run. |
232 current_loop_.reset(); | 233 current_loop_.reset(); |
233 | 234 |
234 // This should ensure the relay has been run. We need to record the | 235 // This should ensure the relay has been run. We need to record the |
235 // MessageLoop pointer before stopping the thread because Thread::Stop() will | 236 // MessageLoop pointer before stopping the thread because Thread::Stop() will |
236 // NULL out its own pointer. | 237 // NULL out its own pointer. |
237 MessageLoop* task_loop = task_thread_.message_loop(); | 238 MessageLoop* task_loop = task_thread_.message_loop(); |
238 task_thread_.Stop(); | 239 task_thread_.Stop(); |
239 | 240 |
| 241 // Even if the reply task runner is already gone, the original task should |
| 242 // already be deleted. However, the reply which hasn't executed yet should |
| 243 // leak to avoid thread-safety issues. |
240 EXPECT_EQ(task_loop, task_run_on); | 244 EXPECT_EQ(task_loop, task_run_on); |
241 ASSERT_FALSE(task_deleted_on); | 245 EXPECT_EQ(task_loop, task_deleted_on); |
242 EXPECT_FALSE(reply_run_on); | 246 EXPECT_FALSE(reply_run_on); |
243 ASSERT_FALSE(reply_deleted_on); | 247 ASSERT_FALSE(reply_deleted_on); |
244 EXPECT_EQ(task_delete_order, reply_delete_order); | |
245 | 248 |
246 // The PostTaskAndReplyRelay is leaked here. Even if we had a reference to | 249 // The PostTaskAndReplyRelay is leaked here. Even if we had a reference to |
247 // it, we cannot just delete it because PostTaskAndReplyRelay's destructor | 250 // it, we cannot just delete it because PostTaskAndReplyRelay's destructor |
248 // checks that MessageLoop::current() is the the same as when the | 251 // checks that MessageLoop::current() is the the same as when the |
249 // PostTaskAndReplyRelay object was constructed. However, this loop must have | 252 // PostTaskAndReplyRelay object was constructed. However, this loop must have |
250 // already been deleted in order to perform this test. See | 253 // already been deleted in order to perform this test. See |
251 // http://crbug.com/86301. | 254 // http://crbug.com/86301. |
252 } | 255 } |
253 | 256 |
254 class MessageLoopTaskRunnerThreadingTest : public testing::Test { | 257 class MessageLoopTaskRunnerThreadingTest : public testing::Test { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 new Thread("MessageLoopTaskRunnerThreadingTest_Dummy")); | 356 new Thread("MessageLoopTaskRunnerThreadingTest_Dummy")); |
354 test_thread->Start(); | 357 test_thread->Start(); |
355 task_runner = test_thread->task_runner(); | 358 task_runner = test_thread->task_runner(); |
356 } | 359 } |
357 bool ret = task_runner->PostTask( | 360 bool ret = task_runner->PostTask( |
358 FROM_HERE, Bind(&MessageLoopTaskRunnerThreadingTest::AssertNotRun)); | 361 FROM_HERE, Bind(&MessageLoopTaskRunnerThreadingTest::AssertNotRun)); |
359 EXPECT_FALSE(ret); | 362 EXPECT_FALSE(ret); |
360 } | 363 } |
361 | 364 |
362 } // namespace base | 365 } // namespace base |
OLD | NEW |