| 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 |