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_pump_glib.h" | 5 #include "base/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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 : injector_(injector), | 304 : injector_(injector), |
305 event_count_(kStartingEventCount), | 305 event_count_(kStartingEventCount), |
306 task_count_(kStartingTaskCount) { | 306 task_count_(kStartingTaskCount) { |
307 } | 307 } |
308 | 308 |
309 void FromTask() { | 309 void FromTask() { |
310 if (task_count_ > 0) { | 310 if (task_count_ > 0) { |
311 --task_count_; | 311 --task_count_; |
312 } | 312 } |
313 if (task_count_ == 0 && event_count_ == 0) { | 313 if (task_count_ == 0 && event_count_ == 0) { |
314 MessageLoop::current()->Quit(); | 314 MessageLoop::current()->QuitWhenIdle(); |
315 } else { | 315 } else { |
316 MessageLoop::current()->PostTask( | 316 MessageLoop::current()->PostTask( |
317 FROM_HERE, base::Bind(&ConcurrentHelper::FromTask, this)); | 317 FROM_HERE, base::Bind(&ConcurrentHelper::FromTask, this)); |
318 } | 318 } |
319 } | 319 } |
320 | 320 |
321 void FromEvent() { | 321 void FromEvent() { |
322 if (event_count_ > 0) { | 322 if (event_count_ > 0) { |
323 --event_count_; | 323 --event_count_; |
324 } | 324 } |
325 if (task_count_ == 0 && event_count_ == 0) { | 325 if (task_count_ == 0 && event_count_ == 0) { |
326 MessageLoop::current()->Quit(); | 326 MessageLoop::current()->QuitWhenIdle(); |
327 } else { | 327 } else { |
328 injector_->AddEventAsTask( | 328 injector_->AddEventAsTask( |
329 0, base::Bind(&ConcurrentHelper::FromEvent, this)); | 329 0, base::Bind(&ConcurrentHelper::FromEvent, this)); |
330 } | 330 } |
331 } | 331 } |
332 | 332 |
333 int event_count() const { return event_count_; } | 333 int event_count() const { return event_count_; } |
334 int task_count() const { return task_count_; } | 334 int task_count() const { return task_count_; } |
335 | 335 |
336 private: | 336 private: |
337 friend class base::RefCounted<ConcurrentHelper>; | 337 friend class base::RefCounted<ConcurrentHelper>; |
338 | 338 |
339 ~ConcurrentHelper() {} | 339 ~ConcurrentHelper() {} |
340 | 340 |
341 static const int kStartingEventCount = 20; | 341 static const int kStartingEventCount = 20; |
342 static const int kStartingTaskCount = 20; | 342 static const int kStartingTaskCount = 20; |
343 | 343 |
344 EventInjector* injector_; | 344 EventInjector* injector_; |
345 int event_count_; | 345 int event_count_; |
346 int task_count_; | 346 int task_count_; |
347 }; | 347 }; |
348 | 348 |
349 } // namespace | 349 } // namespace |
350 | 350 |
351 TEST_F(MessagePumpGLibTest, TestConcurrentEventPostedTask) { | 351 TEST_F(MessagePumpGLibTest, TestConcurrentEventPostedTask) { |
352 // Tests that posted tasks don't starve events, nor the opposite. | 352 // Tests that posted tasks don't starve events, nor the opposite. |
353 // We use the helper class above. We keep both event and posted task queues | 353 // We use the helper class above. We keep both event and posted task queues |
354 // full, the helper verifies that both tasks and events get processed. | 354 // full, the helper verifies that both tasks and events get processed. |
355 // If that is not the case, either event_count_ or task_count_ will not get | 355 // If that is not the case, either event_count_ or task_count_ will not get |
356 // to 0, and MessageLoop::Quit() will never be called. | 356 // to 0, and MessageLoop::QuitWhenIdle() will never be called. |
357 scoped_refptr<ConcurrentHelper> helper = new ConcurrentHelper(injector()); | 357 scoped_refptr<ConcurrentHelper> helper = new ConcurrentHelper(injector()); |
358 | 358 |
359 // Add 2 events to the queue to make sure it is always full (when we remove | 359 // Add 2 events to the queue to make sure it is always full (when we remove |
360 // the event before processing it). | 360 // the event before processing it). |
361 injector()->AddEventAsTask( | 361 injector()->AddEventAsTask( |
362 0, base::Bind(&ConcurrentHelper::FromEvent, helper.get())); | 362 0, base::Bind(&ConcurrentHelper::FromEvent, helper.get())); |
363 injector()->AddEventAsTask( | 363 injector()->AddEventAsTask( |
364 0, base::Bind(&ConcurrentHelper::FromEvent, helper.get())); | 364 0, base::Bind(&ConcurrentHelper::FromEvent, helper.get())); |
365 | 365 |
366 // Similarly post 2 tasks. | 366 // Similarly post 2 tasks. |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 MessageLoop::current()->PostDelayedTask( | 507 MessageLoop::current()->PostDelayedTask( |
508 FROM_HERE, | 508 FROM_HERE, |
509 base::Bind(&GLibLoopRunner::Quit, runner.get()), | 509 base::Bind(&GLibLoopRunner::Quit, runner.get()), |
510 base::TimeDelta::FromMilliseconds(40)); | 510 base::TimeDelta::FromMilliseconds(40)); |
511 | 511 |
512 // Run a nested, straight GLib message loop. | 512 // Run a nested, straight GLib message loop. |
513 runner->RunGLib(); | 513 runner->RunGLib(); |
514 | 514 |
515 ASSERT_EQ(3, task_count); | 515 ASSERT_EQ(3, task_count); |
516 EXPECT_EQ(4, injector->processed_events()); | 516 EXPECT_EQ(4, injector->processed_events()); |
517 MessageLoop::current()->Quit(); | 517 MessageLoop::current()->QuitWhenIdle(); |
518 } | 518 } |
519 | 519 |
520 void TestGtkLoopInternal(EventInjector* injector) { | 520 void TestGtkLoopInternal(EventInjector* injector) { |
521 // Allow tasks to be processed from 'native' event loops. | 521 // Allow tasks to be processed from 'native' event loops. |
522 MessageLoop::current()->SetNestableTasksAllowed(true); | 522 MessageLoop::current()->SetNestableTasksAllowed(true); |
523 scoped_refptr<GLibLoopRunner> runner = new GLibLoopRunner(); | 523 scoped_refptr<GLibLoopRunner> runner = new GLibLoopRunner(); |
524 | 524 |
525 int task_count = 0; | 525 int task_count = 0; |
526 // Add a couple of dummy events | 526 // Add a couple of dummy events |
527 injector->AddDummyEvent(0); | 527 injector->AddDummyEvent(0); |
(...skipping 14 matching lines...) Expand all Loading... |
542 MessageLoop::current()->PostDelayedTask( | 542 MessageLoop::current()->PostDelayedTask( |
543 FROM_HERE, | 543 FROM_HERE, |
544 base::Bind(&GLibLoopRunner::Quit, runner.get()), | 544 base::Bind(&GLibLoopRunner::Quit, runner.get()), |
545 base::TimeDelta::FromMilliseconds(40)); | 545 base::TimeDelta::FromMilliseconds(40)); |
546 | 546 |
547 // Run a nested, straight Gtk message loop. | 547 // Run a nested, straight Gtk message loop. |
548 runner->RunLoop(); | 548 runner->RunLoop(); |
549 | 549 |
550 ASSERT_EQ(3, task_count); | 550 ASSERT_EQ(3, task_count); |
551 EXPECT_EQ(4, injector->processed_events()); | 551 EXPECT_EQ(4, injector->processed_events()); |
552 MessageLoop::current()->Quit(); | 552 MessageLoop::current()->QuitWhenIdle(); |
553 } | 553 } |
554 | 554 |
555 } // namespace | 555 } // namespace |
556 | 556 |
557 TEST_F(MessagePumpGLibTest, TestGLibLoop) { | 557 TEST_F(MessagePumpGLibTest, TestGLibLoop) { |
558 // Tests that events and posted tasks are correctly executed if the message | 558 // Tests that events and posted tasks are correctly executed if the message |
559 // loop is not run by MessageLoop::Run() but by a straight GLib loop. | 559 // loop is not run by MessageLoop::Run() but by a straight GLib loop. |
560 // Note that in this case we don't make strong guarantees about niceness | 560 // Note that in this case we don't make strong guarantees about niceness |
561 // between events and posted tasks. | 561 // between events and posted tasks. |
562 loop()->PostTask( | 562 loop()->PostTask( |
563 FROM_HERE, | 563 FROM_HERE, |
564 base::Bind(&TestGLibLoopInternal, base::Unretained(injector()))); | 564 base::Bind(&TestGLibLoopInternal, base::Unretained(injector()))); |
565 loop()->Run(); | 565 loop()->Run(); |
566 } | 566 } |
567 | 567 |
568 TEST_F(MessagePumpGLibTest, TestGtkLoop) { | 568 TEST_F(MessagePumpGLibTest, TestGtkLoop) { |
569 // Tests that events and posted tasks are correctly executed if the message | 569 // Tests that events and posted tasks are correctly executed if the message |
570 // loop is not run by MessageLoop::Run() but by a straight Gtk loop. | 570 // loop is not run by MessageLoop::Run() but by a straight Gtk loop. |
571 // Note that in this case we don't make strong guarantees about niceness | 571 // Note that in this case we don't make strong guarantees about niceness |
572 // between events and posted tasks. | 572 // between events and posted tasks. |
573 loop()->PostTask( | 573 loop()->PostTask( |
574 FROM_HERE, | 574 FROM_HERE, |
575 base::Bind(&TestGtkLoopInternal, base::Unretained(injector()))); | 575 base::Bind(&TestGtkLoopInternal, base::Unretained(injector()))); |
576 loop()->Run(); | 576 loop()->Run(); |
577 } | 577 } |
OLD | NEW |