OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/logging.h" | 5 #include "base/logging.h" |
6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
7 #include "base/platform_thread.h" | 7 #include "base/platform_thread.h" |
8 #include "base/ref_counted.h" | 8 #include "base/ref_counted.h" |
9 #include "base/thread.h" | 9 #include "base/thread.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 | 130 |
131 // Now kick things off with the SEH block active. | 131 // Now kick things off with the SEH block active. |
132 MessageLoop::current()->set_exception_restoration(true); | 132 MessageLoop::current()->set_exception_restoration(true); |
133 MessageLoop::current()->Run(); | 133 MessageLoop::current()->Run(); |
134 MessageLoop::current()->set_exception_restoration(false); | 134 MessageLoop::current()->set_exception_restoration(false); |
135 | 135 |
136 EXPECT_EQ(foo->test_count(), 105); | 136 EXPECT_EQ(foo->test_count(), 105); |
137 EXPECT_EQ(foo->result(), "abacad"); | 137 EXPECT_EQ(foo->result(), "abacad"); |
138 } | 138 } |
139 | 139 |
| 140 // This class runs slowly to simulate a large amount of work being done. |
| 141 class SlowTask : public Task { |
| 142 public: |
| 143 SlowTask(int pause_ms, int* quit_counter) |
| 144 : pause_ms_(pause_ms), quit_counter_(quit_counter) { |
| 145 } |
| 146 virtual void Run() { |
| 147 PlatformThread::Sleep(pause_ms_); |
| 148 if (--(*quit_counter_) == 0) |
| 149 MessageLoop::current()->Quit(); |
| 150 } |
| 151 private: |
| 152 int pause_ms_; |
| 153 int* quit_counter_; |
| 154 }; |
| 155 |
| 156 // This class records the time when Run was called in a Time object, which is |
| 157 // useful for building a variety of MessageLoop tests. |
| 158 class RecordRunTimeTask : public SlowTask { |
| 159 public: |
| 160 RecordRunTimeTask(Time* run_time, int* quit_counter) |
| 161 : SlowTask(10, quit_counter), run_time_(run_time) { |
| 162 } |
| 163 virtual void Run() { |
| 164 *run_time_ = Time::Now(); |
| 165 // Cause our Run function to take some time to execute. As a result we can |
| 166 // count on subsequent RecordRunTimeTask objects running at a future time, |
| 167 // without worry about the resolution of our system clock being an issue. |
| 168 SlowTask::Run(); |
| 169 } |
| 170 private: |
| 171 Time* run_time_; |
| 172 }; |
| 173 |
| 174 void RunTest_PostDelayedTask_Basic(MessageLoop::Type message_loop_type) { |
| 175 MessageLoop loop(message_loop_type); |
| 176 |
| 177 // Test that PostDelayedTask results in a delayed task. |
| 178 |
| 179 const int kDelayMS = 100; |
| 180 |
| 181 int num_tasks = 1; |
| 182 Time run_time; |
| 183 |
| 184 loop.PostDelayedTask( |
| 185 FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), kDelayMS); |
| 186 |
| 187 Time time_before_run = Time::Now(); |
| 188 loop.Run(); |
| 189 Time time_after_run = Time::Now(); |
| 190 |
| 191 EXPECT_EQ(0, num_tasks); |
| 192 EXPECT_LT(kDelayMS, (time_after_run - time_before_run).InMilliseconds()); |
| 193 } |
| 194 |
| 195 void RunTest_PostDelayedTask_InDelayOrder(MessageLoop::Type message_loop_type) { |
| 196 MessageLoop loop(message_loop_type); |
| 197 |
| 198 // Test that two tasks with different delays run in the right order. |
| 199 |
| 200 int num_tasks = 2; |
| 201 Time run_time1, run_time2; |
| 202 |
| 203 loop.PostDelayedTask( |
| 204 FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), 200); |
| 205 // If we get a large pause in execution (due to a context switch) here, this |
| 206 // test could fail. |
| 207 loop.PostDelayedTask( |
| 208 FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 10); |
| 209 |
| 210 loop.Run(); |
| 211 EXPECT_EQ(0, num_tasks); |
| 212 |
| 213 EXPECT_TRUE(run_time2 < run_time1); |
| 214 } |
| 215 |
| 216 void RunTest_PostDelayedTask_InPostOrder(MessageLoop::Type message_loop_type) { |
| 217 MessageLoop loop(message_loop_type); |
| 218 |
| 219 // Test that two tasks with the same delay run in the order in which they |
| 220 // were posted. |
| 221 // |
| 222 // NOTE: This is actually an approximate test since the API only takes a |
| 223 // "delay" parameter, so we are not exactly simulating two tasks that get |
| 224 // posted at the exact same time. It would be nice if the API allowed us to |
| 225 // specify the desired run time. |
| 226 |
| 227 const int kDelayMS = 100; |
| 228 |
| 229 int num_tasks = 2; |
| 230 Time run_time1, run_time2; |
| 231 |
| 232 loop.PostDelayedTask( |
| 233 FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), kDelayMS); |
| 234 loop.PostDelayedTask( |
| 235 FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), kDelayMS); |
| 236 |
| 237 loop.Run(); |
| 238 EXPECT_EQ(0, num_tasks); |
| 239 |
| 240 EXPECT_TRUE(run_time1 < run_time2); |
| 241 } |
| 242 |
| 243 void RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::Type message_loop_type)
{ |
| 244 MessageLoop loop(message_loop_type); |
| 245 |
| 246 // Test that a delayed task still runs after a normal tasks even if the |
| 247 // normal tasks take a long time to run. |
| 248 |
| 249 const int kPauseMS = 50; |
| 250 |
| 251 int num_tasks = 2; |
| 252 Time run_time; |
| 253 |
| 254 loop.PostTask( |
| 255 FROM_HERE, new SlowTask(kPauseMS, &num_tasks)); |
| 256 loop.PostDelayedTask( |
| 257 FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), 10); |
| 258 |
| 259 Time time_before_run = Time::Now(); |
| 260 loop.Run(); |
| 261 Time time_after_run = Time::Now(); |
| 262 |
| 263 EXPECT_EQ(0, num_tasks); |
| 264 |
| 265 EXPECT_LT(kPauseMS, (time_after_run - time_before_run).InMilliseconds()); |
| 266 } |
| 267 |
| 268 void RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::Type message_loop_type)
{ |
| 269 MessageLoop loop(message_loop_type); |
| 270 |
| 271 // Test that a delayed task still runs after a pile of normal tasks. The key |
| 272 // difference between this test and the previous one is that here we return |
| 273 // the MessageLoop a lot so we give the MessageLoop plenty of opportunities |
| 274 // to maybe run the delayed task. It should know not to do so until the |
| 275 // delayed task's delay has passed. |
| 276 |
| 277 int num_tasks = 11; |
| 278 Time run_time1, run_time2; |
| 279 |
| 280 // Clutter the ML with tasks. |
| 281 for (int i = 1; i < num_tasks; ++i) |
| 282 loop.PostTask(FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks)); |
| 283 |
| 284 loop.PostDelayedTask( |
| 285 FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 1); |
| 286 |
| 287 loop.Run(); |
| 288 EXPECT_EQ(0, num_tasks); |
| 289 |
| 290 EXPECT_TRUE(run_time2 > run_time1); |
| 291 } |
| 292 |
140 class NestingTest : public Task { | 293 class NestingTest : public Task { |
141 public: | 294 public: |
142 explicit NestingTest(int* depth) : depth_(depth) { | 295 explicit NestingTest(int* depth) : depth_(depth) { |
143 } | 296 } |
144 void Run() { | 297 void Run() { |
145 if (*depth_ > 0) { | 298 if (*depth_ > 0) { |
146 *depth_ -= 1; | 299 *depth_ -= 1; |
147 MessageLoop::current()->PostTask(FROM_HERE, new NestingTest(depth_)); | 300 MessageLoop::current()->PostTask(FROM_HERE, new NestingTest(depth_)); |
148 | 301 |
149 MessageLoop::current()->SetNestableTasksAllowed(true); | 302 MessageLoop::current()->SetNestableTasksAllowed(true); |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 } | 851 } |
699 }; | 852 }; |
700 | 853 |
701 // Tests that non nestable tasks run in FIFO if there are no nested loops. | 854 // Tests that non nestable tasks run in FIFO if there are no nested loops. |
702 void RunTest_NonNestableWithNoNesting(MessageLoop::Type message_loop_type) { | 855 void RunTest_NonNestableWithNoNesting(MessageLoop::Type message_loop_type) { |
703 MessageLoop loop(message_loop_type); | 856 MessageLoop loop(message_loop_type); |
704 | 857 |
705 TaskList order; | 858 TaskList order; |
706 | 859 |
707 Task* task = new OrderedTasks(&order, 1); | 860 Task* task = new OrderedTasks(&order, 1); |
708 task->set_nestable(false); | 861 MessageLoop::current()->PostNonNestableTask(FROM_HERE, task); |
709 MessageLoop::current()->PostTask(FROM_HERE, task); | |
710 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 2)); | 862 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 2)); |
711 MessageLoop::current()->PostTask(FROM_HERE, new QuitTask(&order, 3)); | 863 MessageLoop::current()->PostTask(FROM_HERE, new QuitTask(&order, 3)); |
712 MessageLoop::current()->Run(); | 864 MessageLoop::current()->Run(); |
713 | 865 |
714 // FIFO order. | 866 // FIFO order. |
715 ASSERT_EQ(6U, order.size()); | 867 ASSERT_EQ(6U, order.size()); |
716 EXPECT_EQ(order[ 0], TaskItem(ORDERERD, 1, true)); | 868 EXPECT_EQ(order[ 0], TaskItem(ORDERERD, 1, true)); |
717 EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 1, false)); | 869 EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 1, false)); |
718 EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 2, true)); | 870 EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 2, true)); |
719 EXPECT_EQ(order[ 3], TaskItem(ORDERERD, 2, false)); | 871 EXPECT_EQ(order[ 3], TaskItem(ORDERERD, 2, false)); |
720 EXPECT_EQ(order[ 4], TaskItem(QUITMESSAGELOOP, 3, true)); | 872 EXPECT_EQ(order[ 4], TaskItem(QUITMESSAGELOOP, 3, true)); |
721 EXPECT_EQ(order[ 5], TaskItem(QUITMESSAGELOOP, 3, false)); | 873 EXPECT_EQ(order[ 5], TaskItem(QUITMESSAGELOOP, 3, false)); |
722 } | 874 } |
723 | 875 |
724 // Tests that non nestable tasks don't run when there's code in the call stack. | 876 // Tests that non nestable tasks don't run when there's code in the call stack. |
725 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type) { | 877 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type) { |
726 MessageLoop loop(message_loop_type); | 878 MessageLoop loop(message_loop_type); |
727 | 879 |
728 TaskList order; | 880 TaskList order; |
729 | 881 |
730 MessageLoop::current()->PostTask(FROM_HERE, | 882 MessageLoop::current()->PostTask(FROM_HERE, |
731 new TaskThatPumps(&order, 1)); | 883 new TaskThatPumps(&order, 1)); |
732 Task* task = new OrderedTasks(&order, 2); | 884 Task* task = new OrderedTasks(&order, 2); |
733 task->set_nestable(false); | 885 MessageLoop::current()->PostNonNestableTask(FROM_HERE, task); |
734 MessageLoop::current()->PostTask(FROM_HERE, task); | |
735 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 3)); | 886 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 3)); |
736 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 4)); | 887 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 4)); |
737 Task* non_nestable_quit = new QuitTask(&order, 5); | 888 Task* non_nestable_quit = new QuitTask(&order, 5); |
738 non_nestable_quit->set_nestable(false); | 889 MessageLoop::current()->PostNonNestableTask(FROM_HERE, non_nestable_quit); |
739 MessageLoop::current()->PostTask(FROM_HERE, non_nestable_quit); | |
740 | 890 |
741 MessageLoop::current()->Run(); | 891 MessageLoop::current()->Run(); |
742 | 892 |
743 // FIFO order. | 893 // FIFO order. |
744 ASSERT_EQ(10U, order.size()); | 894 ASSERT_EQ(10U, order.size()); |
745 EXPECT_EQ(order[ 0], TaskItem(PUMPS, 1, true)); | 895 EXPECT_EQ(order[ 0], TaskItem(PUMPS, 1, true)); |
746 EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 3, true)); | 896 EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 3, true)); |
747 EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 3, false)); | 897 EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 3, false)); |
748 EXPECT_EQ(order[ 3], TaskItem(ORDERERD, 4, true)); | 898 EXPECT_EQ(order[ 3], TaskItem(ORDERERD, 4, true)); |
749 EXPECT_EQ(order[ 4], TaskItem(ORDERERD, 4, false)); | 899 EXPECT_EQ(order[ 4], TaskItem(ORDERERD, 4, false)); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 RunTest_PostTask(MessageLoop::TYPE_UI); | 1012 RunTest_PostTask(MessageLoop::TYPE_UI); |
863 RunTest_PostTask(MessageLoop::TYPE_IO); | 1013 RunTest_PostTask(MessageLoop::TYPE_IO); |
864 } | 1014 } |
865 | 1015 |
866 TEST(MessageLoopTest, PostTask_SEH) { | 1016 TEST(MessageLoopTest, PostTask_SEH) { |
867 RunTest_PostTask_SEH(MessageLoop::TYPE_DEFAULT); | 1017 RunTest_PostTask_SEH(MessageLoop::TYPE_DEFAULT); |
868 RunTest_PostTask_SEH(MessageLoop::TYPE_UI); | 1018 RunTest_PostTask_SEH(MessageLoop::TYPE_UI); |
869 RunTest_PostTask_SEH(MessageLoop::TYPE_IO); | 1019 RunTest_PostTask_SEH(MessageLoop::TYPE_IO); |
870 } | 1020 } |
871 | 1021 |
| 1022 TEST(MessageLoopTest, PostDelayedTask_Basic) { |
| 1023 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_DEFAULT); |
| 1024 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_UI); |
| 1025 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_IO); |
| 1026 } |
| 1027 |
| 1028 TEST(MessageLoopTest, PostDelayedTask_InDelayOrder) { |
| 1029 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_DEFAULT); |
| 1030 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_UI); |
| 1031 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_IO); |
| 1032 } |
| 1033 |
| 1034 TEST(MessageLoopTest, PostDelayedTask_InPostOrder) { |
| 1035 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_DEFAULT); |
| 1036 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_UI); |
| 1037 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_IO); |
| 1038 } |
| 1039 |
| 1040 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_2) { |
| 1041 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_DEFAULT); |
| 1042 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_UI); |
| 1043 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_IO); |
| 1044 } |
| 1045 |
| 1046 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_3) { |
| 1047 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_DEFAULT); |
| 1048 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_UI); |
| 1049 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_IO); |
| 1050 } |
| 1051 |
872 #if defined(OS_WIN) | 1052 #if defined(OS_WIN) |
873 TEST(MessageLoopTest, Crasher) { | 1053 TEST(MessageLoopTest, Crasher) { |
874 RunTest_Crasher(MessageLoop::TYPE_DEFAULT); | 1054 RunTest_Crasher(MessageLoop::TYPE_DEFAULT); |
875 RunTest_Crasher(MessageLoop::TYPE_UI); | 1055 RunTest_Crasher(MessageLoop::TYPE_UI); |
876 RunTest_Crasher(MessageLoop::TYPE_IO); | 1056 RunTest_Crasher(MessageLoop::TYPE_IO); |
877 } | 1057 } |
878 | 1058 |
879 TEST(MessageLoopTest, CrasherNasty) { | 1059 TEST(MessageLoopTest, CrasherNasty) { |
880 RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT); | 1060 RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT); |
881 RunTest_CrasherNasty(MessageLoop::TYPE_UI); | 1061 RunTest_CrasherNasty(MessageLoop::TYPE_UI); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 TEST(MessageLoopTest, AutoresetEvents) { | 1110 TEST(MessageLoopTest, AutoresetEvents) { |
931 // This test requires an IO loop | 1111 // This test requires an IO loop |
932 RunTest_AutoresetEvents(MessageLoop::TYPE_IO); | 1112 RunTest_AutoresetEvents(MessageLoop::TYPE_IO); |
933 } | 1113 } |
934 | 1114 |
935 TEST(MessageLoopTest, Dispatcher) { | 1115 TEST(MessageLoopTest, Dispatcher) { |
936 // This test requires a UI loop | 1116 // This test requires a UI loop |
937 RunTest_Dispatcher(MessageLoop::TYPE_UI); | 1117 RunTest_Dispatcher(MessageLoop::TYPE_UI); |
938 } | 1118 } |
939 #endif // defined(OS_WIN) | 1119 #endif // defined(OS_WIN) |
OLD | NEW |