| 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 |