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