| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "mojo/system/message_pipe.h" | 5 #include "mojo/system/message_pipe.h" |
| 6 | 6 |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/threading/platform_thread.h" // For |Sleep()|. | 8 #include "base/threading/platform_thread.h" // For |Sleep()|. |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "mojo/system/waiter.h" | 10 #include "mojo/system/waiter.h" |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 359 scoped_refptr<MessagePipe> mp(new MessagePipe()); |
| 360 Waiter waiter; | 360 Waiter waiter; |
| 361 | 361 |
| 362 int32_t buffer[1]; | 362 int32_t buffer[1]; |
| 363 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 363 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
| 364 uint32_t buffer_size; | 364 uint32_t buffer_size; |
| 365 | 365 |
| 366 // Always writable (until the other port is closed). | 366 // Always writable (until the other port is closed). |
| 367 waiter.Init(); | 367 waiter.Init(); |
| 368 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | 368 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, |
| 369 mp->AddWaiter(0, &waiter, MOJO_WAIT_FLAG_WRITABLE, 0)); | 369 mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0)); |
| 370 waiter.Init(); | 370 waiter.Init(); |
| 371 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | 371 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, |
| 372 mp->AddWaiter(0, | 372 mp->AddWaiter(0, |
| 373 &waiter, | 373 &waiter, |
| 374 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE, | 374 MOJO_HANDLE_SIGNAL_READABLE | |
| 375 MOJO_HANDLE_SIGNAL_WRITABLE, |
| 375 0)); | 376 0)); |
| 376 | 377 |
| 377 // Not yet readable. | 378 // Not yet readable. |
| 378 waiter.Init(); | 379 waiter.Init(); |
| 379 EXPECT_EQ(MOJO_RESULT_OK, | 380 EXPECT_EQ(MOJO_RESULT_OK, |
| 380 mp->AddWaiter(0, &waiter, MOJO_WAIT_FLAG_READABLE, 1)); | 381 mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 1)); |
| 381 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, NULL)); | 382 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, NULL)); |
| 382 mp->RemoveWaiter(0, &waiter); | 383 mp->RemoveWaiter(0, &waiter); |
| 383 | 384 |
| 384 // Write from port 0 (to port 1), to make port 1 readable. | 385 // Write from port 0 (to port 1), to make port 1 readable. |
| 385 buffer[0] = 123456789; | 386 buffer[0] = 123456789; |
| 386 EXPECT_EQ(MOJO_RESULT_OK, | 387 EXPECT_EQ(MOJO_RESULT_OK, |
| 387 mp->WriteMessage(0, | 388 mp->WriteMessage(0, |
| 388 buffer, kBufferSize, | 389 buffer, kBufferSize, |
| 389 NULL, | 390 NULL, |
| 390 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 391 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 391 | 392 |
| 392 // Port 1 should already be readable now. | 393 // Port 1 should already be readable now. |
| 393 waiter.Init(); | 394 waiter.Init(); |
| 394 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | 395 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, |
| 395 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 2)); | 396 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 2)); |
| 396 waiter.Init(); | 397 waiter.Init(); |
| 397 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | 398 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, |
| 398 mp->AddWaiter(1, | 399 mp->AddWaiter(1, |
| 399 &waiter, | 400 &waiter, |
| 400 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE, | 401 MOJO_HANDLE_SIGNAL_READABLE | |
| 402 MOJO_HANDLE_SIGNAL_WRITABLE, |
| 401 0)); | 403 0)); |
| 402 // ... and still writable. | 404 // ... and still writable. |
| 403 waiter.Init(); | 405 waiter.Init(); |
| 404 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | 406 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, |
| 405 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_WRITABLE, 3)); | 407 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 3)); |
| 406 | 408 |
| 407 // Close port 0. | 409 // Close port 0. |
| 408 mp->Close(0); | 410 mp->Close(0); |
| 409 | 411 |
| 410 // Now port 1 should not be writable. | 412 // Now port 1 should not be writable. |
| 411 waiter.Init(); | 413 waiter.Init(); |
| 412 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 414 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 413 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_WRITABLE, 4)); | 415 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 4)); |
| 414 | 416 |
| 415 // But it should still be readable. | 417 // But it should still be readable. |
| 416 waiter.Init(); | 418 waiter.Init(); |
| 417 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | 419 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, |
| 418 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 5)); | 420 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 5)); |
| 419 | 421 |
| 420 // Read from port 1. | 422 // Read from port 1. |
| 421 buffer[0] = 0; | 423 buffer[0] = 0; |
| 422 buffer_size = kBufferSize; | 424 buffer_size = kBufferSize; |
| 423 EXPECT_EQ(MOJO_RESULT_OK, | 425 EXPECT_EQ(MOJO_RESULT_OK, |
| 424 mp->ReadMessage(1, | 426 mp->ReadMessage(1, |
| 425 buffer, &buffer_size, | 427 buffer, &buffer_size, |
| 426 0, NULL, | 428 0, NULL, |
| 427 MOJO_READ_MESSAGE_FLAG_NONE)); | 429 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 428 EXPECT_EQ(123456789, buffer[0]); | 430 EXPECT_EQ(123456789, buffer[0]); |
| 429 | 431 |
| 430 // Now port 1 should no longer be readable. | 432 // Now port 1 should no longer be readable. |
| 431 waiter.Init(); | 433 waiter.Init(); |
| 432 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 434 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 433 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 6)); | 435 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 6)); |
| 434 | 436 |
| 435 mp->Close(1); | 437 mp->Close(1); |
| 436 } | 438 } |
| 437 | 439 |
| 438 TEST(MessagePipeTest, ThreadedWaiting) { | 440 TEST(MessagePipeTest, ThreadedWaiting) { |
| 439 int32_t buffer[1]; | 441 int32_t buffer[1]; |
| 440 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 442 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
| 441 | 443 |
| 442 MojoResult result; | 444 MojoResult result; |
| 443 uint32_t context; | 445 uint32_t context; |
| 444 | 446 |
| 445 // Write to wake up waiter waiting for read. | 447 // Write to wake up waiter waiting for read. |
| 446 { | 448 { |
| 447 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 449 scoped_refptr<MessagePipe> mp(new MessagePipe()); |
| 448 test::SimpleWaiterThread thread(&result, &context); | 450 test::SimpleWaiterThread thread(&result, &context); |
| 449 | 451 |
| 450 thread.waiter()->Init(); | 452 thread.waiter()->Init(); |
| 451 EXPECT_EQ(MOJO_RESULT_OK, | 453 EXPECT_EQ(MOJO_RESULT_OK, |
| 452 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 1)); | 454 mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, |
| 455 1)); |
| 453 thread.Start(); | 456 thread.Start(); |
| 454 | 457 |
| 455 buffer[0] = 123456789; | 458 buffer[0] = 123456789; |
| 456 // Write from port 0 (to port 1), which should wake up the waiter. | 459 // Write from port 0 (to port 1), which should wake up the waiter. |
| 457 EXPECT_EQ(MOJO_RESULT_OK, | 460 EXPECT_EQ(MOJO_RESULT_OK, |
| 458 mp->WriteMessage(0, | 461 mp->WriteMessage(0, |
| 459 buffer, kBufferSize, | 462 buffer, kBufferSize, |
| 460 NULL, | 463 NULL, |
| 461 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 464 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 462 | 465 |
| 463 mp->RemoveWaiter(1, thread.waiter()); | 466 mp->RemoveWaiter(1, thread.waiter()); |
| 464 | 467 |
| 465 mp->Close(0); | 468 mp->Close(0); |
| 466 mp->Close(1); | 469 mp->Close(1); |
| 467 } // Joins |thread|. | 470 } // Joins |thread|. |
| 468 // The waiter should have woken up successfully. | 471 // The waiter should have woken up successfully. |
| 469 EXPECT_EQ(MOJO_RESULT_OK, result); | 472 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 470 EXPECT_EQ(1u, context); | 473 EXPECT_EQ(1u, context); |
| 471 | 474 |
| 472 // Close to cancel waiter. | 475 // Close to cancel waiter. |
| 473 { | 476 { |
| 474 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 477 scoped_refptr<MessagePipe> mp(new MessagePipe()); |
| 475 test::SimpleWaiterThread thread(&result, &context); | 478 test::SimpleWaiterThread thread(&result, &context); |
| 476 | 479 |
| 477 thread.waiter()->Init(); | 480 thread.waiter()->Init(); |
| 478 EXPECT_EQ(MOJO_RESULT_OK, | 481 EXPECT_EQ(MOJO_RESULT_OK, |
| 479 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2)); | 482 mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, |
| 483 2)); |
| 480 thread.Start(); | 484 thread.Start(); |
| 481 | 485 |
| 482 // Close port 1 first -- this should result in the waiter being cancelled. | 486 // Close port 1 first -- this should result in the waiter being cancelled. |
| 483 mp->CancelAllWaiters(1); | 487 mp->CancelAllWaiters(1); |
| 484 mp->Close(1); | 488 mp->Close(1); |
| 485 | 489 |
| 486 // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the | 490 // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the |
| 487 // |MessagePipe| to remove any waiter. | 491 // |MessagePipe| to remove any waiter. |
| 488 | 492 |
| 489 mp->Close(0); | 493 mp->Close(0); |
| 490 } // Joins |thread|. | 494 } // Joins |thread|. |
| 491 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 495 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
| 492 EXPECT_EQ(2u, context); | 496 EXPECT_EQ(2u, context); |
| 493 | 497 |
| 494 // Close to make waiter un-wake-up-able. | 498 // Close to make waiter un-wake-up-able. |
| 495 { | 499 { |
| 496 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 500 scoped_refptr<MessagePipe> mp(new MessagePipe()); |
| 497 test::SimpleWaiterThread thread(&result, &context); | 501 test::SimpleWaiterThread thread(&result, &context); |
| 498 | 502 |
| 499 thread.waiter()->Init(); | 503 thread.waiter()->Init(); |
| 500 EXPECT_EQ(MOJO_RESULT_OK, | 504 EXPECT_EQ(MOJO_RESULT_OK, |
| 501 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 3)); | 505 mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, |
| 506 3)); |
| 502 thread.Start(); | 507 thread.Start(); |
| 503 | 508 |
| 504 // Close port 0 first -- this should wake the waiter up, since port 1 will | 509 // Close port 0 first -- this should wake the waiter up, since port 1 will |
| 505 // never be readable. | 510 // never be readable. |
| 506 mp->CancelAllWaiters(0); | 511 mp->CancelAllWaiters(0); |
| 507 mp->Close(0); | 512 mp->Close(0); |
| 508 | 513 |
| 509 mp->RemoveWaiter(1, thread.waiter()); | 514 mp->RemoveWaiter(1, thread.waiter()); |
| 510 | 515 |
| 511 mp->CancelAllWaiters(1); | 516 mp->CancelAllWaiters(1); |
| 512 mp->Close(1); | 517 mp->Close(1); |
| 513 } // Joins |thread|. | 518 } // Joins |thread|. |
| 514 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 519 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| 515 EXPECT_EQ(3u, context); | 520 EXPECT_EQ(3u, context); |
| 516 } | 521 } |
| 517 | 522 |
| 518 } // namespace | 523 } // namespace |
| 519 } // namespace system | 524 } // namespace system |
| 520 } // namespace mojo | 525 } // namespace mojo |
| OLD | NEW |