| OLD | NEW |
| 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 "base/message_pump_glib.h" | 5 #include "base/message_pump_glib.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | |
| 8 #include <math.h> | 7 #include <math.h> |
| 9 | 8 |
| 10 #include <algorithm> | 9 #include <algorithm> |
| 11 #include <vector> | 10 #include <vector> |
| 12 | 11 |
| 13 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 14 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 15 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 16 |
| 17 #if defined(TOOLKIT_USES_GTK) |
| 18 #include <gtk/gtk.h> |
| 19 #endif |
| 20 |
| 18 namespace { | 21 namespace { |
| 19 | 22 |
| 20 // This class injects dummy "events" into the GLib loop. When "handled" these | 23 // This class injects dummy "events" into the GLib loop. When "handled" these |
| 21 // events can run tasks. This is intended to mock gtk events (the corresponding | 24 // events can run tasks. This is intended to mock gtk events (the corresponding |
| 22 // GLib source runs at the same priority). | 25 // GLib source runs at the same priority). |
| 23 class EventInjector { | 26 class EventInjector { |
| 24 public: | 27 public: |
| 25 EventInjector() : processed_events_(0) { | 28 EventInjector() : processed_events_(0) { |
| 26 source_ = static_cast<Source*>(g_source_new(&SourceFuncs, sizeof(Source))); | 29 source_ = static_cast<Source*>(g_source_new(&SourceFuncs, sizeof(Source))); |
| 27 source_->injector = this; | 30 source_->injector = this; |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 loop()->PostTask( | 391 loop()->PostTask( |
| 389 FROM_HERE, NewRunnableFunction(AddEventsAndDrainGLib, injector())); | 392 FROM_HERE, NewRunnableFunction(AddEventsAndDrainGLib, injector())); |
| 390 loop()->Run(); | 393 loop()->Run(); |
| 391 | 394 |
| 392 EXPECT_EQ(3, injector()->processed_events()); | 395 EXPECT_EQ(3, injector()->processed_events()); |
| 393 } | 396 } |
| 394 | 397 |
| 395 | 398 |
| 396 namespace { | 399 namespace { |
| 397 | 400 |
| 401 #if defined(TOOLKIT_USES_GTK) |
| 398 void AddEventsAndDrainGtk(EventInjector* injector) { | 402 void AddEventsAndDrainGtk(EventInjector* injector) { |
| 399 // Add a couple of dummy events | 403 // Add a couple of dummy events |
| 400 injector->AddEvent(0, NULL); | 404 injector->AddEvent(0, NULL); |
| 401 injector->AddEvent(0, NULL); | 405 injector->AddEvent(0, NULL); |
| 402 // Then add an event that will quit the main loop. | 406 // Then add an event that will quit the main loop. |
| 403 injector->AddEvent(0, NewQuitTask()); | 407 injector->AddEvent(0, NewQuitTask()); |
| 404 | 408 |
| 405 // Post a couple of dummy tasks | 409 // Post a couple of dummy tasks |
| 406 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(DoNothing)); | 410 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(DoNothing)); |
| 407 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(DoNothing)); | 411 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(DoNothing)); |
| 408 | 412 |
| 409 // Drain the events | 413 // Drain the events |
| 410 while (gtk_events_pending()) { | 414 while (gtk_events_pending()) { |
| 411 gtk_main_iteration(); | 415 gtk_main_iteration(); |
| 412 } | 416 } |
| 413 } | 417 } |
| 418 #endif |
| 414 | 419 |
| 415 } // namespace | 420 } // namespace |
| 416 | 421 |
| 422 #if defined(TOOLKIT_USES_GTK) |
| 417 TEST_F(MessagePumpGLibTest, TestDrainingGtk) { | 423 TEST_F(MessagePumpGLibTest, TestDrainingGtk) { |
| 418 // Tests that draining events using Gtk works. | 424 // Tests that draining events using Gtk works. |
| 419 loop()->PostTask( | 425 loop()->PostTask( |
| 420 FROM_HERE, NewRunnableFunction(AddEventsAndDrainGtk, injector())); | 426 FROM_HERE, NewRunnableFunction(AddEventsAndDrainGtk, injector())); |
| 421 loop()->Run(); | 427 loop()->Run(); |
| 422 | 428 |
| 423 EXPECT_EQ(3, injector()->processed_events()); | 429 EXPECT_EQ(3, injector()->processed_events()); |
| 424 } | 430 } |
| 431 #endif |
| 425 | 432 |
| 426 namespace { | 433 namespace { |
| 427 | 434 |
| 428 // Helper class that lets us run the GLib message loop. | 435 // Helper class that lets us run the GLib message loop. |
| 429 class GLibLoopRunner : public base::RefCounted<GLibLoopRunner> { | 436 class GLibLoopRunner : public base::RefCounted<GLibLoopRunner> { |
| 430 public: | 437 public: |
| 431 GLibLoopRunner() : quit_(false) { } | 438 GLibLoopRunner() : quit_(false) { } |
| 432 | 439 |
| 433 void RunGLib() { | 440 void RunGLib() { |
| 434 while (!quit_) { | 441 while (!quit_) { |
| 435 g_main_context_iteration(NULL, TRUE); | 442 g_main_context_iteration(NULL, TRUE); |
| 436 } | 443 } |
| 437 } | 444 } |
| 438 | 445 |
| 439 void RunGtk() { | 446 void RunLoop() { |
| 447 #if defined(TOOLKIT_USES_GTK) |
| 440 while (!quit_) { | 448 while (!quit_) { |
| 441 gtk_main_iteration(); | 449 gtk_main_iteration(); |
| 442 } | 450 } |
| 451 #else |
| 452 while (!quit_) { |
| 453 g_main_context_iteration(NULL, TRUE); |
| 454 } |
| 455 #endif |
| 443 } | 456 } |
| 444 | 457 |
| 445 void Quit() { | 458 void Quit() { |
| 446 quit_ = true; | 459 quit_ = true; |
| 447 } | 460 } |
| 448 | 461 |
| 449 void Reset() { | 462 void Reset() { |
| 450 quit_ = false; | 463 quit_ = false; |
| 451 } | 464 } |
| 452 | 465 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 // Delayed events | 519 // Delayed events |
| 507 injector->AddEvent(10, NULL); | 520 injector->AddEvent(10, NULL); |
| 508 injector->AddEvent(10, NULL); | 521 injector->AddEvent(10, NULL); |
| 509 // Delayed work | 522 // Delayed work |
| 510 MessageLoop::current()->PostDelayedTask( | 523 MessageLoop::current()->PostDelayedTask( |
| 511 FROM_HERE, NewRunnableFunction(IncrementInt, &task_count), 30); | 524 FROM_HERE, NewRunnableFunction(IncrementInt, &task_count), 30); |
| 512 MessageLoop::current()->PostDelayedTask( | 525 MessageLoop::current()->PostDelayedTask( |
| 513 FROM_HERE, NewRunnableMethod(runner.get(), &GLibLoopRunner::Quit), 40); | 526 FROM_HERE, NewRunnableMethod(runner.get(), &GLibLoopRunner::Quit), 40); |
| 514 | 527 |
| 515 // Run a nested, straight Gtk message loop. | 528 // Run a nested, straight Gtk message loop. |
| 516 runner->RunGtk(); | 529 runner->RunLoop(); |
| 517 | 530 |
| 518 ASSERT_EQ(3, task_count); | 531 ASSERT_EQ(3, task_count); |
| 519 EXPECT_EQ(4, injector->processed_events()); | 532 EXPECT_EQ(4, injector->processed_events()); |
| 520 MessageLoop::current()->Quit(); | 533 MessageLoop::current()->Quit(); |
| 521 } | 534 } |
| 522 | 535 |
| 523 } // namespace | 536 } // namespace |
| 524 | 537 |
| 525 TEST_F(MessagePumpGLibTest, TestGLibLoop) { | 538 TEST_F(MessagePumpGLibTest, TestGLibLoop) { |
| 526 // Tests that events and posted tasks are correctly exectuted if the message | 539 // Tests that events and posted tasks are correctly exectuted if the message |
| 527 // loop is not run by MessageLoop::Run() but by a straight GLib loop. | 540 // loop is not run by MessageLoop::Run() but by a straight GLib loop. |
| 528 // Note that in this case we don't make strong guarantees about niceness | 541 // Note that in this case we don't make strong guarantees about niceness |
| 529 // between events and posted tasks. | 542 // between events and posted tasks. |
| 530 loop()->PostTask(FROM_HERE, | 543 loop()->PostTask(FROM_HERE, |
| 531 NewRunnableFunction(TestGLibLoopInternal, injector())); | 544 NewRunnableFunction(TestGLibLoopInternal, injector())); |
| 532 loop()->Run(); | 545 loop()->Run(); |
| 533 } | 546 } |
| 534 | 547 |
| 535 TEST_F(MessagePumpGLibTest, TestGtkLoop) { | 548 TEST_F(MessagePumpGLibTest, TestGtkLoop) { |
| 536 // Tests that events and posted tasks are correctly exectuted if the message | 549 // Tests that events and posted tasks are correctly exectuted if the message |
| 537 // loop is not run by MessageLoop::Run() but by a straight Gtk loop. | 550 // loop is not run by MessageLoop::Run() but by a straight Gtk loop. |
| 538 // Note that in this case we don't make strong guarantees about niceness | 551 // Note that in this case we don't make strong guarantees about niceness |
| 539 // between events and posted tasks. | 552 // between events and posted tasks. |
| 540 loop()->PostTask(FROM_HERE, | 553 loop()->PostTask(FROM_HERE, |
| 541 NewRunnableFunction(TestGtkLoopInternal, injector())); | 554 NewRunnableFunction(TestGtkLoopInternal, injector())); |
| 542 loop()->Run(); | 555 loop()->Run(); |
| 543 } | 556 } |
| OLD | NEW |