OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/message_loop/message_pump_glib.h" | 5 #include "base/message_loop/message_pump_glib.h" |
6 | 6 |
7 #include <glib.h> | 7 #include <glib.h> |
8 #include <math.h> | 8 #include <math.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 RunLoop().Run(); | 230 RunLoop().Run(); |
231 EXPECT_EQ(4, injector()->processed_events()); | 231 EXPECT_EQ(4, injector()->processed_events()); |
232 } | 232 } |
233 | 233 |
234 TEST_F(MessagePumpGLibTest, TestWorkWhileWaitingForEvents) { | 234 TEST_F(MessagePumpGLibTest, TestWorkWhileWaitingForEvents) { |
235 int task_count = 0; | 235 int task_count = 0; |
236 // Tests that we process tasks while waiting for new events. | 236 // Tests that we process tasks while waiting for new events. |
237 // The event queue is empty at first. | 237 // The event queue is empty at first. |
238 for (int i = 0; i < 10; ++i) { | 238 for (int i = 0; i < 10; ++i) { |
239 loop()->task_runner()->PostTask(FROM_HERE, | 239 loop()->task_runner()->PostTask(FROM_HERE, |
240 Bind(&IncrementInt, &task_count)); | 240 BindOnce(&IncrementInt, &task_count)); |
241 } | 241 } |
242 // After all the previous tasks have executed, enqueue an event that will | 242 // After all the previous tasks have executed, enqueue an event that will |
243 // quit. | 243 // quit. |
244 loop()->task_runner()->PostTask( | 244 loop()->task_runner()->PostTask( |
245 FROM_HERE, Bind(&EventInjector::AddEvent, Unretained(injector()), 0, | 245 FROM_HERE, BindOnce(&EventInjector::AddEvent, Unretained(injector()), 0, |
246 MessageLoop::QuitWhenIdleClosure())); | 246 MessageLoop::QuitWhenIdleClosure())); |
247 RunLoop().Run(); | 247 RunLoop().Run(); |
248 ASSERT_EQ(10, task_count); | 248 ASSERT_EQ(10, task_count); |
249 EXPECT_EQ(1, injector()->processed_events()); | 249 EXPECT_EQ(1, injector()->processed_events()); |
250 | 250 |
251 // Tests that we process delayed tasks while waiting for new events. | 251 // Tests that we process delayed tasks while waiting for new events. |
252 injector()->Reset(); | 252 injector()->Reset(); |
253 task_count = 0; | 253 task_count = 0; |
254 for (int i = 0; i < 10; ++i) { | 254 for (int i = 0; i < 10; ++i) { |
255 loop()->task_runner()->PostDelayedTask(FROM_HERE, | 255 loop()->task_runner()->PostDelayedTask(FROM_HERE, |
256 Bind(&IncrementInt, &task_count), | 256 BindOnce(&IncrementInt, &task_count), |
257 TimeDelta::FromMilliseconds(10 * i)); | 257 TimeDelta::FromMilliseconds(10 * i)); |
258 } | 258 } |
259 // After all the previous tasks have executed, enqueue an event that will | 259 // After all the previous tasks have executed, enqueue an event that will |
260 // quit. | 260 // quit. |
261 // This relies on the fact that delayed tasks are executed in delay order. | 261 // This relies on the fact that delayed tasks are executed in delay order. |
262 // That is verified in message_loop_unittest.cc. | 262 // That is verified in message_loop_unittest.cc. |
263 loop()->task_runner()->PostDelayedTask( | 263 loop()->task_runner()->PostDelayedTask( |
264 FROM_HERE, Bind(&EventInjector::AddEvent, Unretained(injector()), 10, | 264 FROM_HERE, |
265 MessageLoop::QuitWhenIdleClosure()), | 265 BindOnce(&EventInjector::AddEvent, Unretained(injector()), 10, |
| 266 MessageLoop::QuitWhenIdleClosure()), |
266 TimeDelta::FromMilliseconds(150)); | 267 TimeDelta::FromMilliseconds(150)); |
267 RunLoop().Run(); | 268 RunLoop().Run(); |
268 ASSERT_EQ(10, task_count); | 269 ASSERT_EQ(10, task_count); |
269 EXPECT_EQ(1, injector()->processed_events()); | 270 EXPECT_EQ(1, injector()->processed_events()); |
270 } | 271 } |
271 | 272 |
272 TEST_F(MessagePumpGLibTest, TestEventsWhileWaitingForWork) { | 273 TEST_F(MessagePumpGLibTest, TestEventsWhileWaitingForWork) { |
273 // Tests that we process events while waiting for work. | 274 // Tests that we process events while waiting for work. |
274 // The event queue is empty at first. | 275 // The event queue is empty at first. |
275 for (int i = 0; i < 10; ++i) { | 276 for (int i = 0; i < 10; ++i) { |
(...skipping 29 matching lines...) Expand all Loading... |
305 } | 306 } |
306 | 307 |
307 void FromTask() { | 308 void FromTask() { |
308 if (task_count_ > 0) { | 309 if (task_count_ > 0) { |
309 --task_count_; | 310 --task_count_; |
310 } | 311 } |
311 if (task_count_ == 0 && event_count_ == 0) { | 312 if (task_count_ == 0 && event_count_ == 0) { |
312 MessageLoop::current()->QuitWhenIdle(); | 313 MessageLoop::current()->QuitWhenIdle(); |
313 } else { | 314 } else { |
314 ThreadTaskRunnerHandle::Get()->PostTask( | 315 ThreadTaskRunnerHandle::Get()->PostTask( |
315 FROM_HERE, Bind(&ConcurrentHelper::FromTask, this)); | 316 FROM_HERE, BindOnce(&ConcurrentHelper::FromTask, this)); |
316 } | 317 } |
317 } | 318 } |
318 | 319 |
319 void FromEvent() { | 320 void FromEvent() { |
320 if (event_count_ > 0) { | 321 if (event_count_ > 0) { |
321 --event_count_; | 322 --event_count_; |
322 } | 323 } |
323 if (task_count_ == 0 && event_count_ == 0) { | 324 if (task_count_ == 0 && event_count_ == 0) { |
324 MessageLoop::current()->QuitWhenIdle(); | 325 MessageLoop::current()->QuitWhenIdle(); |
325 } else { | 326 } else { |
(...skipping 30 matching lines...) Expand all Loading... |
356 | 357 |
357 // Add 2 events to the queue to make sure it is always full (when we remove | 358 // Add 2 events to the queue to make sure it is always full (when we remove |
358 // the event before processing it). | 359 // the event before processing it). |
359 injector()->AddEventAsTask( | 360 injector()->AddEventAsTask( |
360 0, Bind(&ConcurrentHelper::FromEvent, helper)); | 361 0, Bind(&ConcurrentHelper::FromEvent, helper)); |
361 injector()->AddEventAsTask( | 362 injector()->AddEventAsTask( |
362 0, Bind(&ConcurrentHelper::FromEvent, helper)); | 363 0, Bind(&ConcurrentHelper::FromEvent, helper)); |
363 | 364 |
364 // Similarly post 2 tasks. | 365 // Similarly post 2 tasks. |
365 loop()->task_runner()->PostTask( | 366 loop()->task_runner()->PostTask( |
366 FROM_HERE, Bind(&ConcurrentHelper::FromTask, helper)); | 367 FROM_HERE, BindOnce(&ConcurrentHelper::FromTask, helper)); |
367 loop()->task_runner()->PostTask( | 368 loop()->task_runner()->PostTask( |
368 FROM_HERE, Bind(&ConcurrentHelper::FromTask, helper)); | 369 FROM_HERE, BindOnce(&ConcurrentHelper::FromTask, helper)); |
369 | 370 |
370 RunLoop().Run(); | 371 RunLoop().Run(); |
371 EXPECT_EQ(0, helper->event_count()); | 372 EXPECT_EQ(0, helper->event_count()); |
372 EXPECT_EQ(0, helper->task_count()); | 373 EXPECT_EQ(0, helper->task_count()); |
373 } | 374 } |
374 | 375 |
375 namespace { | 376 namespace { |
376 | 377 |
377 void AddEventsAndDrainGLib(EventInjector* injector) { | 378 void AddEventsAndDrainGLib(EventInjector* injector) { |
378 // Add a couple of dummy events | 379 // Add a couple of dummy events |
379 injector->AddDummyEvent(0); | 380 injector->AddDummyEvent(0); |
380 injector->AddDummyEvent(0); | 381 injector->AddDummyEvent(0); |
381 // Then add an event that will quit the main loop. | 382 // Then add an event that will quit the main loop. |
382 injector->AddEvent(0, MessageLoop::QuitWhenIdleClosure()); | 383 injector->AddEvent(0, MessageLoop::QuitWhenIdleClosure()); |
383 | 384 |
384 // Post a couple of dummy tasks | 385 // Post a couple of dummy tasks |
385 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, Bind(&DoNothing)); | 386 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, BindOnce(&DoNothing)); |
386 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, Bind(&DoNothing)); | 387 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, BindOnce(&DoNothing)); |
387 | 388 |
388 // Drain the events | 389 // Drain the events |
389 while (g_main_context_pending(NULL)) { | 390 while (g_main_context_pending(NULL)) { |
390 g_main_context_iteration(NULL, FALSE); | 391 g_main_context_iteration(NULL, FALSE); |
391 } | 392 } |
392 } | 393 } |
393 | 394 |
394 } // namespace | 395 } // namespace |
395 | 396 |
396 TEST_F(MessagePumpGLibTest, TestDrainingGLib) { | 397 TEST_F(MessagePumpGLibTest, TestDrainingGLib) { |
397 // Tests that draining events using GLib works. | 398 // Tests that draining events using GLib works. |
398 loop()->task_runner()->PostTask( | 399 loop()->task_runner()->PostTask( |
399 FROM_HERE, Bind(&AddEventsAndDrainGLib, Unretained(injector()))); | 400 FROM_HERE, BindOnce(&AddEventsAndDrainGLib, Unretained(injector()))); |
400 RunLoop().Run(); | 401 RunLoop().Run(); |
401 | 402 |
402 EXPECT_EQ(3, injector()->processed_events()); | 403 EXPECT_EQ(3, injector()->processed_events()); |
403 } | 404 } |
404 | 405 |
405 namespace { | 406 namespace { |
406 | 407 |
407 // Helper class that lets us run the GLib message loop. | 408 // Helper class that lets us run the GLib message loop. |
408 class GLibLoopRunner : public RefCounted<GLibLoopRunner> { | 409 class GLibLoopRunner : public RefCounted<GLibLoopRunner> { |
409 public: | 410 public: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 // Allow tasks to be processed from 'native' event loops. | 442 // Allow tasks to be processed from 'native' event loops. |
442 MessageLoop::current()->SetNestableTasksAllowed(true); | 443 MessageLoop::current()->SetNestableTasksAllowed(true); |
443 scoped_refptr<GLibLoopRunner> runner = new GLibLoopRunner(); | 444 scoped_refptr<GLibLoopRunner> runner = new GLibLoopRunner(); |
444 | 445 |
445 int task_count = 0; | 446 int task_count = 0; |
446 // Add a couple of dummy events | 447 // Add a couple of dummy events |
447 injector->AddDummyEvent(0); | 448 injector->AddDummyEvent(0); |
448 injector->AddDummyEvent(0); | 449 injector->AddDummyEvent(0); |
449 // Post a couple of dummy tasks | 450 // Post a couple of dummy tasks |
450 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 451 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
451 Bind(&IncrementInt, &task_count)); | 452 BindOnce(&IncrementInt, &task_count)); |
452 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 453 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
453 Bind(&IncrementInt, &task_count)); | 454 BindOnce(&IncrementInt, &task_count)); |
454 // Delayed events | 455 // Delayed events |
455 injector->AddDummyEvent(10); | 456 injector->AddDummyEvent(10); |
456 injector->AddDummyEvent(10); | 457 injector->AddDummyEvent(10); |
457 // Delayed work | 458 // Delayed work |
458 ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 459 ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
459 FROM_HERE, Bind(&IncrementInt, &task_count), | 460 FROM_HERE, BindOnce(&IncrementInt, &task_count), |
460 TimeDelta::FromMilliseconds(30)); | 461 TimeDelta::FromMilliseconds(30)); |
461 ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 462 ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
462 FROM_HERE, Bind(&GLibLoopRunner::Quit, runner), | 463 FROM_HERE, BindOnce(&GLibLoopRunner::Quit, runner), |
463 TimeDelta::FromMilliseconds(40)); | 464 TimeDelta::FromMilliseconds(40)); |
464 | 465 |
465 // Run a nested, straight GLib message loop. | 466 // Run a nested, straight GLib message loop. |
466 runner->RunGLib(); | 467 runner->RunGLib(); |
467 | 468 |
468 ASSERT_EQ(3, task_count); | 469 ASSERT_EQ(3, task_count); |
469 EXPECT_EQ(4, injector->processed_events()); | 470 EXPECT_EQ(4, injector->processed_events()); |
470 MessageLoop::current()->QuitWhenIdle(); | 471 MessageLoop::current()->QuitWhenIdle(); |
471 } | 472 } |
472 | 473 |
473 void TestGtkLoopInternal(EventInjector* injector) { | 474 void TestGtkLoopInternal(EventInjector* injector) { |
474 // Allow tasks to be processed from 'native' event loops. | 475 // Allow tasks to be processed from 'native' event loops. |
475 MessageLoop::current()->SetNestableTasksAllowed(true); | 476 MessageLoop::current()->SetNestableTasksAllowed(true); |
476 scoped_refptr<GLibLoopRunner> runner = new GLibLoopRunner(); | 477 scoped_refptr<GLibLoopRunner> runner = new GLibLoopRunner(); |
477 | 478 |
478 int task_count = 0; | 479 int task_count = 0; |
479 // Add a couple of dummy events | 480 // Add a couple of dummy events |
480 injector->AddDummyEvent(0); | 481 injector->AddDummyEvent(0); |
481 injector->AddDummyEvent(0); | 482 injector->AddDummyEvent(0); |
482 // Post a couple of dummy tasks | 483 // Post a couple of dummy tasks |
483 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 484 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
484 Bind(&IncrementInt, &task_count)); | 485 BindOnce(&IncrementInt, &task_count)); |
485 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 486 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
486 Bind(&IncrementInt, &task_count)); | 487 BindOnce(&IncrementInt, &task_count)); |
487 // Delayed events | 488 // Delayed events |
488 injector->AddDummyEvent(10); | 489 injector->AddDummyEvent(10); |
489 injector->AddDummyEvent(10); | 490 injector->AddDummyEvent(10); |
490 // Delayed work | 491 // Delayed work |
491 ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 492 ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
492 FROM_HERE, Bind(&IncrementInt, &task_count), | 493 FROM_HERE, BindOnce(&IncrementInt, &task_count), |
493 TimeDelta::FromMilliseconds(30)); | 494 TimeDelta::FromMilliseconds(30)); |
494 ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 495 ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
495 FROM_HERE, Bind(&GLibLoopRunner::Quit, runner), | 496 FROM_HERE, BindOnce(&GLibLoopRunner::Quit, runner), |
496 TimeDelta::FromMilliseconds(40)); | 497 TimeDelta::FromMilliseconds(40)); |
497 | 498 |
498 // Run a nested, straight Gtk message loop. | 499 // Run a nested, straight Gtk message loop. |
499 runner->RunLoop(); | 500 runner->RunLoop(); |
500 | 501 |
501 ASSERT_EQ(3, task_count); | 502 ASSERT_EQ(3, task_count); |
502 EXPECT_EQ(4, injector->processed_events()); | 503 EXPECT_EQ(4, injector->processed_events()); |
503 MessageLoop::current()->QuitWhenIdle(); | 504 MessageLoop::current()->QuitWhenIdle(); |
504 } | 505 } |
505 | 506 |
506 } // namespace | 507 } // namespace |
507 | 508 |
508 TEST_F(MessagePumpGLibTest, TestGLibLoop) { | 509 TEST_F(MessagePumpGLibTest, TestGLibLoop) { |
509 // Tests that events and posted tasks are correctly executed if the message | 510 // Tests that events and posted tasks are correctly executed if the message |
510 // loop is not run by MessageLoop::Run() but by a straight GLib loop. | 511 // loop is not run by MessageLoop::Run() but by a straight GLib loop. |
511 // Note that in this case we don't make strong guarantees about niceness | 512 // Note that in this case we don't make strong guarantees about niceness |
512 // between events and posted tasks. | 513 // between events and posted tasks. |
513 loop()->task_runner()->PostTask( | 514 loop()->task_runner()->PostTask( |
514 FROM_HERE, Bind(&TestGLibLoopInternal, Unretained(injector()))); | 515 FROM_HERE, BindOnce(&TestGLibLoopInternal, Unretained(injector()))); |
515 RunLoop().Run(); | 516 RunLoop().Run(); |
516 } | 517 } |
517 | 518 |
518 TEST_F(MessagePumpGLibTest, TestGtkLoop) { | 519 TEST_F(MessagePumpGLibTest, TestGtkLoop) { |
519 // Tests that events and posted tasks are correctly executed if the message | 520 // Tests that events and posted tasks are correctly executed if the message |
520 // loop is not run by MessageLoop::Run() but by a straight Gtk loop. | 521 // loop is not run by MessageLoop::Run() but by a straight Gtk loop. |
521 // Note that in this case we don't make strong guarantees about niceness | 522 // Note that in this case we don't make strong guarantees about niceness |
522 // between events and posted tasks. | 523 // between events and posted tasks. |
523 loop()->task_runner()->PostTask( | 524 loop()->task_runner()->PostTask( |
524 FROM_HERE, Bind(&TestGtkLoopInternal, Unretained(injector()))); | 525 FROM_HERE, BindOnce(&TestGtkLoopInternal, Unretained(injector()))); |
525 RunLoop().Run(); | 526 RunLoop().Run(); |
526 } | 527 } |
527 | 528 |
528 } // namespace base | 529 } // namespace base |
OLD | NEW |