Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(374)

Side by Side Diff: base/message_loop_unittest.cc

Issue 6463013: Add support for base::Closure in the MessageLoop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: address will's comments. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <vector> 5 #include <vector>
6 6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
7 #include "base/eintr_wrapper.h" 10 #include "base/eintr_wrapper.h"
8 #include "base/logging.h" 11 #include "base/logging.h"
9 #include "base/message_loop.h" 12 #include "base/message_loop.h"
10 #include "base/ref_counted.h" 13 #include "base/ref_counted.h"
11 #include "base/task.h"
12 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
13 #include "base/threading/thread.h" 15 #include "base/threading/thread.h"
14 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
15 17
16 #if defined(OS_WIN) 18 #if defined(OS_WIN)
17 #include "base/message_pump_win.h" 19 #include "base/message_pump_win.h"
18 #include "base/win/scoped_handle.h" 20 #include "base/win/scoped_handle.h"
19 #endif 21 #endif
20 #if defined(OS_POSIX) 22 #if defined(OS_POSIX)
21 #include "base/message_pump_libevent.h" 23 #include "base/message_pump_libevent.h"
22 #endif 24 #endif
23 25
24 using base::PlatformThread; 26 using base::PlatformThread;
25 using base::Thread; 27 using base::Thread;
26 using base::Time; 28 using base::Time;
27 using base::TimeDelta; 29 using base::TimeDelta;
30 using base::TimeTicks;
28 31
29 // TODO(darin): Platform-specific MessageLoop tests should be grouped together 32 // TODO(darin): Platform-specific MessageLoop tests should be grouped together
30 // to avoid chopping this file up with so many #ifdefs. 33 // to avoid chopping this file up with so many #ifdefs.
31 34
32 namespace { 35 namespace {
33 36
34 class MessageLoopTest : public testing::Test {}; 37 class MessageLoopTest : public testing::Test {};
35 38
36 class Foo : public base::RefCounted<Foo> { 39 class Foo : public base::RefCounted<Foo> {
37 public: 40 public:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 76
74 private: 77 private:
75 friend class base::RefCounted<Foo>; 78 friend class base::RefCounted<Foo>;
76 79
77 ~Foo() {} 80 ~Foo() {}
78 81
79 int test_count_; 82 int test_count_;
80 std::string result_; 83 std::string result_;
81 }; 84 };
82 85
83 class QuitMsgLoop : public base::RefCounted<QuitMsgLoop> { 86 // TODO(ajwong): Remove this once we've finished getting rid of the PostTask()
84 public: 87 // compatibility methods.
85 void QuitNow() {
86 MessageLoop::current()->Quit();
87 }
88
89 private:
90 friend class base::RefCounted<QuitMsgLoop>;
91
92 ~QuitMsgLoop() {}
93 };
94
95 void RunTest_PostTask(MessageLoop::Type message_loop_type) { 88 void RunTest_PostTask(MessageLoop::Type message_loop_type) {
96 MessageLoop loop(message_loop_type); 89 MessageLoop loop(message_loop_type);
97 90
98 // Add tests to message loop 91 // Add tests to message loop
99 scoped_refptr<Foo> foo(new Foo()); 92 scoped_refptr<Foo> foo(new Foo());
100 std::string a("a"), b("b"), c("c"), d("d"); 93 std::string a("a"), b("b"), c("c"), d("d");
101 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 94 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
102 foo.get(), &Foo::Test0)); 95 foo.get(), &Foo::Test0));
103 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 96 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
104 foo.get(), &Foo::Test1ConstRef, a)); 97 foo.get(), &Foo::Test1ConstRef, a));
105 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 98 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
106 foo.get(), &Foo::Test1Ptr, &b)); 99 foo.get(), &Foo::Test1Ptr, &b));
107 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 100 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
108 foo.get(), &Foo::Test1Int, 100)); 101 foo.get(), &Foo::Test1Int, 100));
109 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 102 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
110 foo.get(), &Foo::Test2Ptr, &a, &c)); 103 foo.get(), &Foo::Test2Ptr, &a, &c));
111 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 104 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
112 foo.get(), &Foo::Test2Mixed, a, &d)); 105 foo.get(), &Foo::Test2Mixed, a, &d));
113 106
114 // After all tests, post a message that will shut down the message loop 107 // After all tests, post a message that will shut down the message loop
115 scoped_refptr<QuitMsgLoop> quit(new QuitMsgLoop()); 108 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
116 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 109 &MessageLoop::Quit, base::Unretained(MessageLoop::current())));
117 quit.get(), &QuitMsgLoop::QuitNow));
118 110
119 // Now kick things off 111 // Now kick things off
120 MessageLoop::current()->Run(); 112 MessageLoop::current()->Run();
121 113
122 EXPECT_EQ(foo->test_count(), 105); 114 EXPECT_EQ(foo->test_count(), 105);
123 EXPECT_EQ(foo->result(), "abacad"); 115 EXPECT_EQ(foo->result(), "abacad");
124 } 116 }
125 117
126 void RunTest_PostTask_SEH(MessageLoop::Type message_loop_type) { 118 void RunTest_PostClosure(MessageLoop::Type message_loop_type) {
127 MessageLoop loop(message_loop_type); 119 MessageLoop loop(message_loop_type);
128 120
129 // Add tests to message loop 121 // Add tests to message loop
130 scoped_refptr<Foo> foo(new Foo()); 122 scoped_refptr<Foo> foo(new Foo());
131 std::string a("a"), b("b"), c("c"), d("d"); 123 std::string a("a"), b("b"), c("c"), d("d");
132 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 124 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
133 foo.get(), &Foo::Test0)); 125 &Foo::Test0, foo.get()));
134 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 126 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
135 foo.get(), &Foo::Test1ConstRef, a)); 127 &Foo::Test1ConstRef, foo.get(), a));
136 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 128 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
137 foo.get(), &Foo::Test1Ptr, &b)); 129 &Foo::Test1Ptr, foo.get(), &b));
138 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 130 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
139 foo.get(), &Foo::Test1Int, 100)); 131 &Foo::Test1Int, foo.get(), 100));
140 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 132 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
141 foo.get(), &Foo::Test2Ptr, &a, &c)); 133 &Foo::Test2Ptr, foo.get(), &a, &c));
142 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 134 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
143 foo.get(), &Foo::Test2Mixed, a, &d)); 135 &Foo::Test2Mixed, foo.get(), a, &d));
144 136
145 // After all tests, post a message that will shut down the message loop 137 // After all tests, post a message that will shut down the message loop
146 scoped_refptr<QuitMsgLoop> quit(new QuitMsgLoop()); 138 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
147 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 139 &MessageLoop::Quit, base::Unretained(MessageLoop::current())));
148 quit.get(), &QuitMsgLoop::QuitNow)); 140
141 // Now kick things off
142 MessageLoop::current()->Run();
143
144 EXPECT_EQ(foo->test_count(), 105);
145 EXPECT_EQ(foo->result(), "abacad");
146 }
147
148 void RunTest_PostClosure_SEH(MessageLoop::Type message_loop_type) {
149 MessageLoop loop(message_loop_type);
150
151 // Add tests to message loop
152 scoped_refptr<Foo> foo(new Foo());
153 std::string a("a"), b("b"), c("c"), d("d");
154 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
155 &Foo::Test0, foo.get()));
156 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
157 &Foo::Test1ConstRef,foo.get(), a));
158 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
159 &Foo::Test1Ptr,foo.get(), &b));
160 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
161 &Foo::Test1Int,foo.get(), 100));
162 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
163 &Foo::Test2Ptr,foo.get(), &a, &c));
164 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
165 &Foo::Test2Mixed,foo.get(), a, &d));
166
167 // After all tests, post a message that will shut down the message loop
168 MessageLoop::current()->PostClosure(FROM_HERE, base::Bind(
169 &MessageLoop::Quit, base::Unretained(MessageLoop::current())));
149 170
150 // Now kick things off with the SEH block active. 171 // Now kick things off with the SEH block active.
151 MessageLoop::current()->set_exception_restoration(true); 172 MessageLoop::current()->set_exception_restoration(true);
152 MessageLoop::current()->Run(); 173 MessageLoop::current()->Run();
153 MessageLoop::current()->set_exception_restoration(false); 174 MessageLoop::current()->set_exception_restoration(false);
154 175
155 EXPECT_EQ(foo->test_count(), 105); 176 EXPECT_EQ(foo->test_count(), 105);
156 EXPECT_EQ(foo->result(), "abacad"); 177 EXPECT_EQ(foo->result(), "abacad");
157 } 178 }
158 179
159 // This class runs slowly to simulate a large amount of work being done. 180 // This function runs slowly to simulate a large amount of work being done.
160 class SlowTask : public Task { 181 static void SlowFunc(int pause_ms, int* quit_counter) {
161 public: 182 PlatformThread::Sleep(pause_ms);
162 SlowTask(int pause_ms, int* quit_counter) 183 if (--(*quit_counter) == 0)
163 : pause_ms_(pause_ms), quit_counter_(quit_counter) {
164 }
165 virtual void Run() {
166 PlatformThread::Sleep(pause_ms_);
167 if (--(*quit_counter_) == 0)
168 MessageLoop::current()->Quit(); 184 MessageLoop::current()->Quit();
169 } 185 }
170 private:
171 int pause_ms_;
172 int* quit_counter_;
173 };
174 186
175 // This class records the time when Run was called in a Time object, which is 187 // This function records the time when Run was called in a Time object, which is
176 // useful for building a variety of MessageLoop tests. 188 // useful for building a variety of MessageLoop tests.
177 class RecordRunTimeTask : public SlowTask { 189 static void RecordRunTimeFunc(Time* run_time, int* quit_counter) {
178 public: 190 *run_time = Time::Now();
179 RecordRunTimeTask(Time* run_time, int* quit_counter) 191
180 : SlowTask(10, quit_counter), run_time_(run_time) {
181 }
182 virtual void Run() {
183 *run_time_ = Time::Now();
184 // Cause our Run function to take some time to execute. As a result we can 192 // Cause our Run function to take some time to execute. As a result we can
185 // count on subsequent RecordRunTimeTask objects running at a future time, 193 // count on subsequent RecordRunTimeFunc()s running at a future time,
186 // without worry about the resolution of our system clock being an issue. 194 // without worry about the resolution of our system clock being an issue.
187 SlowTask::Run(); 195 SlowFunc(10, quit_counter);
188 } 196 }
189 private:
190 Time* run_time_;
191 };
192 197
193 void RunTest_PostDelayedTask_Basic(MessageLoop::Type message_loop_type) { 198 void RunTest_PostDelayedClosure_Basic(MessageLoop::Type message_loop_type) {
194 MessageLoop loop(message_loop_type); 199 MessageLoop loop(message_loop_type);
195 200
196 // Test that PostDelayedTask results in a delayed task. 201 // Test that PostDelayedClosure results in a delayed task.
197 202
198 const int kDelayMS = 100; 203 const int kDelayMS = 100;
199 204
200 int num_tasks = 1; 205 int num_tasks = 1;
201 Time run_time; 206 Time run_time;
202 207
203 loop.PostDelayedTask( 208 loop.PostDelayedClosure(
204 FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), kDelayMS); 209 FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
210 kDelayMS);
205 211
206 Time time_before_run = Time::Now(); 212 Time time_before_run = Time::Now();
207 loop.Run(); 213 loop.Run();
208 Time time_after_run = Time::Now(); 214 Time time_after_run = Time::Now();
209 215
210 EXPECT_EQ(0, num_tasks); 216 EXPECT_EQ(0, num_tasks);
211 EXPECT_LT(kDelayMS, (time_after_run - time_before_run).InMilliseconds()); 217 EXPECT_LT(kDelayMS, (time_after_run - time_before_run).InMilliseconds());
212 } 218 }
213 219
214 void RunTest_PostDelayedTask_InDelayOrder(MessageLoop::Type message_loop_type) { 220 void RunTest_PostDelayedClosure_InDelayOrder(
221 MessageLoop::Type message_loop_type) {
215 MessageLoop loop(message_loop_type); 222 MessageLoop loop(message_loop_type);
216 223
217 // Test that two tasks with different delays run in the right order. 224 // Test that two tasks with different delays run in the right order.
218 225
219 int num_tasks = 2; 226 int num_tasks = 2;
220 Time run_time1, run_time2; 227 Time run_time1, run_time2;
221 228
222 loop.PostDelayedTask( 229 loop.PostDelayedClosure(
223 FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), 200); 230 FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), 200);
224 // If we get a large pause in execution (due to a context switch) here, this 231 // If we get a large pause in execution (due to a context switch) here, this
225 // test could fail. 232 // test could fail.
226 loop.PostDelayedTask( 233 loop.PostDelayedClosure(
227 FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 10); 234 FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), 10);
228 235
229 loop.Run(); 236 loop.Run();
230 EXPECT_EQ(0, num_tasks); 237 EXPECT_EQ(0, num_tasks);
231 238
232 EXPECT_TRUE(run_time2 < run_time1); 239 EXPECT_TRUE(run_time2 < run_time1);
233 } 240 }
234 241
235 void RunTest_PostDelayedTask_InPostOrder(MessageLoop::Type message_loop_type) { 242 void RunTest_PostDelayedClosure_InPostOrder(
243 MessageLoop::Type message_loop_type) {
236 MessageLoop loop(message_loop_type); 244 MessageLoop loop(message_loop_type);
237 245
238 // Test that two tasks with the same delay run in the order in which they 246 // Test that two tasks with the same delay run in the order in which they
239 // were posted. 247 // were posted.
240 // 248 //
241 // NOTE: This is actually an approximate test since the API only takes a 249 // NOTE: This is actually an approximate test since the API only takes a
242 // "delay" parameter, so we are not exactly simulating two tasks that get 250 // "delay" parameter, so we are not exactly simulating two tasks that get
243 // posted at the exact same time. It would be nice if the API allowed us to 251 // posted at the exact same time. It would be nice if the API allowed us to
244 // specify the desired run time. 252 // specify the desired run time.
245 253
246 const int kDelayMS = 100; 254 const int kDelayMS = 100;
247 255
248 int num_tasks = 2; 256 int num_tasks = 2;
249 Time run_time1, run_time2; 257 Time run_time1, run_time2;
250 258
251 loop.PostDelayedTask( 259 loop.PostDelayedClosure(
252 FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), kDelayMS); 260 FROM_HERE,
253 loop.PostDelayedTask( 261 base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks),
254 FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), kDelayMS); 262 kDelayMS);
263 loop.PostDelayedClosure(
264 FROM_HERE,
265 base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
266 kDelayMS);
255 267
256 loop.Run(); 268 loop.Run();
257 EXPECT_EQ(0, num_tasks); 269 EXPECT_EQ(0, num_tasks);
258 270
259 EXPECT_TRUE(run_time1 < run_time2); 271 EXPECT_TRUE(run_time1 < run_time2);
260 } 272 }
261 273
262 void RunTest_PostDelayedTask_InPostOrder_2( 274 void RunTest_PostDelayedClosure_InPostOrder_2(
263 MessageLoop::Type message_loop_type) { 275 MessageLoop::Type message_loop_type) {
264 MessageLoop loop(message_loop_type); 276 MessageLoop loop(message_loop_type);
265 277
266 // Test that a delayed task still runs after a normal tasks even if the 278 // Test that a delayed task still runs after a normal tasks even if the
267 // normal tasks take a long time to run. 279 // normal tasks take a long time to run.
268 280
269 const int kPauseMS = 50; 281 const int kPauseMS = 50;
270 282
271 int num_tasks = 2; 283 int num_tasks = 2;
272 Time run_time; 284 Time run_time;
273 285
274 loop.PostTask( 286 loop.PostClosure(
275 FROM_HERE, new SlowTask(kPauseMS, &num_tasks)); 287 FROM_HERE, base::Bind(&SlowFunc, kPauseMS, &num_tasks));
276 loop.PostDelayedTask( 288 loop.PostDelayedClosure(
277 FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), 10); 289 FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks), 10);
278 290
279 Time time_before_run = Time::Now(); 291 Time time_before_run = Time::Now();
280 loop.Run(); 292 loop.Run();
281 Time time_after_run = Time::Now(); 293 Time time_after_run = Time::Now();
282 294
283 EXPECT_EQ(0, num_tasks); 295 EXPECT_EQ(0, num_tasks);
284 296
285 EXPECT_LT(kPauseMS, (time_after_run - time_before_run).InMilliseconds()); 297 EXPECT_LT(kPauseMS, (time_after_run - time_before_run).InMilliseconds());
286 } 298 }
287 299
288 void RunTest_PostDelayedTask_InPostOrder_3( 300 void RunTest_PostDelayedClosure_InPostOrder_3(
289 MessageLoop::Type message_loop_type) { 301 MessageLoop::Type message_loop_type) {
290 MessageLoop loop(message_loop_type); 302 MessageLoop loop(message_loop_type);
291 303
292 // Test that a delayed task still runs after a pile of normal tasks. The key 304 // Test that a delayed task still runs after a pile of normal tasks. The key
293 // difference between this test and the previous one is that here we return 305 // difference between this test and the previous one is that here we return
294 // the MessageLoop a lot so we give the MessageLoop plenty of opportunities 306 // the MessageLoop a lot so we give the MessageLoop plenty of opportunities
295 // to maybe run the delayed task. It should know not to do so until the 307 // to maybe run the delayed task. It should know not to do so until the
296 // delayed task's delay has passed. 308 // delayed task's delay has passed.
297 309
298 int num_tasks = 11; 310 int num_tasks = 11;
299 Time run_time1, run_time2; 311 Time run_time1, run_time2;
300 312
301 // Clutter the ML with tasks. 313 // Clutter the ML with tasks.
302 for (int i = 1; i < num_tasks; ++i) 314 for (int i = 1; i < num_tasks; ++i)
303 loop.PostTask(FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks)); 315 loop.PostClosure(FROM_HERE,
316 base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks));
304 317
305 loop.PostDelayedTask( 318 loop.PostDelayedClosure(
306 FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 1); 319 FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), 1);
307 320
308 loop.Run(); 321 loop.Run();
309 EXPECT_EQ(0, num_tasks); 322 EXPECT_EQ(0, num_tasks);
310 323
311 EXPECT_TRUE(run_time2 > run_time1); 324 EXPECT_TRUE(run_time2 > run_time1);
312 } 325 }
313 326
314 void RunTest_PostDelayedTask_SharedTimer(MessageLoop::Type message_loop_type) { 327 void RunTest_PostDelayedClosure_SharedTimer(
328 MessageLoop::Type message_loop_type) {
315 MessageLoop loop(message_loop_type); 329 MessageLoop loop(message_loop_type);
316 330
317 // Test that the interval of the timer, used to run the next delayed task, is 331 // Test that the interval of the timer, used to run the next delayed task, is
318 // set to a value corresponding to when the next delayed task should run. 332 // set to a value corresponding to when the next delayed task should run.
319 333
320 // By setting num_tasks to 1, we ensure that the first task to run causes the 334 // By setting num_tasks to 1, we ensure that the first task to run causes the
321 // run loop to exit. 335 // run loop to exit.
322 int num_tasks = 1; 336 int num_tasks = 1;
323 Time run_time1, run_time2; 337 Time run_time1, run_time2;
324 338
325 loop.PostDelayedTask( 339 loop.PostDelayedClosure(
326 FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), 1000000); 340 FROM_HERE,
327 loop.PostDelayedTask( 341 base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks),
328 FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 10); 342 1000000);
343 loop.PostDelayedClosure(
344 FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), 10);
329 345
330 Time start_time = Time::Now(); 346 Time start_time = Time::Now();
331 347
332 loop.Run(); 348 loop.Run();
333 EXPECT_EQ(0, num_tasks); 349 EXPECT_EQ(0, num_tasks);
334 350
335 // Ensure that we ran in far less time than the slower timer. 351 // Ensure that we ran in far less time than the slower timer.
336 TimeDelta total_time = Time::Now() - start_time; 352 TimeDelta total_time = Time::Now() - start_time;
337 EXPECT_GT(5000, total_time.InMilliseconds()); 353 EXPECT_GT(5000, total_time.InMilliseconds());
338 354
339 // In case both timers somehow run at nearly the same time, sleep a little 355 // In case both timers somehow run at nearly the same time, sleep a little
340 // and then run all pending to force them both to have run. This is just 356 // and then run all pending to force them both to have run. This is just
341 // encouraging flakiness if there is any. 357 // encouraging flakiness if there is any.
342 PlatformThread::Sleep(100); 358 PlatformThread::Sleep(100);
343 loop.RunAllPending(); 359 loop.RunAllPending();
344 360
345 EXPECT_TRUE(run_time1.is_null()); 361 EXPECT_TRUE(run_time1.is_null());
346 EXPECT_FALSE(run_time2.is_null()); 362 EXPECT_FALSE(run_time2.is_null());
347 } 363 }
348 364
349 #if defined(OS_WIN) 365 #if defined(OS_WIN)
350 366
351 class SubPumpTask : public Task { 367 void SubPumpFunc() {
352 public: 368 MessageLoop::current()->SetNestableTasksAllowed(true);
353 virtual void Run() { 369 MSG msg;
354 MessageLoop::current()->SetNestableTasksAllowed(true); 370 while (GetMessage(&msg, NULL, 0, 0)) {
355 MSG msg; 371 TranslateMessage(&msg);
356 while (GetMessage(&msg, NULL, 0, 0)) { 372 DispatchMessage(&msg);
357 TranslateMessage(&msg);
358 DispatchMessage(&msg);
359 }
360 MessageLoop::current()->Quit();
361 } 373 }
362 }; 374 MessageLoop::current()->Quit();
375 }
363 376
364 class SubPumpQuitTask : public Task { 377 void RunTest_PostDelayedClosure_SharedTimer_SubPump() {
365 public:
366 SubPumpQuitTask() {
367 }
368 virtual void Run() {
369 PostQuitMessage(0);
370 }
371 };
372
373 void RunTest_PostDelayedTask_SharedTimer_SubPump() {
374 MessageLoop loop(MessageLoop::TYPE_UI); 378 MessageLoop loop(MessageLoop::TYPE_UI);
375 379
376 // Test that the interval of the timer, used to run the next delayed task, is 380 // Test that the interval of the timer, used to run the next delayed task, is
377 // set to a value corresponding to when the next delayed task should run. 381 // set to a value corresponding to when the next delayed task should run.
378 382
379 // By setting num_tasks to 1, we ensure that the first task to run causes the 383 // By setting num_tasks to 1, we ensure that the first task to run causes the
380 // run loop to exit. 384 // run loop to exit.
381 int num_tasks = 1; 385 int num_tasks = 1;
382 Time run_time; 386 Time run_time;
383 387
384 loop.PostTask(FROM_HERE, new SubPumpTask()); 388 loop.PostClosure(FROM_HERE, base::Bind(&SubPumpFunc));
385 389
386 // This very delayed task should never run. 390 // This very delayed task should never run.
387 loop.PostDelayedTask( 391 loop.PostDelayedClosure(
388 FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), 1000000); 392 FROM_HERE,
393 base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
394 1000000);
389 395
390 // This slightly delayed task should run from within SubPumpTask::Run(). 396 // This slightly delayed task should run from within SubPumpFunc).
391 loop.PostDelayedTask( 397 loop.PostDelayedClosure(FROM_HERE, base::Bind(&PostQuitMessage, 0), 10);
392 FROM_HERE, new SubPumpQuitTask(), 10);
393 398
394 Time start_time = Time::Now(); 399 Time start_time = Time::Now();
395 400
396 loop.Run(); 401 loop.Run();
397 EXPECT_EQ(1, num_tasks); 402 EXPECT_EQ(1, num_tasks);
398 403
399 // Ensure that we ran in far less time than the slower timer. 404 // Ensure that we ran in far less time than the slower timer.
400 TimeDelta total_time = Time::Now() - start_time; 405 TimeDelta total_time = Time::Now() - start_time;
401 EXPECT_GT(5000, total_time.InMilliseconds()); 406 EXPECT_GT(5000, total_time.InMilliseconds());
402 407
403 // In case both timers somehow run at nearly the same time, sleep a little 408 // In case both timers somehow run at nearly the same time, sleep a little
404 // and then run all pending to force them both to have run. This is just 409 // and then run all pending to force them both to have run. This is just
405 // encouraging flakiness if there is any. 410 // encouraging flakiness if there is any.
406 PlatformThread::Sleep(100); 411 PlatformThread::Sleep(100);
407 loop.RunAllPending(); 412 loop.RunAllPending();
408 413
409 EXPECT_TRUE(run_time.is_null()); 414 EXPECT_TRUE(run_time.is_null());
410 } 415 }
411 416
412 #endif // defined(OS_WIN) 417 #endif // defined(OS_WIN)
413 418
414 class RecordDeletionTask : public Task { 419 class RecordDeletionProbe : public base::RefCounted<RecordDeletionProbe> {
415 public: 420 public:
416 RecordDeletionTask(Task* post_on_delete, bool* was_deleted) 421 RecordDeletionProbe(RecordDeletionProbe* post_on_delete, bool* was_deleted)
417 : post_on_delete_(post_on_delete), was_deleted_(was_deleted) { 422 : post_on_delete_(post_on_delete), was_deleted_(was_deleted) {
418 } 423 }
419 ~RecordDeletionTask() { 424 ~RecordDeletionProbe() {
420 *was_deleted_ = true; 425 *was_deleted_ = true;
421 if (post_on_delete_) 426 if (post_on_delete_)
422 MessageLoop::current()->PostTask(FROM_HERE, post_on_delete_); 427 MessageLoop::current()->PostClosure(
428 FROM_HERE,
429 base::Bind(&RecordDeletionProbe::Run, post_on_delete_.get()));
423 } 430 }
424 virtual void Run() {} 431 virtual void Run() {}
425 private: 432 private:
426 Task* post_on_delete_; 433 scoped_refptr<RecordDeletionProbe> post_on_delete_;
427 bool* was_deleted_; 434 bool* was_deleted_;
428 }; 435 };
429 436
430 void RunTest_EnsureTaskDeletion(MessageLoop::Type message_loop_type) { 437 void RunTest_EnsureDeletion(MessageLoop::Type message_loop_type) {
431 bool a_was_deleted = false; 438 bool a_was_deleted = false;
432 bool b_was_deleted = false; 439 bool b_was_deleted = false;
433 { 440 {
434 MessageLoop loop(message_loop_type); 441 MessageLoop loop(message_loop_type);
435 loop.PostTask( 442 loop.PostClosure(
436 FROM_HERE, new RecordDeletionTask(NULL, &a_was_deleted)); 443 FROM_HERE, base::Bind(&RecordDeletionProbe::Run,
437 loop.PostDelayedTask( 444 new RecordDeletionProbe(NULL, &a_was_deleted)));
438 FROM_HERE, new RecordDeletionTask(NULL, &b_was_deleted), 1000); 445 loop.PostDelayedClosure(
446 FROM_HERE, base::Bind(&RecordDeletionProbe::Run,
447 new RecordDeletionProbe(NULL, &b_was_deleted)),
448 1000); // TODO(ajwong): Do we really need 1000ms here?
439 } 449 }
440 EXPECT_TRUE(a_was_deleted); 450 EXPECT_TRUE(a_was_deleted);
441 EXPECT_TRUE(b_was_deleted); 451 EXPECT_TRUE(b_was_deleted);
442 } 452 }
443 453
444 void RunTest_EnsureTaskDeletion_Chain(MessageLoop::Type message_loop_type) { 454 void RunTest_EnsureDeletion_Chain(MessageLoop::Type message_loop_type) {
445 bool a_was_deleted = false; 455 bool a_was_deleted = false;
446 bool b_was_deleted = false; 456 bool b_was_deleted = false;
447 bool c_was_deleted = false; 457 bool c_was_deleted = false;
448 { 458 {
449 MessageLoop loop(message_loop_type); 459 MessageLoop loop(message_loop_type);
450 RecordDeletionTask* a = new RecordDeletionTask(NULL, &a_was_deleted); 460 // The scoped_refptr for each of the below is held either by the chained
451 RecordDeletionTask* b = new RecordDeletionTask(a, &b_was_deleted); 461 // RecordDeletionProbe, or the bound RecordDeletionProbe::Run() callback.
452 RecordDeletionTask* c = new RecordDeletionTask(b, &c_was_deleted); 462 RecordDeletionProbe* a = new RecordDeletionProbe(NULL, &a_was_deleted);
453 loop.PostTask(FROM_HERE, c); 463 RecordDeletionProbe* b = new RecordDeletionProbe(a, &b_was_deleted);
464 RecordDeletionProbe* c = new RecordDeletionProbe(b, &c_was_deleted);
465 loop.PostClosure(FROM_HERE, base::Bind(&RecordDeletionProbe::Run, c));
454 } 466 }
455 EXPECT_TRUE(a_was_deleted); 467 EXPECT_TRUE(a_was_deleted);
456 EXPECT_TRUE(b_was_deleted); 468 EXPECT_TRUE(b_was_deleted);
457 EXPECT_TRUE(c_was_deleted); 469 EXPECT_TRUE(c_was_deleted);
458 } 470 }
459 471
460 class NestingTest : public Task { 472 void NestingFunc(int* depth) {
461 public: 473 if (*depth > 0) {
462 explicit NestingTest(int* depth) : depth_(depth) { 474 *depth -= 1;
475 MessageLoop::current()->PostClosure(FROM_HERE,
476 base::Bind(&NestingFunc, depth));
477
478 MessageLoop::current()->SetNestableTasksAllowed(true);
479 MessageLoop::current()->Run();
463 } 480 }
464 void Run() { 481 MessageLoop::current()->Quit();
465 if (*depth_ > 0) { 482 }
466 *depth_ -= 1;
467 MessageLoop::current()->PostTask(FROM_HERE, new NestingTest(depth_));
468
469 MessageLoop::current()->SetNestableTasksAllowed(true);
470 MessageLoop::current()->Run();
471 }
472 MessageLoop::current()->Quit();
473 }
474 private:
475 int* depth_;
476 };
477 483
478 #if defined(OS_WIN) 484 #if defined(OS_WIN)
479 485
480 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) { 486 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) {
481 ADD_FAILURE() << "bad exception handler"; 487 ADD_FAILURE() << "bad exception handler";
482 ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode); 488 ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode);
483 return EXCEPTION_EXECUTE_HANDLER; 489 return EXCEPTION_EXECUTE_HANDLER;
484 } 490 }
485 491
486 // This task throws an SEH exception: initially write to an invalid address. 492 // This task throws an SEH exception: initially write to an invalid address.
487 // If the right SEH filter is installed, it will fix the error. 493 // If the right SEH filter is installed, it will fix the error.
488 class CrasherTask : public Task { 494 class Crasher : public base::RefCounted<Crasher> {
489 public: 495 public:
490 // Ctor. If trash_SEH_handler is true, the task will override the unhandled 496 // Ctor. If trash_SEH_handler is true, the task will override the unhandled
491 // exception handler with one sure to crash this test. 497 // exception handler with one sure to crash this test.
492 explicit CrasherTask(bool trash_SEH_handler) 498 explicit Crasher(bool trash_SEH_handler)
493 : trash_SEH_handler_(trash_SEH_handler) { 499 : trash_SEH_handler_(trash_SEH_handler) {
494 } 500 }
501
495 void Run() { 502 void Run() {
496 PlatformThread::Sleep(1); 503 PlatformThread::Sleep(1);
497 if (trash_SEH_handler_) 504 if (trash_SEH_handler_)
498 ::SetUnhandledExceptionFilter(&BadExceptionHandler); 505 ::SetUnhandledExceptionFilter(&BadExceptionHandler);
499 // Generate a SEH fault. We do it in asm to make sure we know how to undo 506 // Generate a SEH fault. We do it in asm to make sure we know how to undo
500 // the damage. 507 // the damage.
501 508
502 #if defined(_M_IX86) 509 #if defined(_M_IX86)
503 510
504 __asm { 511 __asm {
505 mov eax, dword ptr [CrasherTask::bad_array_] 512 mov eax, dword ptr [Crasher::bad_array_]
506 mov byte ptr [eax], 66 513 mov byte ptr [eax], 66
507 } 514 }
508 515
509 #elif defined(_M_X64) 516 #elif defined(_M_X64)
510 517
511 bad_array_[0] = 66; 518 bad_array_[0] = 66;
512 519
513 #else 520 #else
514 #error "needs architecture support" 521 #error "needs architecture support"
515 #endif 522 #endif
516 523
517 MessageLoop::current()->Quit(); 524 MessageLoop::current()->Quit();
518 } 525 }
519 // Points the bad array to a valid memory location. 526 // Points the bad array to a valid memory location.
520 static void FixError() { 527 static void FixError() {
521 bad_array_ = &valid_store_; 528 bad_array_ = &valid_store_;
522 } 529 }
523 530
524 private: 531 private:
525 bool trash_SEH_handler_; 532 bool trash_SEH_handler_;
526 static volatile char* bad_array_; 533 static volatile char* bad_array_;
527 static char valid_store_; 534 static char valid_store_;
528 }; 535 };
529 536
530 volatile char* CrasherTask::bad_array_ = 0; 537 volatile char* Crasher::bad_array_ = 0;
531 char CrasherTask::valid_store_ = 0; 538 char Crasher::valid_store_ = 0;
532 539
533 // This SEH filter fixes the problem and retries execution. Fixing requires 540 // This SEH filter fixes the problem and retries execution. Fixing requires
534 // that the last instruction: mov eax, [CrasherTask::bad_array_] to be retried 541 // that the last instruction: mov eax, [Crasher::bad_array_] to be retried
535 // so we move the instruction pointer 5 bytes back. 542 // so we move the instruction pointer 5 bytes back.
536 LONG WINAPI HandleCrasherTaskException(EXCEPTION_POINTERS *ex_info) { 543 LONG WINAPI HandleCrasherException(EXCEPTION_POINTERS *ex_info) {
537 if (ex_info->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) 544 if (ex_info->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
538 return EXCEPTION_EXECUTE_HANDLER; 545 return EXCEPTION_EXECUTE_HANDLER;
539 546
540 CrasherTask::FixError(); 547 Crasher::FixError();
541 548
542 #if defined(_M_IX86) 549 #if defined(_M_IX86)
543 550
544 ex_info->ContextRecord->Eip -= 5; 551 ex_info->ContextRecord->Eip -= 5;
545 552
546 #elif defined(_M_X64) 553 #elif defined(_M_X64)
547 554
548 ex_info->ContextRecord->Rip -= 5; 555 ex_info->ContextRecord->Rip -= 5;
549 556
550 #endif 557 #endif
551 558
552 return EXCEPTION_CONTINUE_EXECUTION; 559 return EXCEPTION_CONTINUE_EXECUTION;
553 } 560 }
554 561
555 void RunTest_Crasher(MessageLoop::Type message_loop_type) { 562 void RunTest_Crasher(MessageLoop::Type message_loop_type) {
556 MessageLoop loop(message_loop_type); 563 MessageLoop loop(message_loop_type);
557 564
558 if (::IsDebuggerPresent()) 565 if (::IsDebuggerPresent())
559 return; 566 return;
560 567
561 LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter = 568 LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter =
562 ::SetUnhandledExceptionFilter(&HandleCrasherTaskException); 569 ::SetUnhandledExceptionFilter(&HandleCrasherException);
563 570
564 MessageLoop::current()->PostTask(FROM_HERE, new CrasherTask(false)); 571 MessageLoop::current()->PostClosure(
572 FROM_HERE,
573 base::Bind(&Crasher::Run, new Crasher(false)));
565 MessageLoop::current()->set_exception_restoration(true); 574 MessageLoop::current()->set_exception_restoration(true);
566 MessageLoop::current()->Run(); 575 MessageLoop::current()->Run();
567 MessageLoop::current()->set_exception_restoration(false); 576 MessageLoop::current()->set_exception_restoration(false);
568 577
569 ::SetUnhandledExceptionFilter(old_SEH_filter); 578 ::SetUnhandledExceptionFilter(old_SEH_filter);
570 } 579 }
571 580
572 void RunTest_CrasherNasty(MessageLoop::Type message_loop_type) { 581 void RunTest_CrasherNasty(MessageLoop::Type message_loop_type) {
573 MessageLoop loop(message_loop_type); 582 MessageLoop loop(message_loop_type);
574 583
575 if (::IsDebuggerPresent()) 584 if (::IsDebuggerPresent())
576 return; 585 return;
577 586
578 LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter = 587 LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter =
579 ::SetUnhandledExceptionFilter(&HandleCrasherTaskException); 588 ::SetUnhandledExceptionFilter(&HandleCrasherException);
580 589
581 MessageLoop::current()->PostTask(FROM_HERE, new CrasherTask(true)); 590 MessageLoop::current()->PostClosure(
591 FROM_HERE,
592 base::Bind(&Crasher::Run, new Crasher(true)));
582 MessageLoop::current()->set_exception_restoration(true); 593 MessageLoop::current()->set_exception_restoration(true);
583 MessageLoop::current()->Run(); 594 MessageLoop::current()->Run();
584 MessageLoop::current()->set_exception_restoration(false); 595 MessageLoop::current()->set_exception_restoration(false);
585 596
586 ::SetUnhandledExceptionFilter(old_SEH_filter); 597 ::SetUnhandledExceptionFilter(old_SEH_filter);
587 } 598 }
588 599
589 #endif // defined(OS_WIN) 600 #endif // defined(OS_WIN)
590 601
591 void RunTest_Nesting(MessageLoop::Type message_loop_type) { 602 void RunTest_Nesting(MessageLoop::Type message_loop_type) {
592 MessageLoop loop(message_loop_type); 603 MessageLoop loop(message_loop_type);
593 604
594 int depth = 100; 605 int depth = 100;
595 MessageLoop::current()->PostTask(FROM_HERE, new NestingTest(&depth)); 606 MessageLoop::current()->PostClosure(FROM_HERE,
607 base::Bind(&NestingFunc, &depth));
596 MessageLoop::current()->Run(); 608 MessageLoop::current()->Run();
597 EXPECT_EQ(depth, 0); 609 EXPECT_EQ(depth, 0);
598 } 610 }
599 611
600 const wchar_t* const kMessageBoxTitle = L"MessageLoop Unit Test"; 612 const wchar_t* const kMessageBoxTitle = L"MessageLoop Unit Test";
601 613
602 enum TaskType { 614 enum TaskType {
603 MESSAGEBOX, 615 MESSAGEBOX,
604 ENDDIALOG, 616 ENDDIALOG,
605 RECURSIVE, 617 RECURSIVE,
(...skipping 14 matching lines...) Expand all
620 632
621 TaskType type; 633 TaskType type;
622 int cookie; 634 int cookie;
623 bool start; 635 bool start;
624 636
625 bool operator == (const TaskItem& other) const { 637 bool operator == (const TaskItem& other) const {
626 return type == other.type && cookie == other.cookie && start == other.start; 638 return type == other.type && cookie == other.cookie && start == other.start;
627 } 639 }
628 }; 640 };
629 641
630 typedef std::vector<TaskItem> TaskList;
631
632 std::ostream& operator <<(std::ostream& os, TaskType type) { 642 std::ostream& operator <<(std::ostream& os, TaskType type) {
633 switch (type) { 643 switch (type) {
634 case MESSAGEBOX: os << "MESSAGEBOX"; break; 644 case MESSAGEBOX: os << "MESSAGEBOX"; break;
635 case ENDDIALOG: os << "ENDDIALOG"; break; 645 case ENDDIALOG: os << "ENDDIALOG"; break;
636 case RECURSIVE: os << "RECURSIVE"; break; 646 case RECURSIVE: os << "RECURSIVE"; break;
637 case TIMEDMESSAGELOOP: os << "TIMEDMESSAGELOOP"; break; 647 case TIMEDMESSAGELOOP: os << "TIMEDMESSAGELOOP"; break;
638 case QUITMESSAGELOOP: os << "QUITMESSAGELOOP"; break; 648 case QUITMESSAGELOOP: os << "QUITMESSAGELOOP"; break;
639 case ORDERERD: os << "ORDERERD"; break; 649 case ORDERERD: os << "ORDERERD"; break;
640 case PUMPS: os << "PUMPS"; break; 650 case PUMPS: os << "PUMPS"; break;
641 case SLEEP: os << "SLEEP"; break; 651 case SLEEP: os << "SLEEP"; break;
642 default: 652 default:
643 NOTREACHED(); 653 NOTREACHED();
644 os << "Unknown TaskType"; 654 os << "Unknown TaskType";
645 break; 655 break;
646 } 656 }
647 return os; 657 return os;
648 } 658 }
649 659
650 std::ostream& operator <<(std::ostream& os, const TaskItem& item) { 660 std::ostream& operator <<(std::ostream& os, const TaskItem& item) {
651 if (item.start) 661 if (item.start)
652 return os << item.type << " " << item.cookie << " starts"; 662 return os << item.type << " " << item.cookie << " starts";
653 else 663 else
654 return os << item.type << " " << item.cookie << " ends"; 664 return os << item.type << " " << item.cookie << " ends";
655 } 665 }
656 666
657 // Saves the order the tasks ran. 667 class TaskList {
658 class OrderedTasks : public Task {
659 public: 668 public:
660 OrderedTasks(TaskList* order, int cookie) 669 void RecordStart(TaskType type, int cookie) {
661 : order_(order), 670 TaskItem item(type, cookie, true);
662 type_(ORDERERD), 671 DVLOG(1) << item;
663 cookie_(cookie) { 672 task_list_.push_back(item);
664 }
665 OrderedTasks(TaskList* order, TaskType type, int cookie)
666 : order_(order),
667 type_(type),
668 cookie_(cookie) {
669 } 673 }
670 674
671 void RunStart() { 675 void RecordEnd(TaskType type, int cookie) {
672 TaskItem item(type_, cookie_, true); 676 TaskItem item(type, cookie, false);
673 DVLOG(1) << item; 677 DVLOG(1) << item;
674 order_->push_back(item); 678 task_list_.push_back(item);
675 }
676 void RunEnd() {
677 TaskItem item(type_, cookie_, false);
678 DVLOG(1) << item;
679 order_->push_back(item);
680 } 679 }
681 680
682 virtual void Run() { 681 size_t Size() {
683 RunStart(); 682 return task_list_.size();
684 RunEnd();
685 } 683 }
686 684
687 protected: 685 TaskItem Get(int n) {
688 TaskList* order() const { 686 return task_list_[n];
689 return order_;
690 }
691
692 int cookie() const {
693 return cookie_;
694 } 687 }
695 688
696 private: 689 private:
697 TaskList* order_; 690 std::vector<TaskItem> task_list_;
698 TaskType type_;
699 int cookie_;
700 }; 691 };
701 692
693 // Saves the order the tasks ran.
694 void OrderedFunc(TaskList* order, int cookie) {
695 order->RecordStart(ORDERERD, cookie);
696 order->RecordEnd(ORDERERD, cookie);
697 }
698
702 #if defined(OS_WIN) 699 #if defined(OS_WIN)
703 700
704 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes, 701 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes,
705 // common controls (like OpenFile) and StartDoc printing function can cause 702 // common controls (like OpenFile) and StartDoc printing function can cause
706 // implicit message loops. 703 // implicit message loops.
707 class MessageBoxTask : public OrderedTasks { 704 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) {
708 public: 705 order->RecordStart(MESSAGEBOX, cookie);
709 MessageBoxTask(TaskList* order, int cookie, bool is_reentrant) 706 if (is_reentrant)
710 : OrderedTasks(order, MESSAGEBOX, cookie), 707 MessageLoop::current()->SetNestableTasksAllowed(true);
711 is_reentrant_(is_reentrant) { 708 MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK);
712 } 709 order->RecordEnd(MESSAGEBOX, cookie);
713 710 }
714 virtual void Run() {
715 RunStart();
716 if (is_reentrant_)
717 MessageLoop::current()->SetNestableTasksAllowed(true);
718 MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK);
719 RunEnd();
720 }
721
722 private:
723 bool is_reentrant_;
724 };
725 711
726 // Will end the MessageBox. 712 // Will end the MessageBox.
727 class EndDialogTask : public OrderedTasks { 713 void EndDialogFunc(TaskList* order, int cookie) {
728 public: 714 order->RecordStart(ENDDIALOG, cookie);
729 EndDialogTask(TaskList* order, int cookie) 715 HWND window = GetActiveWindow();
730 : OrderedTasks(order, ENDDIALOG, cookie) { 716 if (window != NULL) {
717 EXPECT_NE(EndDialog(window, IDCONTINUE), 0);
718 // Cheap way to signal that the window wasn't found if RunEnd() isn't
719 // called.
720 order->RecordEnd(ENDDIALOG, cookie);
731 } 721 }
732 722 }
733 virtual void Run() {
734 RunStart();
735 HWND window = GetActiveWindow();
736 if (window != NULL) {
737 EXPECT_NE(EndDialog(window, IDCONTINUE), 0);
738 // Cheap way to signal that the window wasn't found if RunEnd() isn't
739 // called.
740 RunEnd();
741 }
742 }
743 };
744 723
745 #endif // defined(OS_WIN) 724 #endif // defined(OS_WIN)
746 725
747 class RecursiveTask : public OrderedTasks { 726 void RecursiveFunc(TaskList* order, int cookie, int depth,
748 public: 727 bool is_reentrant) {
749 RecursiveTask(int depth, TaskList* order, int cookie, bool is_reentrant) 728 order->RecordStart(RECURSIVE, cookie);
750 : OrderedTasks(order, RECURSIVE, cookie), 729 if (depth > 0) {
751 depth_(depth), 730 if (is_reentrant)
752 is_reentrant_(is_reentrant) { 731 MessageLoop::current()->SetNestableTasksAllowed(true);
732 MessageLoop::current()->PostClosure(
733 FROM_HERE,
734 base::Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant));
753 } 735 }
736 order->RecordEnd(RECURSIVE, cookie);
737 }
754 738
755 virtual void Run() { 739 void RecursiveSlowFunc(TaskList* order, int cookie, int depth,
756 RunStart(); 740 bool is_reentrant) {
757 if (depth_ > 0) { 741 RecursiveFunc(order, cookie, depth, is_reentrant);
758 if (is_reentrant_) 742 PlatformThread::Sleep(10); // milliseconds
759 MessageLoop::current()->SetNestableTasksAllowed(true); 743 }
760 MessageLoop::current()->PostTask(FROM_HERE,
761 new RecursiveTask(depth_ - 1, order(), cookie(), is_reentrant_));
762 }
763 RunEnd();
764 }
765 744
766 private: 745 void QuitFunc(TaskList* order, int cookie) {
767 int depth_; 746 order->RecordStart(QUITMESSAGELOOP, cookie);
768 bool is_reentrant_; 747 MessageLoop::current()->Quit();
769 }; 748 order->RecordEnd(QUITMESSAGELOOP, cookie);
749 }
770 750
771 class RecursiveSlowTask : public RecursiveTask { 751 void SleepFunc(TaskList* order, int cookie, int ms) {
772 public: 752 order->RecordStart(SLEEP, cookie);
773 RecursiveSlowTask(int depth, TaskList* order, int cookie, bool is_reentrant) 753 PlatformThread::Sleep(ms);
774 : RecursiveTask(depth, order, cookie, is_reentrant) { 754 order->RecordEnd(SLEEP, cookie);
775 } 755 }
776
777 virtual void Run() {
778 RecursiveTask::Run();
779 PlatformThread::Sleep(10); // milliseconds
780 }
781 };
782
783 class QuitTask : public OrderedTasks {
784 public:
785 QuitTask(TaskList* order, int cookie)
786 : OrderedTasks(order, QUITMESSAGELOOP, cookie) {
787 }
788
789 virtual void Run() {
790 RunStart();
791 MessageLoop::current()->Quit();
792 RunEnd();
793 }
794 };
795
796 class SleepTask : public OrderedTasks {
797 public:
798 SleepTask(TaskList* order, int cookie, int ms)
799 : OrderedTasks(order, SLEEP, cookie), ms_(ms) {
800 }
801
802 virtual void Run() {
803 RunStart();
804 PlatformThread::Sleep(ms_);
805 RunEnd();
806 }
807
808 private:
809 int ms_;
810 };
811 756
812 #if defined(OS_WIN) 757 #if defined(OS_WIN)
758 void RecursiveFuncWin(MessageLoop* target,
759 HANDLE event,
760 bool expect_window,
761 TaskList* order,
762 bool is_reentrant) {
763 target->PostClosure(FROM_HERE,
764 base::Bind(&RecursiveFunc, order, 1, 2, is_reentrant));
765 target->PostClosure(FROM_HERE,
766 base::Bind(&MessageBoxFunc, order, 2, is_reentrant));
767 target->PostClosure(FROM_HERE,
768 base::Bind(&RecursiveFunc, order, 3, 2, is_reentrant));
769 // The trick here is that for recursive task processing, this task will be
770 // ran _inside_ the MessageBox message loop, dismissing the MessageBox
771 // without a chance.
772 // For non-recursive task processing, this will be executed _after_ the
773 // MessageBox will have been dismissed by the code below, where
774 // expect_window_ is true.
775 target->PostClosure(FROM_HERE,
776 base::Bind(&EndDialogFunc, order, 4));
777 target->PostClosure(FROM_HERE,
778 base::Bind(&QuitFunc, order, 5));
813 779
814 class Recursive2Tasks : public Task { 780 // Enforce that every tasks are sent before starting to run the main thread
815 public: 781 // message loop.
816 Recursive2Tasks(MessageLoop* target, 782 ASSERT_TRUE(SetEvent(event));
817 HANDLE event,
818 bool expect_window,
819 TaskList* order,
820 bool is_reentrant)
821 : target_(target),
822 event_(event),
823 expect_window_(expect_window),
824 order_(order),
825 is_reentrant_(is_reentrant) {
826 }
827 783
828 virtual void Run() { 784 // Poll for the MessageBox. Don't do this at home! At the speed we do it,
829 target_->PostTask(FROM_HERE, 785 // you will never realize one MessageBox was shown.
830 new RecursiveTask(2, order_, 1, is_reentrant_)); 786 for (; expect_window;) {
831 target_->PostTask(FROM_HERE, 787 HWND window = FindWindow(L"#32770", kMessageBoxTitle);
832 new MessageBoxTask(order_, 2, is_reentrant_)); 788 if (window) {
833 target_->PostTask(FROM_HERE, 789 // Dismiss it.
834 new RecursiveTask(2, order_, 3, is_reentrant_)); 790 for (;;) {
835 // The trick here is that for recursive task processing, this task will be 791 HWND button = FindWindowEx(window, NULL, L"Button", NULL);
836 // ran _inside_ the MessageBox message loop, dismissing the MessageBox 792 if (button != NULL) {
837 // without a chance. 793 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0));
838 // For non-recursive task processing, this will be executed _after_ the 794 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0));
839 // MessageBox will have been dismissed by the code below, where 795 break;
840 // expect_window_ is true.
841 target_->PostTask(FROM_HERE, new EndDialogTask(order_, 4));
842 target_->PostTask(FROM_HERE, new QuitTask(order_, 5));
843
844 // Enforce that every tasks are sent before starting to run the main thread
845 // message loop.
846 ASSERT_TRUE(SetEvent(event_));
847
848 // Poll for the MessageBox. Don't do this at home! At the speed we do it,
849 // you will never realize one MessageBox was shown.
850 for (; expect_window_;) {
851 HWND window = FindWindow(L"#32770", kMessageBoxTitle);
852 if (window) {
853 // Dismiss it.
854 for (;;) {
855 HWND button = FindWindowEx(window, NULL, L"Button", NULL);
856 if (button != NULL) {
857 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0));
858 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0));
859 break;
860 }
861 } 796 }
862 break;
863 } 797 }
798 break;
864 } 799 }
865 } 800 }
866 801 }
867 private:
868 MessageLoop* target_;
869 HANDLE event_;
870 TaskList* order_;
871 bool expect_window_;
872 bool is_reentrant_;
873 };
874 802
875 #endif // defined(OS_WIN) 803 #endif // defined(OS_WIN)
876 804
877 void RunTest_RecursiveDenial1(MessageLoop::Type message_loop_type) { 805 void RunTest_RecursiveDenial1(MessageLoop::Type message_loop_type) {
878 MessageLoop loop(message_loop_type); 806 MessageLoop loop(message_loop_type);
879 807
880 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); 808 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed());
881 TaskList order; 809 TaskList order;
882 MessageLoop::current()->PostTask(FROM_HERE, 810 MessageLoop::current()->PostClosure(
883 new RecursiveTask(2, &order, 1, false)); 811 FROM_HERE,
884 MessageLoop::current()->PostTask(FROM_HERE, 812 base::Bind(&RecursiveFunc, &order, 1, 2, false));
885 new RecursiveTask(2, &order, 2, false)); 813 MessageLoop::current()->PostClosure(
886 MessageLoop::current()->PostTask(FROM_HERE, new QuitTask(&order, 3)); 814 FROM_HERE,
815 base::Bind(&RecursiveFunc, &order, 2, 2, false));
816 MessageLoop::current()->PostClosure(
817 FROM_HERE,
818 base::Bind(&QuitFunc, &order, 3));
887 819
888 MessageLoop::current()->Run(); 820 MessageLoop::current()->Run();
889 821
890 // FIFO order. 822 // FIFO order.
891 ASSERT_EQ(14U, order.size()); 823 ASSERT_EQ(14U, order.Size());
892 EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true)); 824 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
893 EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false)); 825 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
894 EXPECT_EQ(order[ 2], TaskItem(RECURSIVE, 2, true)); 826 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
895 EXPECT_EQ(order[ 3], TaskItem(RECURSIVE, 2, false)); 827 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
896 EXPECT_EQ(order[ 4], TaskItem(QUITMESSAGELOOP, 3, true)); 828 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
897 EXPECT_EQ(order[ 5], TaskItem(QUITMESSAGELOOP, 3, false)); 829 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
898 EXPECT_EQ(order[ 6], TaskItem(RECURSIVE, 1, true)); 830 EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true));
899 EXPECT_EQ(order[ 7], TaskItem(RECURSIVE, 1, false)); 831 EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false));
900 EXPECT_EQ(order[ 8], TaskItem(RECURSIVE, 2, true)); 832 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
901 EXPECT_EQ(order[ 9], TaskItem(RECURSIVE, 2, false)); 833 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
902 EXPECT_EQ(order[10], TaskItem(RECURSIVE, 1, true)); 834 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
903 EXPECT_EQ(order[11], TaskItem(RECURSIVE, 1, false)); 835 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
904 EXPECT_EQ(order[12], TaskItem(RECURSIVE, 2, true)); 836 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true));
905 EXPECT_EQ(order[13], TaskItem(RECURSIVE, 2, false)); 837 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false));
906 } 838 }
907 839
908 void RunTest_RecursiveDenial3(MessageLoop::Type message_loop_type) { 840 void RunTest_RecursiveDenial3(MessageLoop::Type message_loop_type) {
909 MessageLoop loop(message_loop_type); 841 MessageLoop loop(message_loop_type);
910 842
911 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); 843 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed());
912 TaskList order; 844 TaskList order;
913 MessageLoop::current()->PostTask(FROM_HERE, 845 MessageLoop::current()->PostClosure(
914 new RecursiveSlowTask(2, &order, 1, false)); 846 FROM_HERE, base::Bind(&RecursiveSlowFunc, &order, 1, 2, false));
915 MessageLoop::current()->PostTask(FROM_HERE, 847 MessageLoop::current()->PostClosure(
916 new RecursiveSlowTask(2, &order, 2, false)); 848 FROM_HERE, base::Bind(&RecursiveSlowFunc, &order, 2, 2, false));
917 MessageLoop::current()->PostDelayedTask(FROM_HERE, 849 MessageLoop::current()->PostDelayedClosure(
918 new OrderedTasks(&order, 3), 5); 850 FROM_HERE, base::Bind(&OrderedFunc, &order, 3), 5);
919 MessageLoop::current()->PostDelayedTask(FROM_HERE, 851 MessageLoop::current()->PostDelayedClosure(
920 new QuitTask(&order, 4), 5); 852 FROM_HERE, base::Bind(&QuitFunc, &order, 4), 5);
921 853
922 MessageLoop::current()->Run(); 854 MessageLoop::current()->Run();
923 855
924 // FIFO order. 856 // FIFO order.
925 ASSERT_EQ(16U, order.size()); 857 ASSERT_EQ(16U, order.Size());
926 EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true)); 858 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
927 EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false)); 859 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
928 EXPECT_EQ(order[ 2], TaskItem(RECURSIVE, 2, true)); 860 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
929 EXPECT_EQ(order[ 3], TaskItem(RECURSIVE, 2, false)); 861 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
930 EXPECT_EQ(order[ 4], TaskItem(RECURSIVE, 1, true)); 862 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 1, true));
931 EXPECT_EQ(order[ 5], TaskItem(RECURSIVE, 1, false)); 863 EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 1, false));
932 EXPECT_EQ(order[ 6], TaskItem(ORDERERD, 3, true)); 864 EXPECT_EQ(order.Get(6), TaskItem(ORDERERD, 3, true));
933 EXPECT_EQ(order[ 7], TaskItem(ORDERERD, 3, false)); 865 EXPECT_EQ(order.Get(7), TaskItem(ORDERERD, 3, false));
934 EXPECT_EQ(order[ 8], TaskItem(RECURSIVE, 2, true)); 866 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
935 EXPECT_EQ(order[ 9], TaskItem(RECURSIVE, 2, false)); 867 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
936 EXPECT_EQ(order[10], TaskItem(QUITMESSAGELOOP, 4, true)); 868 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 4, true));
937 EXPECT_EQ(order[11], TaskItem(QUITMESSAGELOOP, 4, false)); 869 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 4, false));
938 EXPECT_EQ(order[12], TaskItem(RECURSIVE, 1, true)); 870 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 1, true));
939 EXPECT_EQ(order[13], TaskItem(RECURSIVE, 1, false)); 871 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, false));
940 EXPECT_EQ(order[14], TaskItem(RECURSIVE, 2, true)); 872 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 2, true));
941 EXPECT_EQ(order[15], TaskItem(RECURSIVE, 2, false)); 873 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 2, false));
942 } 874 }
943 875
944 void RunTest_RecursiveSupport1(MessageLoop::Type message_loop_type) { 876 void RunTest_RecursiveSupport1(MessageLoop::Type message_loop_type) {
945 MessageLoop loop(message_loop_type); 877 MessageLoop loop(message_loop_type);
946 878
947 TaskList order; 879 TaskList order;
948 MessageLoop::current()->PostTask(FROM_HERE, 880 MessageLoop::current()->PostClosure(
949 new RecursiveTask(2, &order, 1, true)); 881 FROM_HERE,
950 MessageLoop::current()->PostTask(FROM_HERE, 882 base::Bind(&RecursiveFunc, &order, 1, 2, true));
951 new RecursiveTask(2, &order, 2, true)); 883 MessageLoop::current()->PostClosure(
952 MessageLoop::current()->PostTask(FROM_HERE, 884 FROM_HERE,
953 new QuitTask(&order, 3)); 885 base::Bind(&RecursiveFunc, &order, 2, 2, true));
886 MessageLoop::current()->PostClosure(
887 FROM_HERE,
888 base::Bind(&QuitFunc, &order, 3));
954 889
955 MessageLoop::current()->Run(); 890 MessageLoop::current()->Run();
956 891
957 // FIFO order. 892 // FIFO order.
958 ASSERT_EQ(14U, order.size()); 893 ASSERT_EQ(14U, order.Size());
959 EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true)); 894 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
960 EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false)); 895 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
961 EXPECT_EQ(order[ 2], TaskItem(RECURSIVE, 2, true)); 896 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
962 EXPECT_EQ(order[ 3], TaskItem(RECURSIVE, 2, false)); 897 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
963 EXPECT_EQ(order[ 4], TaskItem(QUITMESSAGELOOP, 3, true)); 898 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
964 EXPECT_EQ(order[ 5], TaskItem(QUITMESSAGELOOP, 3, false)); 899 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
965 EXPECT_EQ(order[ 6], TaskItem(RECURSIVE, 1, true)); 900 EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true));
966 EXPECT_EQ(order[ 7], TaskItem(RECURSIVE, 1, false)); 901 EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false));
967 EXPECT_EQ(order[ 8], TaskItem(RECURSIVE, 2, true)); 902 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
968 EXPECT_EQ(order[ 9], TaskItem(RECURSIVE, 2, false)); 903 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
969 EXPECT_EQ(order[10], TaskItem(RECURSIVE, 1, true)); 904 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
970 EXPECT_EQ(order[11], TaskItem(RECURSIVE, 1, false)); 905 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
971 EXPECT_EQ(order[12], TaskItem(RECURSIVE, 2, true)); 906 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true));
972 EXPECT_EQ(order[13], TaskItem(RECURSIVE, 2, false)); 907 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false));
973 } 908 }
974 909
975 #if defined(OS_WIN) 910 #if defined(OS_WIN)
976 // TODO(darin): These tests need to be ported since they test critical 911 // TODO(darin): These tests need to be ported since they test critical
977 // message loop functionality. 912 // message loop functionality.
978 913
979 // A side effect of this test is the generation a beep. Sorry. 914 // A side effect of this test is the generation a beep. Sorry.
980 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { 915 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) {
981 MessageLoop loop(message_loop_type); 916 MessageLoop loop(message_loop_type);
982 917
983 Thread worker("RecursiveDenial2_worker"); 918 Thread worker("RecursiveDenial2_worker");
984 Thread::Options options; 919 Thread::Options options;
985 options.message_loop_type = message_loop_type; 920 options.message_loop_type = message_loop_type;
986 ASSERT_EQ(true, worker.StartWithOptions(options)); 921 ASSERT_EQ(true, worker.StartWithOptions(options));
987 TaskList order; 922 TaskList order;
988 base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); 923 base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
989 worker.message_loop()->PostTask(FROM_HERE, 924 worker.message_loop()->PostClosure(FROM_HERE,
990 new Recursive2Tasks(MessageLoop::current(), 925 base::Bind(&RecursiveFuncWin,
991 event, 926 MessageLoop::current(),
992 true, 927 event.Get(),
993 &order, 928 true,
994 false)); 929 &order,
930 false));
995 // Let the other thread execute. 931 // Let the other thread execute.
996 WaitForSingleObject(event, INFINITE); 932 WaitForSingleObject(event, INFINITE);
997 MessageLoop::current()->Run(); 933 MessageLoop::current()->Run();
998 934
999 ASSERT_EQ(order.size(), 17); 935 ASSERT_EQ(order.Size(), 17);
1000 EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true)); 936 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
1001 EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false)); 937 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
1002 EXPECT_EQ(order[ 2], TaskItem(MESSAGEBOX, 2, true)); 938 EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true));
1003 EXPECT_EQ(order[ 3], TaskItem(MESSAGEBOX, 2, false)); 939 EXPECT_EQ(order.Get(3), TaskItem(MESSAGEBOX, 2, false));
1004 EXPECT_EQ(order[ 4], TaskItem(RECURSIVE, 3, true)); 940 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, true));
1005 EXPECT_EQ(order[ 5], TaskItem(RECURSIVE, 3, false)); 941 EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 3, false));
1006 // When EndDialogTask is processed, the window is already dismissed, hence no 942 // When EndDialogFunc is processed, the window is already dismissed, hence no
1007 // "end" entry. 943 // "end" entry.
1008 EXPECT_EQ(order[ 6], TaskItem(ENDDIALOG, 4, true)); 944 EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, true));
1009 EXPECT_EQ(order[ 7], TaskItem(QUITMESSAGELOOP, 5, true)); 945 EXPECT_EQ(order.Get(7), TaskItem(QUITMESSAGELOOP, 5, true));
1010 EXPECT_EQ(order[ 8], TaskItem(QUITMESSAGELOOP, 5, false)); 946 EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, false));
1011 EXPECT_EQ(order[ 9], TaskItem(RECURSIVE, 1, true)); 947 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 1, true));
1012 EXPECT_EQ(order[10], TaskItem(RECURSIVE, 1, false)); 948 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, false));
1013 EXPECT_EQ(order[11], TaskItem(RECURSIVE, 3, true)); 949 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 3, true));
1014 EXPECT_EQ(order[12], TaskItem(RECURSIVE, 3, false)); 950 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, false));
1015 EXPECT_EQ(order[13], TaskItem(RECURSIVE, 1, true)); 951 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, true));
1016 EXPECT_EQ(order[14], TaskItem(RECURSIVE, 1, false)); 952 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, false));
1017 EXPECT_EQ(order[15], TaskItem(RECURSIVE, 3, true)); 953 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 3, true));
1018 EXPECT_EQ(order[16], TaskItem(RECURSIVE, 3, false)); 954 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, false));
1019 } 955 }
1020 956
1021 // A side effect of this test is the generation a beep. Sorry. This test also 957 // A side effect of this test is the generation a beep. Sorry. This test also
1022 // needs to process windows messages on the current thread. 958 // needs to process windows messages on the current thread.
1023 void RunTest_RecursiveSupport2(MessageLoop::Type message_loop_type) { 959 void RunTest_RecursiveSupport2(MessageLoop::Type message_loop_type) {
1024 MessageLoop loop(message_loop_type); 960 MessageLoop loop(message_loop_type);
1025 961
1026 Thread worker("RecursiveSupport2_worker"); 962 Thread worker("RecursiveSupport2_worker");
1027 Thread::Options options; 963 Thread::Options options;
1028 options.message_loop_type = message_loop_type; 964 options.message_loop_type = message_loop_type;
1029 ASSERT_EQ(true, worker.StartWithOptions(options)); 965 ASSERT_EQ(true, worker.StartWithOptions(options));
1030 TaskList order; 966 TaskList order;
1031 base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); 967 base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
1032 worker.message_loop()->PostTask(FROM_HERE, 968 worker.message_loop()->PostClosure(FROM_HERE,
1033 new Recursive2Tasks(MessageLoop::current(), 969 base::Bind(&RecursiveFuncWin,
1034 event, 970 MessageLoop::current(),
1035 false, 971 event.Get(),
1036 &order, 972 false,
1037 true)); 973 &order,
974 true));
1038 // Let the other thread execute. 975 // Let the other thread execute.
1039 WaitForSingleObject(event, INFINITE); 976 WaitForSingleObject(event, INFINITE);
1040 MessageLoop::current()->Run(); 977 MessageLoop::current()->Run();
1041 978
1042 ASSERT_EQ(order.size(), 18); 979 ASSERT_EQ(order.Size(), 18);
1043 EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true)); 980 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
1044 EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false)); 981 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
1045 EXPECT_EQ(order[ 2], TaskItem(MESSAGEBOX, 2, true)); 982 EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true));
1046 // Note that this executes in the MessageBox modal loop. 983 // Note that this executes in the MessageBox modal loop.
1047 EXPECT_EQ(order[ 3], TaskItem(RECURSIVE, 3, true)); 984 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 3, true));
1048 EXPECT_EQ(order[ 4], TaskItem(RECURSIVE, 3, false)); 985 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, false));
1049 EXPECT_EQ(order[ 5], TaskItem(ENDDIALOG, 4, true)); 986 EXPECT_EQ(order.Get(5), TaskItem(ENDDIALOG, 4, true));
1050 EXPECT_EQ(order[ 6], TaskItem(ENDDIALOG, 4, false)); 987 EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, false));
1051 EXPECT_EQ(order[ 7], TaskItem(MESSAGEBOX, 2, false)); 988 EXPECT_EQ(order.Get(7), TaskItem(MESSAGEBOX, 2, false));
1052 /* The order can subtly change here. The reason is that when RecursiveTask(1) 989 /* The order can subtly change here. The reason is that when RecursiveFunc(1)
1053 is called in the main thread, if it is faster than getting to the 990 is called in the main thread, if it is faster than getting to the
1054 PostTask(FROM_HERE, QuitTask) execution, the order of task execution can 991 PostClosure(FROM_HERE, base::Bind(&QuitFunc) execution, the order of task
1055 change. We don't care anyway that the order isn't correct. 992 execution can change. We don't care anyway that the order isn't correct.
1056 EXPECT_EQ(order[ 8], TaskItem(QUITMESSAGELOOP, 5, true)); 993 EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, true));
1057 EXPECT_EQ(order[ 9], TaskItem(QUITMESSAGELOOP, 5, false)); 994 EXPECT_EQ(order.Get(9), TaskItem(QUITMESSAGELOOP, 5, false));
1058 EXPECT_EQ(order[10], TaskItem(RECURSIVE, 1, true)); 995 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
1059 EXPECT_EQ(order[11], TaskItem(RECURSIVE, 1, false)); 996 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
1060 */ 997 */
1061 EXPECT_EQ(order[12], TaskItem(RECURSIVE, 3, true)); 998 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true));
1062 EXPECT_EQ(order[13], TaskItem(RECURSIVE, 3, false)); 999 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false));
1063 EXPECT_EQ(order[14], TaskItem(RECURSIVE, 1, true)); 1000 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true));
1064 EXPECT_EQ(order[15], TaskItem(RECURSIVE, 1, false)); 1001 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false));
1065 EXPECT_EQ(order[16], TaskItem(RECURSIVE, 3, true)); 1002 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true));
1066 EXPECT_EQ(order[17], TaskItem(RECURSIVE, 3, false)); 1003 EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false));
1067 } 1004 }
1068 1005
1069 #endif // defined(OS_WIN) 1006 #endif // defined(OS_WIN)
1070 1007
1071 class TaskThatPumps : public OrderedTasks { 1008 void FuncThatPumps(TaskList* order, int cookie) {
1072 public: 1009 order->RecordStart(PUMPS, cookie);
1073 TaskThatPumps(TaskList* order, int cookie) 1010 bool old_state = MessageLoop::current()->NestableTasksAllowed();
1074 : OrderedTasks(order, PUMPS, cookie) { 1011 MessageLoop::current()->SetNestableTasksAllowed(true);
1075 } 1012 MessageLoop::current()->RunAllPending();
1076 1013 MessageLoop::current()->SetNestableTasksAllowed(old_state);
1077 virtual void Run() { 1014 order->RecordEnd(PUMPS, cookie);
1078 RunStart(); 1015 }
1079 bool old_state = MessageLoop::current()->NestableTasksAllowed();
1080 MessageLoop::current()->SetNestableTasksAllowed(true);
1081 MessageLoop::current()->RunAllPending();
1082 MessageLoop::current()->SetNestableTasksAllowed(old_state);
1083 RunEnd();
1084 }
1085 };
1086 1016
1087 // Tests that non nestable tasks run in FIFO if there are no nested loops. 1017 // Tests that non nestable tasks run in FIFO if there are no nested loops.
1088 void RunTest_NonNestableWithNoNesting(MessageLoop::Type message_loop_type) { 1018 void RunTest_NonNestableWithNoNesting(
1019 MessageLoop::Type message_loop_type) {
1089 MessageLoop loop(message_loop_type); 1020 MessageLoop loop(message_loop_type);
1090 1021
1091 TaskList order; 1022 TaskList order;
1092 1023
1093 Task* task = new OrderedTasks(&order, 1); 1024 MessageLoop::current()->PostNonNestableClosure(
1094 MessageLoop::current()->PostNonNestableTask(FROM_HERE, task); 1025 FROM_HERE,
1095 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 2)); 1026 base::Bind(&OrderedFunc, &order, 1));
1096 MessageLoop::current()->PostTask(FROM_HERE, new QuitTask(&order, 3)); 1027 MessageLoop::current()->PostClosure(FROM_HERE,
1028 base::Bind(&OrderedFunc, &order, 2));
1029 MessageLoop::current()->PostClosure(FROM_HERE,
1030 base::Bind(&QuitFunc, &order, 3));
1097 MessageLoop::current()->Run(); 1031 MessageLoop::current()->Run();
1098 1032
1099 // FIFO order. 1033 // FIFO order.
1100 ASSERT_EQ(6U, order.size()); 1034 ASSERT_EQ(6U, order.Size());
1101 EXPECT_EQ(order[ 0], TaskItem(ORDERERD, 1, true)); 1035 EXPECT_EQ(order.Get(0), TaskItem(ORDERERD, 1, true));
1102 EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 1, false)); 1036 EXPECT_EQ(order.Get(1), TaskItem(ORDERERD, 1, false));
1103 EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 2, true)); 1037 EXPECT_EQ(order.Get(2), TaskItem(ORDERERD, 2, true));
1104 EXPECT_EQ(order[ 3], TaskItem(ORDERERD, 2, false)); 1038 EXPECT_EQ(order.Get(3), TaskItem(ORDERERD, 2, false));
1105 EXPECT_EQ(order[ 4], TaskItem(QUITMESSAGELOOP, 3, true)); 1039 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
1106 EXPECT_EQ(order[ 5], TaskItem(QUITMESSAGELOOP, 3, false)); 1040 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
1107 } 1041 }
1108 1042
1109 // Tests that non nestable tasks don't run when there's code in the call stack. 1043 // Tests that non nestable tasks don't run when there's code in the call stack.
1110 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type, 1044 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type,
1111 bool use_delayed) { 1045 bool use_delayed) {
1112 MessageLoop loop(message_loop_type); 1046 MessageLoop loop(message_loop_type);
1113 1047
1114 TaskList order; 1048 TaskList order;
1115 1049
1116 MessageLoop::current()->PostTask(FROM_HERE, 1050 MessageLoop::current()->PostClosure(
1117 new TaskThatPumps(&order, 1)); 1051 FROM_HERE,
1118 Task* task = new OrderedTasks(&order, 2); 1052 base::Bind(&FuncThatPumps, &order, 1));
1119 if (use_delayed) { 1053 if (use_delayed) {
1120 MessageLoop::current()->PostNonNestableDelayedTask(FROM_HERE, task, 1); 1054 MessageLoop::current()->PostNonNestableDelayedClosure(
1055 FROM_HERE,
1056 base::Bind(&OrderedFunc, &order, 2),
1057 1);
1121 } else { 1058 } else {
1122 MessageLoop::current()->PostNonNestableTask(FROM_HERE, task); 1059 MessageLoop::current()->PostNonNestableClosure(
1060 FROM_HERE,
1061 base::Bind(&OrderedFunc, &order, 2));
1123 } 1062 }
1124 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 3)); 1063 MessageLoop::current()->PostClosure(FROM_HERE,
1125 MessageLoop::current()->PostTask(FROM_HERE, new SleepTask(&order, 4, 50)); 1064 base::Bind(&OrderedFunc, &order, 3));
1126 MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 5)); 1065 MessageLoop::current()->PostClosure(FROM_HERE,
1127 Task* non_nestable_quit = new QuitTask(&order, 6); 1066 base::Bind(&SleepFunc, &order, 4, 50));
1067 MessageLoop::current()->PostClosure(FROM_HERE,
1068 base::Bind(&OrderedFunc, &order, 5));
1128 if (use_delayed) { 1069 if (use_delayed) {
1129 MessageLoop::current()->PostNonNestableDelayedTask(FROM_HERE, 1070 MessageLoop::current()->PostNonNestableDelayedClosure(
1130 non_nestable_quit, 1071 FROM_HERE,
1131 2); 1072 base::Bind(&QuitFunc, &order, 6),
1073 2);
1132 } else { 1074 } else {
1133 MessageLoop::current()->PostNonNestableTask(FROM_HERE, non_nestable_quit); 1075 MessageLoop::current()->PostNonNestableClosure(
1076 FROM_HERE,
1077 base::Bind(&QuitFunc, &order, 6));
1134 } 1078 }
1135 1079
1136 MessageLoop::current()->Run(); 1080 MessageLoop::current()->Run();
1137 1081
1138 // FIFO order. 1082 // FIFO order.
1139 ASSERT_EQ(12U, order.size()); 1083 ASSERT_EQ(12U, order.Size());
1140 EXPECT_EQ(order[ 0], TaskItem(PUMPS, 1, true)); 1084 EXPECT_EQ(order.Get(0), TaskItem(PUMPS, 1, true));
1141 EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 3, true)); 1085 EXPECT_EQ(order.Get(1), TaskItem(ORDERERD, 3, true));
1142 EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 3, false)); 1086 EXPECT_EQ(order.Get(2), TaskItem(ORDERERD, 3, false));
1143 EXPECT_EQ(order[ 3], TaskItem(SLEEP, 4, true)); 1087 EXPECT_EQ(order.Get(3), TaskItem(SLEEP, 4, true));
1144 EXPECT_EQ(order[ 4], TaskItem(SLEEP, 4, false)); 1088 EXPECT_EQ(order.Get(4), TaskItem(SLEEP, 4, false));
1145 EXPECT_EQ(order[ 5], TaskItem(ORDERERD, 5, true)); 1089 EXPECT_EQ(order.Get(5), TaskItem(ORDERERD, 5, true));
1146 EXPECT_EQ(order[ 6], TaskItem(ORDERERD, 5, false)); 1090 EXPECT_EQ(order.Get(6), TaskItem(ORDERERD, 5, false));
1147 EXPECT_EQ(order[ 7], TaskItem(PUMPS, 1, false)); 1091 EXPECT_EQ(order.Get(7), TaskItem(PUMPS, 1, false));
1148 EXPECT_EQ(order[ 8], TaskItem(ORDERERD, 2, true)); 1092 EXPECT_EQ(order.Get(8), TaskItem(ORDERERD, 2, true));
1149 EXPECT_EQ(order[ 9], TaskItem(ORDERERD, 2, false)); 1093 EXPECT_EQ(order.Get(9), TaskItem(ORDERERD, 2, false));
1150 EXPECT_EQ(order[10], TaskItem(QUITMESSAGELOOP, 6, true)); 1094 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 6, true));
1151 EXPECT_EQ(order[11], TaskItem(QUITMESSAGELOOP, 6, false)); 1095 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 6, false));
1152 } 1096 }
1153 1097
1154 #if defined(OS_WIN) 1098 #if defined(OS_WIN)
1155 1099
1156 class DispatcherImpl : public MessageLoopForUI::Dispatcher { 1100 class DispatcherImpl : public MessageLoopForUI::Dispatcher {
1157 public: 1101 public:
1158 DispatcherImpl() : dispatch_count_(0) {} 1102 DispatcherImpl() : dispatch_count_(0) {}
1159 1103
1160 virtual bool Dispatch(const MSG& msg) { 1104 virtual bool Dispatch(const MSG& msg) {
1161 ::TranslateMessage(&msg); 1105 ::TranslateMessage(&msg);
1162 ::DispatchMessage(&msg); 1106 ::DispatchMessage(&msg);
1163 // Do not count WM_TIMER since it is not what we post and it will cause 1107 // Do not count WM_TIMER since it is not what we post and it will cause
1164 // flakiness. 1108 // flakiness.
1165 if (msg.message != WM_TIMER) 1109 if (msg.message != WM_TIMER)
1166 ++dispatch_count_; 1110 ++dispatch_count_;
1167 // We treat WM_LBUTTONUP as the last message. 1111 // We treat WM_LBUTTONUP as the last message.
1168 return msg.message != WM_LBUTTONUP; 1112 return msg.message != WM_LBUTTONUP;
1169 } 1113 }
1170 1114
1171 int dispatch_count_; 1115 int dispatch_count_;
1172 }; 1116 };
1173 1117
1118 void MouseDownUp() {
1119 PostMessage(NULL, WM_LBUTTONDOWN, 0, 0);
1120 PostMessage(NULL, WM_LBUTTONUP, 'A', 0);
1121 }
1122
1174 void RunTest_Dispatcher(MessageLoop::Type message_loop_type) { 1123 void RunTest_Dispatcher(MessageLoop::Type message_loop_type) {
1175 MessageLoop loop(message_loop_type); 1124 MessageLoop loop(message_loop_type);
1176 1125
1177 class MyTask : public Task { 1126 MessageLoop::current()->PostDelayedClosure(FROM_HERE,
1178 public: 1127 base::Bind(&MouseDownUp), 100);
1179 virtual void Run() {
1180 PostMessage(NULL, WM_LBUTTONDOWN, 0, 0);
1181 PostMessage(NULL, WM_LBUTTONUP, 'A', 0);
1182 }
1183 };
1184 Task* task = new MyTask();
1185 MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 100);
1186 DispatcherImpl dispatcher; 1128 DispatcherImpl dispatcher;
1187 MessageLoopForUI::current()->Run(&dispatcher); 1129 MessageLoopForUI::current()->Run(&dispatcher);
1188 ASSERT_EQ(2, dispatcher.dispatch_count_); 1130 ASSERT_EQ(2, dispatcher.dispatch_count_);
1189 } 1131 }
1190 1132
1191 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) { 1133 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) {
1192 if (code == base::MessagePumpForUI::kMessageFilterCode) { 1134 if (code == base::MessagePumpForUI::kMessageFilterCode) {
1193 MSG* msg = reinterpret_cast<MSG*>(lparam); 1135 MSG* msg = reinterpret_cast<MSG*>(lparam);
1194 if (msg->message == WM_LBUTTONDOWN) 1136 if (msg->message == WM_LBUTTONDOWN)
1195 return TRUE; 1137 return TRUE;
1196 } 1138 }
1197 return FALSE; 1139 return FALSE;
1198 } 1140 }
1199 1141
1200 void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) { 1142 void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) {
1201 MessageLoop loop(message_loop_type); 1143 MessageLoop loop(message_loop_type);
1202 1144
1203 class MyTask : public Task { 1145 MessageLoop::current()->PostDelayedClosure(FROM_HERE,
1204 public: 1146 base::Bind(&MouseDownUp), 100);
1205 virtual void Run() {
1206 PostMessage(NULL, WM_LBUTTONDOWN, 0, 0);
1207 PostMessage(NULL, WM_LBUTTONUP, 'A', 0);
1208 }
1209 };
1210 Task* task = new MyTask();
1211 MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 100);
1212 HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER, 1147 HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER,
1213 MsgFilterProc, 1148 MsgFilterProc,
1214 NULL, 1149 NULL,
1215 GetCurrentThreadId()); 1150 GetCurrentThreadId());
1216 DispatcherImpl dispatcher; 1151 DispatcherImpl dispatcher;
1217 MessageLoopForUI::current()->Run(&dispatcher); 1152 MessageLoopForUI::current()->Run(&dispatcher);
1218 ASSERT_EQ(1, dispatcher.dispatch_count_); 1153 ASSERT_EQ(1, dispatcher.dispatch_count_);
1219 UnhookWindowsHookEx(msg_hook); 1154 UnhookWindowsHookEx(msg_hook);
1220 } 1155 }
1221 1156
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 DWORD bytes_transfered, DWORD error) { 1199 DWORD bytes_transfered, DWORD error) {
1265 ASSERT_TRUE(context == &context_); 1200 ASSERT_TRUE(context == &context_);
1266 ASSERT_TRUE(SetEvent(signal_)); 1201 ASSERT_TRUE(SetEvent(signal_));
1267 } 1202 }
1268 1203
1269 void TestIOHandler::WaitForIO() { 1204 void TestIOHandler::WaitForIO() {
1270 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this)); 1205 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this));
1271 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this)); 1206 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this));
1272 } 1207 }
1273 1208
1274 class IOHandlerTask : public Task {
1275 public:
1276 explicit IOHandlerTask(TestIOHandler* handler) : handler_(handler) {}
1277 virtual void Run() {
1278 handler_->Init();
1279 }
1280
1281 private:
1282 TestIOHandler* handler_;
1283 };
1284
1285 void RunTest_IOHandler() { 1209 void RunTest_IOHandler() {
1286 base::win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL)); 1210 base::win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL));
1287 ASSERT_TRUE(callback_called.IsValid()); 1211 ASSERT_TRUE(callback_called.IsValid());
1288 1212
1289 const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe"; 1213 const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe";
1290 base::win::ScopedHandle server( 1214 base::win::ScopedHandle server(
1291 CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); 1215 CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
1292 ASSERT_TRUE(server.IsValid()); 1216 ASSERT_TRUE(server.IsValid());
1293 1217
1294 Thread thread("IOHandler test"); 1218 Thread thread("IOHandler test");
1295 Thread::Options options; 1219 Thread::Options options;
1296 options.message_loop_type = MessageLoop::TYPE_IO; 1220 options.message_loop_type = MessageLoop::TYPE_IO;
1297 ASSERT_TRUE(thread.StartWithOptions(options)); 1221 ASSERT_TRUE(thread.StartWithOptions(options));
1298 1222
1299 MessageLoop* thread_loop = thread.message_loop(); 1223 MessageLoop* thread_loop = thread.message_loop();
1300 ASSERT_TRUE(NULL != thread_loop); 1224 ASSERT_TRUE(NULL != thread_loop);
1301 1225
1302 TestIOHandler handler(kPipeName, callback_called, false); 1226 TestIOHandler handler(kPipeName, callback_called, false);
1303 IOHandlerTask* task = new IOHandlerTask(&handler); 1227 thread_loop->PostClosure(FROM_HERE, base::Bind(&TestIOHandler::Init,
1304 thread_loop->PostTask(FROM_HERE, task); 1228 base::Unretained(&handler)));
1305 Sleep(100); // Make sure the thread runs and sleeps for lack of work. 1229 Sleep(100); // Make sure the thread runs and sleeps for lack of work.
1306 1230
1307 const char buffer[] = "Hello there!"; 1231 const char buffer[] = "Hello there!";
1308 DWORD written; 1232 DWORD written;
1309 EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL)); 1233 EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL));
1310 1234
1311 DWORD result = WaitForSingleObject(callback_called, 1000); 1235 DWORD result = WaitForSingleObject(callback_called, 1000);
1312 EXPECT_EQ(WAIT_OBJECT_0, result); 1236 EXPECT_EQ(WAIT_OBJECT_0, result);
1313 1237
1314 thread.Stop(); 1238 thread.Stop();
(...skipping 19 matching lines...) Expand all
1334 Thread thread("IOHandler test"); 1258 Thread thread("IOHandler test");
1335 Thread::Options options; 1259 Thread::Options options;
1336 options.message_loop_type = MessageLoop::TYPE_IO; 1260 options.message_loop_type = MessageLoop::TYPE_IO;
1337 ASSERT_TRUE(thread.StartWithOptions(options)); 1261 ASSERT_TRUE(thread.StartWithOptions(options));
1338 1262
1339 MessageLoop* thread_loop = thread.message_loop(); 1263 MessageLoop* thread_loop = thread.message_loop();
1340 ASSERT_TRUE(NULL != thread_loop); 1264 ASSERT_TRUE(NULL != thread_loop);
1341 1265
1342 TestIOHandler handler1(kPipeName1, callback1_called, false); 1266 TestIOHandler handler1(kPipeName1, callback1_called, false);
1343 TestIOHandler handler2(kPipeName2, callback2_called, true); 1267 TestIOHandler handler2(kPipeName2, callback2_called, true);
1344 IOHandlerTask* task1 = new IOHandlerTask(&handler1); 1268 thread_loop->PostClosure(FROM_HERE, base::Bind(&TestIOHandler::Init,
1345 IOHandlerTask* task2 = new IOHandlerTask(&handler2); 1269 base::Unretained(&handler1)));
1346 thread_loop->PostTask(FROM_HERE, task1); 1270 // TODO(ajwong): Do we really need such long Sleeps in ths function?
1347 Sleep(100); // Make sure the thread runs and sleeps for lack of work. 1271 Sleep(100); // Make sure the thread runs and sleeps for lack of work.
1348 thread_loop->PostTask(FROM_HERE, task2); 1272 thread_loop->PostClosure(FROM_HERE, base::Bind(&TestIOHandler::Init,
1273 base::Unretained(&handler2)));
1349 Sleep(100); 1274 Sleep(100);
1350 1275
1351 // At this time handler1 is waiting to be called, and the thread is waiting 1276 // At this time handler1 is waiting to be called, and the thread is waiting
1352 // on the Init method of handler2, filtering only handler2 callbacks. 1277 // on the Init method of handler2, filtering only handler2 callbacks.
1353 1278
1354 const char buffer[] = "Hello there!"; 1279 const char buffer[] = "Hello there!";
1355 DWORD written; 1280 DWORD written;
1356 EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL)); 1281 EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL));
1357 Sleep(200); 1282 Sleep(200);
1358 EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) << 1283 EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) <<
(...skipping 16 matching lines...) Expand all
1375 // Each test is run against each type of MessageLoop. That way we are sure 1300 // Each test is run against each type of MessageLoop. That way we are sure
1376 // that message loops work properly in all configurations. Of course, in some 1301 // that message loops work properly in all configurations. Of course, in some
1377 // cases, a unit test may only be for a particular type of loop. 1302 // cases, a unit test may only be for a particular type of loop.
1378 1303
1379 TEST(MessageLoopTest, PostTask) { 1304 TEST(MessageLoopTest, PostTask) {
1380 RunTest_PostTask(MessageLoop::TYPE_DEFAULT); 1305 RunTest_PostTask(MessageLoop::TYPE_DEFAULT);
1381 RunTest_PostTask(MessageLoop::TYPE_UI); 1306 RunTest_PostTask(MessageLoop::TYPE_UI);
1382 RunTest_PostTask(MessageLoop::TYPE_IO); 1307 RunTest_PostTask(MessageLoop::TYPE_IO);
1383 } 1308 }
1384 1309
1385 TEST(MessageLoopTest, PostTask_SEH) { 1310 TEST(MessageLoopTest, PostClosure) {
1386 RunTest_PostTask_SEH(MessageLoop::TYPE_DEFAULT); 1311 RunTest_PostClosure(MessageLoop::TYPE_DEFAULT);
1387 RunTest_PostTask_SEH(MessageLoop::TYPE_UI); 1312 RunTest_PostClosure(MessageLoop::TYPE_UI);
1388 RunTest_PostTask_SEH(MessageLoop::TYPE_IO); 1313 RunTest_PostClosure(MessageLoop::TYPE_IO);
1389 } 1314 }
1390 1315
1391 TEST(MessageLoopTest, PostDelayedTask_Basic) { 1316 TEST(MessageLoopTest, PostClosure_SEH) {
1392 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_DEFAULT); 1317 RunTest_PostClosure_SEH(MessageLoop::TYPE_DEFAULT);
1393 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_UI); 1318 RunTest_PostClosure_SEH(MessageLoop::TYPE_UI);
1394 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_IO); 1319 RunTest_PostClosure_SEH(MessageLoop::TYPE_IO);
1395 } 1320 }
1396 1321
1397 TEST(MessageLoopTest, PostDelayedTask_InDelayOrder) { 1322 TEST(MessageLoopTest, PostDelayedClosure_Basic) {
1398 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_DEFAULT); 1323 RunTest_PostDelayedClosure_Basic(MessageLoop::TYPE_DEFAULT);
1399 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_UI); 1324 RunTest_PostDelayedClosure_Basic(MessageLoop::TYPE_UI);
1400 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_IO); 1325 RunTest_PostDelayedClosure_Basic(MessageLoop::TYPE_IO);
1401 } 1326 }
1402 1327
1403 TEST(MessageLoopTest, PostDelayedTask_InPostOrder) { 1328 TEST(MessageLoopTest, PostDelayedClosure_InDelayOrder) {
1404 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_DEFAULT); 1329 RunTest_PostDelayedClosure_InDelayOrder(MessageLoop::TYPE_DEFAULT);
1405 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_UI); 1330 RunTest_PostDelayedClosure_InDelayOrder(MessageLoop::TYPE_UI);
1406 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_IO); 1331 RunTest_PostDelayedClosure_InDelayOrder(MessageLoop::TYPE_IO);
1407 } 1332 }
1408 1333
1409 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_2) { 1334 TEST(MessageLoopTest, PostDelayedClosure_InPostOrder) {
1410 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_DEFAULT); 1335 RunTest_PostDelayedClosure_InPostOrder(MessageLoop::TYPE_DEFAULT);
1411 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_UI); 1336 RunTest_PostDelayedClosure_InPostOrder(MessageLoop::TYPE_UI);
1412 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_IO); 1337 RunTest_PostDelayedClosure_InPostOrder(MessageLoop::TYPE_IO);
1413 } 1338 }
1414 1339
1415 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_3) { 1340 TEST(MessageLoopTest, PostDelayedClosure_InPostOrder_2) {
1416 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_DEFAULT); 1341 RunTest_PostDelayedClosure_InPostOrder_2(MessageLoop::TYPE_DEFAULT);
1417 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_UI); 1342 RunTest_PostDelayedClosure_InPostOrder_2(MessageLoop::TYPE_UI);
1418 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_IO); 1343 RunTest_PostDelayedClosure_InPostOrder_2(MessageLoop::TYPE_IO);
1419 } 1344 }
1420 1345
1421 TEST(MessageLoopTest, PostDelayedTask_SharedTimer) { 1346 TEST(MessageLoopTest, PostDelayedClosure_InPostOrder_3) {
1422 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_DEFAULT); 1347 RunTest_PostDelayedClosure_InPostOrder_3(MessageLoop::TYPE_DEFAULT);
1423 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_UI); 1348 RunTest_PostDelayedClosure_InPostOrder_3(MessageLoop::TYPE_UI);
1424 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_IO); 1349 RunTest_PostDelayedClosure_InPostOrder_3(MessageLoop::TYPE_IO);
1350 }
1351
1352 TEST(MessageLoopTest, PostDelayedClosure_SharedTimer) {
1353 RunTest_PostDelayedClosure_SharedTimer(MessageLoop::TYPE_DEFAULT);
1354 RunTest_PostDelayedClosure_SharedTimer(MessageLoop::TYPE_UI);
1355 RunTest_PostDelayedClosure_SharedTimer(MessageLoop::TYPE_IO);
1425 } 1356 }
1426 1357
1427 #if defined(OS_WIN) 1358 #if defined(OS_WIN)
1428 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) { 1359 TEST(MessageLoopTest, PostDelayedClosure_SharedTimer_SubPump) {
1429 RunTest_PostDelayedTask_SharedTimer_SubPump(); 1360 RunTest_PostDelayedClosure_SharedTimer_SubPump();
1430 } 1361 }
1431 #endif 1362 #endif
1432 1363
1433 // TODO(darin): MessageLoop does not support deleting all tasks in the 1364 // TODO(darin): MessageLoop does not support deleting all tasks in the
1434 // destructor. 1365 // destructor.
1435 // Fails, http://crbug.com/50272. 1366 // Fails, http://crbug.com/50272.
1436 TEST(MessageLoopTest, FAILS_EnsureTaskDeletion) { 1367 TEST(MessageLoopTest, FAILS_EnsureDeletion) {
1437 RunTest_EnsureTaskDeletion(MessageLoop::TYPE_DEFAULT); 1368 RunTest_EnsureDeletion(MessageLoop::TYPE_DEFAULT);
1438 RunTest_EnsureTaskDeletion(MessageLoop::TYPE_UI); 1369 RunTest_EnsureDeletion(MessageLoop::TYPE_UI);
1439 RunTest_EnsureTaskDeletion(MessageLoop::TYPE_IO); 1370 RunTest_EnsureDeletion(MessageLoop::TYPE_IO);
1440 } 1371 }
1441 1372
1442 // TODO(darin): MessageLoop does not support deleting all tasks in the 1373 // TODO(darin): MessageLoop does not support deleting all tasks in the
1443 // destructor. 1374 // destructor.
1444 // Fails, http://crbug.com/50272. 1375 // Fails, http://crbug.com/50272.
1445 TEST(MessageLoopTest, FAILS_EnsureTaskDeletion_Chain) { 1376 TEST(MessageLoopTest, FAILS_EnsureDeletion_Chain) {
1446 RunTest_EnsureTaskDeletion_Chain(MessageLoop::TYPE_DEFAULT); 1377 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_DEFAULT);
1447 RunTest_EnsureTaskDeletion_Chain(MessageLoop::TYPE_UI); 1378 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_UI);
1448 RunTest_EnsureTaskDeletion_Chain(MessageLoop::TYPE_IO); 1379 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_IO);
1449 } 1380 }
1450 1381
1451 #if defined(OS_WIN) 1382 #if defined(OS_WIN)
1452 TEST(MessageLoopTest, Crasher) { 1383 TEST(MessageLoopTest, Crasher) {
1453 RunTest_Crasher(MessageLoop::TYPE_DEFAULT); 1384 RunTest_Crasher(MessageLoop::TYPE_DEFAULT);
1454 RunTest_Crasher(MessageLoop::TYPE_UI); 1385 RunTest_Crasher(MessageLoop::TYPE_UI);
1455 RunTest_Crasher(MessageLoop::TYPE_IO); 1386 RunTest_Crasher(MessageLoop::TYPE_IO);
1456 } 1387 }
1457 1388
1458 TEST(MessageLoopTest, CrasherNasty) { 1389 TEST(MessageLoopTest, CrasherNasty) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, false); 1442 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, false);
1512 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, false); 1443 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, false);
1513 } 1444 }
1514 1445
1515 TEST(MessageLoopTest, NonNestableDelayedInNestedLoop) { 1446 TEST(MessageLoopTest, NonNestableDelayedInNestedLoop) {
1516 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, true); 1447 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, true);
1517 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, true); 1448 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, true);
1518 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, true); 1449 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, true);
1519 } 1450 }
1520 1451
1521 class DummyTask : public Task { 1452 void PostNClosuresThenQuit(int posts_remaining) {
1453 if (posts_remaining > 1) {
1454 MessageLoop::current()->PostClosure(
1455 FROM_HERE,
1456 base::Bind(&PostNClosuresThenQuit, posts_remaining - 1));
1457 } else {
1458 MessageLoop::current()->Quit();
1459 }
1460 }
1461
1462 class DummyClosureObserver : public MessageLoop::ClosureObserver {
1522 public: 1463 public:
1523 explicit DummyTask(int num_tasks) : num_tasks_(num_tasks) {} 1464 explicit DummyClosureObserver(int num_closures)
1465 : num_closures_started_(0),
1466 num_closures_processed_(0),
1467 num_closures_(num_closures) {}
1524 1468
1525 virtual void Run() { 1469 virtual ~DummyClosureObserver() {}
1526 if (num_tasks_ > 1) { 1470
1527 MessageLoop::current()->PostTask( 1471 virtual void WillProcessClosure(TimeTicks time_posted) OVERRIDE {
1528 FROM_HERE, 1472 num_closures_started_++;
1529 new DummyTask(num_tasks_ - 1)); 1473 EXPECT_TRUE(time_posted != TimeTicks());
1530 } else { 1474 EXPECT_LE(num_closures_started_, num_closures_);
1531 MessageLoop::current()->Quit(); 1475 EXPECT_EQ(num_closures_started_, num_closures_processed_ + 1);
1532 }
1533 } 1476 }
1534 1477
1478 virtual void DidProcessClosure(TimeTicks time_posted) OVERRIDE {
1479 num_closures_processed_++;
1480 EXPECT_TRUE(time_posted != TimeTicks());
1481 EXPECT_LE(num_closures_started_, num_closures_);
1482 EXPECT_EQ(num_closures_started_, num_closures_processed_);
1483 }
1484
1485 int num_closures_started() const { return num_closures_started_; }
1486 int num_closures_processed() const { return num_closures_processed_; }
1487
1535 private: 1488 private:
1536 const int num_tasks_; 1489 int num_closures_started_;
1490 int num_closures_processed_;
1491 const int num_closures_;
1492
1493 DISALLOW_COPY_AND_ASSIGN(DummyClosureObserver);
1537 }; 1494 };
1538 1495
1539 class DummyTaskObserver : public MessageLoop::TaskObserver { 1496 TEST(MessageLoopTest, ClosureObserver) {
1540 public: 1497 const int kNumPosts = 6;
1541 explicit DummyTaskObserver(int num_tasks) 1498 DummyClosureObserver observer(kNumPosts);
1542 : num_tasks_started_(0),
1543 num_tasks_processed_(0),
1544 num_tasks_(num_tasks) {}
1545
1546 virtual ~DummyTaskObserver() {}
1547
1548 virtual void WillProcessTask(const Task* task) {
1549 num_tasks_started_++;
1550 EXPECT_TRUE(task != NULL);
1551 EXPECT_LE(num_tasks_started_, num_tasks_);
1552 EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1);
1553 }
1554
1555 virtual void DidProcessTask(const Task* task) {
1556 num_tasks_processed_++;
1557 EXPECT_TRUE(task != NULL);
1558 EXPECT_LE(num_tasks_started_, num_tasks_);
1559 EXPECT_EQ(num_tasks_started_, num_tasks_processed_);
1560 }
1561
1562 int num_tasks_started() const { return num_tasks_started_; }
1563 int num_tasks_processed() const { return num_tasks_processed_; }
1564
1565 private:
1566 int num_tasks_started_;
1567 int num_tasks_processed_;
1568 const int num_tasks_;
1569
1570 DISALLOW_COPY_AND_ASSIGN(DummyTaskObserver);
1571 };
1572
1573 TEST(MessageLoopTest, TaskObserver) {
1574 const int kNumTasks = 6;
1575 DummyTaskObserver observer(kNumTasks);
1576 1499
1577 MessageLoop loop; 1500 MessageLoop loop;
1578 loop.AddTaskObserver(&observer); 1501 loop.AddClosureObserver(&observer);
1579 loop.PostTask(FROM_HERE, new DummyTask(kNumTasks)); 1502 loop.PostClosure(FROM_HERE, base::Bind(&PostNClosuresThenQuit, kNumPosts));
1580 loop.Run(); 1503 loop.Run();
1581 loop.RemoveTaskObserver(&observer); 1504 loop.RemoveClosureObserver(&observer);
1582 1505
1583 EXPECT_EQ(kNumTasks, observer.num_tasks_started()); 1506 EXPECT_EQ(kNumPosts, observer.num_closures_started());
1584 EXPECT_EQ(kNumTasks, observer.num_tasks_processed()); 1507 EXPECT_EQ(kNumPosts, observer.num_closures_processed());
1585 } 1508 }
1586 1509
1587 #if defined(OS_WIN) 1510 #if defined(OS_WIN)
1588 TEST(MessageLoopTest, Dispatcher) { 1511 TEST(MessageLoopTest, Dispatcher) {
1589 // This test requires a UI loop 1512 // This test requires a UI loop
1590 RunTest_Dispatcher(MessageLoop::TYPE_UI); 1513 RunTest_Dispatcher(MessageLoop::TYPE_UI);
1591 } 1514 }
1592 1515
1593 TEST(MessageLoopTest, DispatcherWithMessageHook) { 1516 TEST(MessageLoopTest, DispatcherWithMessageHook) {
1594 // This test requires a UI loop 1517 // This test requires a UI loop
(...skipping 10 matching lines...) Expand all
1605 1528
1606 TEST(MessageLoopTest, HighResolutionTimer) { 1529 TEST(MessageLoopTest, HighResolutionTimer) {
1607 MessageLoop loop; 1530 MessageLoop loop;
1608 1531
1609 const int kFastTimerMs = 5; 1532 const int kFastTimerMs = 5;
1610 const int kSlowTimerMs = 100; 1533 const int kSlowTimerMs = 100;
1611 1534
1612 EXPECT_FALSE(loop.high_resolution_timers_enabled()); 1535 EXPECT_FALSE(loop.high_resolution_timers_enabled());
1613 1536
1614 // Post a fast task to enable the high resolution timers. 1537 // Post a fast task to enable the high resolution timers.
1615 loop.PostDelayedTask(FROM_HERE, new DummyTask(1), kFastTimerMs); 1538 loop.PostDelayedClosure(FROM_HERE, base::Bind(&PostNClosuresThenQuit, 1),
1539 kFastTimerMs);
1616 loop.Run(); 1540 loop.Run();
1617 EXPECT_TRUE(loop.high_resolution_timers_enabled()); 1541 EXPECT_TRUE(loop.high_resolution_timers_enabled());
1618 1542
1619 // Post a slow task and verify high resolution timers 1543 // Post a slow task and verify high resolution timers
1620 // are still enabled. 1544 // are still enabled.
1621 loop.PostDelayedTask(FROM_HERE, new DummyTask(1), kSlowTimerMs); 1545 loop.PostDelayedClosure(FROM_HERE, base::Bind(&PostNClosuresThenQuit, 1),
1546 kSlowTimerMs);
1622 loop.Run(); 1547 loop.Run();
1623 EXPECT_TRUE(loop.high_resolution_timers_enabled()); 1548 EXPECT_TRUE(loop.high_resolution_timers_enabled());
1624 1549
1625 // Wait for a while so that high-resolution mode elapses. 1550 // Wait for a while so that high-resolution mode elapses.
1626 Sleep(MessageLoop::kHighResolutionTimerModeLeaseTimeMs); 1551 Sleep(MessageLoop::kHighResolutionTimerModeLeaseTimeMs);
1627 1552
1628 // Post a slow task to disable the high resolution timers. 1553 // Post a slow task to disable the high resolution timers.
1629 loop.PostDelayedTask(FROM_HERE, new DummyTask(1), kSlowTimerMs); 1554 loop.PostDelayedClosure(FROM_HERE, base::Bind(&PostNClosuresThenQuit, 1),
1555 kSlowTimerMs);
1630 loop.Run(); 1556 loop.Run();
1631 EXPECT_FALSE(loop.high_resolution_timers_enabled()); 1557 EXPECT_FALSE(loop.high_resolution_timers_enabled());
1632 } 1558 }
1633 1559
1634 #endif // defined(OS_WIN) 1560 #endif // defined(OS_WIN)
1635 1561
1636 #if defined(OS_POSIX) && !defined(OS_NACL) 1562 #if defined(OS_POSIX) && !defined(OS_NACL)
1637 1563
1638 namespace { 1564 namespace {
1639 1565
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 PLOG(ERROR) << "close"; 1625 PLOG(ERROR) << "close";
1700 if (HANDLE_EINTR(close(pipefds[1])) < 0) 1626 if (HANDLE_EINTR(close(pipefds[1])) < 0)
1701 PLOG(ERROR) << "close"; 1627 PLOG(ERROR) << "close";
1702 } 1628 }
1703 1629
1704 } // namespace 1630 } // namespace
1705 1631
1706 #endif // defined(OS_POSIX) && !defined(OS_NACL) 1632 #endif // defined(OS_POSIX) && !defined(OS_NACL)
1707 1633
1708 namespace { 1634 namespace {
1709 class RunAtDestructionTask : public Task { 1635 class DestructionObserverProbe :
1636 public base::RefCounted<DestructionObserverProbe> {
1710 public: 1637 public:
1711 RunAtDestructionTask(bool* task_destroyed, bool* destruction_observer_called) 1638 DestructionObserverProbe(bool* task_destroyed,
1639 bool* destruction_observer_called)
1712 : task_destroyed_(task_destroyed), 1640 : task_destroyed_(task_destroyed),
1713 destruction_observer_called_(destruction_observer_called) { 1641 destruction_observer_called_(destruction_observer_called) {
1714 } 1642 }
1715 ~RunAtDestructionTask() { 1643 virtual ~DestructionObserverProbe() {
1716 EXPECT_FALSE(*destruction_observer_called_); 1644 EXPECT_FALSE(*destruction_observer_called_);
1717 *task_destroyed_ = true; 1645 *task_destroyed_ = true;
1718 } 1646 }
1719 virtual void Run() { 1647 virtual void Run() {
1720 // This task should never run. 1648 // This task should never run.
1721 ADD_FAILURE(); 1649 ADD_FAILURE();
1722 } 1650 }
1723 private: 1651 private:
1724 bool* task_destroyed_; 1652 bool* task_destroyed_;
1725 bool* destruction_observer_called_; 1653 bool* destruction_observer_called_;
(...skipping 25 matching lines...) Expand all
1751 // Verify that the destruction observer gets called at the very end (after 1679 // Verify that the destruction observer gets called at the very end (after
1752 // all the pending tasks have been destroyed). 1680 // all the pending tasks have been destroyed).
1753 MessageLoop* loop = new MessageLoop; 1681 MessageLoop* loop = new MessageLoop;
1754 const int kDelayMS = 100; 1682 const int kDelayMS = 100;
1755 1683
1756 bool task_destroyed = false; 1684 bool task_destroyed = false;
1757 bool destruction_observer_called = false; 1685 bool destruction_observer_called = false;
1758 1686
1759 MLDestructionObserver observer(&task_destroyed, &destruction_observer_called); 1687 MLDestructionObserver observer(&task_destroyed, &destruction_observer_called);
1760 loop->AddDestructionObserver(&observer); 1688 loop->AddDestructionObserver(&observer);
1761 loop->PostDelayedTask( 1689 loop->PostDelayedClosure(
1762 FROM_HERE, 1690 FROM_HERE,
1763 new RunAtDestructionTask(&task_destroyed, &destruction_observer_called), 1691 base::Bind(&DestructionObserverProbe::Run,
1692 new DestructionObserverProbe(&task_destroyed,
1693 &destruction_observer_called)),
1764 kDelayMS); 1694 kDelayMS);
1765 delete loop; 1695 delete loop;
1766 EXPECT_TRUE(observer.task_destroyed_before_message_loop()); 1696 EXPECT_TRUE(observer.task_destroyed_before_message_loop());
1767 // The task should have been destroyed when we deleted the loop. 1697 // The task should have been destroyed when we deleted the loop.
1768 EXPECT_TRUE(task_destroyed); 1698 EXPECT_TRUE(task_destroyed);
1769 EXPECT_TRUE(destruction_observer_called); 1699 EXPECT_TRUE(destruction_observer_called);
1770 } 1700 }
OLDNEW
« base/message_loop.cc ('K') | « base/message_loop.cc ('k') | chrome/browser/jankometer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698