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 |