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

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