| 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/edk/system/core.h" | 5 #include "mojo/edk/system/core.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/containers/stack_container.h" | 12 #include "base/containers/stack_container.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/rand_util.h" | 17 #include "base/rand_util.h" |
| 18 #include "base/thread_task_runner_handle.h" | 18 #include "base/thread_task_runner_handle.h" |
| 19 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 20 #include "crypto/random.h" | 20 #include "crypto/random.h" |
| 21 #include "mojo/edk/embedder/embedder.h" | 21 #include "mojo/edk/embedder/embedder.h" |
| 22 #include "mojo/edk/embedder/embedder_internal.h" | 22 #include "mojo/edk/embedder/embedder_internal.h" |
| 23 #include "mojo/edk/embedder/platform_shared_buffer.h" | 23 #include "mojo/edk/embedder/platform_shared_buffer.h" |
| 24 #include "mojo/edk/system/async_waiter.h" | 24 #include "mojo/edk/system/async_waiter.h" |
| 25 #include "mojo/edk/system/channel.h" | 25 #include "mojo/edk/system/channel.h" |
| 26 #include "mojo/edk/system/configuration.h" | 26 #include "mojo/edk/system/configuration.h" |
| 27 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 27 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" |
| 28 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" | 28 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" |
| 29 #include "mojo/edk/system/handle_signals_state.h" | 29 #include "mojo/edk/system/handle_signals_state.h" |
| 30 #include "mojo/edk/system/message_for_transit.h" |
| 30 #include "mojo/edk/system/message_pipe_dispatcher.h" | 31 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 31 #include "mojo/edk/system/platform_handle_dispatcher.h" | 32 #include "mojo/edk/system/platform_handle_dispatcher.h" |
| 32 #include "mojo/edk/system/ports/node.h" | 33 #include "mojo/edk/system/ports/node.h" |
| 33 #include "mojo/edk/system/remote_message_pipe_bootstrap.h" | 34 #include "mojo/edk/system/remote_message_pipe_bootstrap.h" |
| 34 #include "mojo/edk/system/request_context.h" | 35 #include "mojo/edk/system/request_context.h" |
| 35 #include "mojo/edk/system/shared_buffer_dispatcher.h" | 36 #include "mojo/edk/system/shared_buffer_dispatcher.h" |
| 36 #include "mojo/edk/system/wait_set_dispatcher.h" | 37 #include "mojo/edk/system/wait_set_dispatcher.h" |
| 37 #include "mojo/edk/system/waiter.h" | 38 #include "mojo/edk/system/waiter.h" |
| 38 | 39 |
| 39 namespace mojo { | 40 namespace mojo { |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 } | 353 } |
| 353 | 354 |
| 354 MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) { | 355 MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) { |
| 355 RequestContext request_context; | 356 RequestContext request_context; |
| 356 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); | 357 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); |
| 357 if (!dispatcher) | 358 if (!dispatcher) |
| 358 return MOJO_RESULT_INVALID_ARGUMENT; | 359 return MOJO_RESULT_INVALID_ARGUMENT; |
| 359 return dispatcher->CancelWatch(context); | 360 return dispatcher->CancelWatch(context); |
| 360 } | 361 } |
| 361 | 362 |
| 363 MojoResult Core::CreateMessage(uint32_t num_bytes, |
| 364 const MojoHandle* handles, |
| 365 uint32_t num_handles, |
| 366 MojoCreateMessageFlags flags, |
| 367 MojoMessageHandle* message) { |
| 368 if (!message) |
| 369 return MOJO_RESULT_INVALID_ARGUMENT; |
| 370 |
| 371 if (num_handles == 0) { // Fast path: no handles. |
| 372 MessageForTransit* msg; |
| 373 MojoResult rv = MessageForTransit::Create(&msg, num_bytes, nullptr, 0); |
| 374 if (rv != MOJO_RESULT_OK) |
| 375 return rv; |
| 376 |
| 377 *message = reinterpret_cast<MojoMessageHandle>(msg); |
| 378 return MOJO_RESULT_OK; |
| 379 } |
| 380 |
| 381 if (!handles) |
| 382 return MOJO_RESULT_INVALID_ARGUMENT; |
| 383 |
| 384 if (num_handles > kMaxHandlesPerMessage) |
| 385 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 386 |
| 387 std::vector<Dispatcher::DispatcherInTransit> dispatchers; |
| 388 { |
| 389 base::AutoLock lock(handles_lock_); |
| 390 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers); |
| 391 if (rv != MOJO_RESULT_OK) { |
| 392 handles_.CancelTransit(dispatchers); |
| 393 return rv; |
| 394 } |
| 395 } |
| 396 DCHECK_EQ(num_handles, dispatchers.size()); |
| 397 |
| 398 MessageForTransit* msg = nullptr; |
| 399 MojoResult rv = MessageForTransit::Create( |
| 400 &msg, num_bytes, dispatchers.data(), num_handles); |
| 401 |
| 402 { |
| 403 base::AutoLock lock(handles_lock_); |
| 404 if (rv == MOJO_RESULT_OK) { |
| 405 handles_.CompleteTransitAndClose(dispatchers); |
| 406 *message = reinterpret_cast<MojoMessageHandle>(msg); |
| 407 } else { |
| 408 handles_.CancelTransit(dispatchers); |
| 409 } |
| 410 } |
| 411 |
| 412 return rv; |
| 413 } |
| 414 |
| 415 MojoResult Core::DestroyMessage(MojoMessageHandle message) { |
| 416 if (!message) |
| 417 return MOJO_RESULT_INVALID_ARGUMENT; |
| 418 |
| 419 delete reinterpret_cast<MessageForTransit*>(message); |
| 420 |
| 421 return MOJO_RESULT_OK; |
| 422 } |
| 423 |
| 424 MojoResult Core::GetMessageBuffer(MojoMessageHandle message, void** buffer) { |
| 425 if (!message) |
| 426 return MOJO_RESULT_INVALID_ARGUMENT; |
| 427 |
| 428 *buffer = reinterpret_cast<MessageForTransit*>(message)->mutable_bytes(); |
| 429 |
| 430 return MOJO_RESULT_OK; |
| 431 } |
| 432 |
| 362 MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) { | 433 MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) { |
| 363 RequestContext request_context; | 434 RequestContext request_context; |
| 364 if (!wait_set_handle) | 435 if (!wait_set_handle) |
| 365 return MOJO_RESULT_INVALID_ARGUMENT; | 436 return MOJO_RESULT_INVALID_ARGUMENT; |
| 366 | 437 |
| 367 scoped_refptr<WaitSetDispatcher> dispatcher = new WaitSetDispatcher(); | 438 scoped_refptr<WaitSetDispatcher> dispatcher = new WaitSetDispatcher(); |
| 368 MojoHandle h = AddDispatcher(dispatcher); | 439 MojoHandle h = AddDispatcher(dispatcher); |
| 369 if (h == MOJO_HANDLE_INVALID) { | 440 if (h == MOJO_HANDLE_INVALID) { |
| 370 LOG(ERROR) << "Handle table full"; | 441 LOG(ERROR) << "Handle table full"; |
| 371 dispatcher->Close(); | 442 dispatcher->Close(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 | 538 |
| 468 return MOJO_RESULT_OK; | 539 return MOJO_RESULT_OK; |
| 469 } | 540 } |
| 470 | 541 |
| 471 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, | 542 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, |
| 472 const void* bytes, | 543 const void* bytes, |
| 473 uint32_t num_bytes, | 544 uint32_t num_bytes, |
| 474 const MojoHandle* handles, | 545 const MojoHandle* handles, |
| 475 uint32_t num_handles, | 546 uint32_t num_handles, |
| 476 MojoWriteMessageFlags flags) { | 547 MojoWriteMessageFlags flags) { |
| 477 RequestContext request_context; | 548 MessageForTransit* msg = nullptr; |
| 478 auto dispatcher = GetDispatcher(message_pipe_handle); | 549 MojoResult rv = MOJO_RESULT_OK; |
| 479 if (!dispatcher) | 550 std::vector<Dispatcher::DispatcherInTransit> dispatchers; |
| 480 return MOJO_RESULT_INVALID_ARGUMENT; | |
| 481 | 551 |
| 482 if (num_handles == 0) // Fast path: no handles. | 552 if (num_handles == 0) { // Fast path: no handles. |
| 483 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, 0, flags); | 553 rv = MessageForTransit::Create(&msg, num_bytes, nullptr, 0); |
| 554 if (rv != MOJO_RESULT_OK) |
| 555 return rv; |
| 556 } else { |
| 557 CHECK(handles); |
| 484 | 558 |
| 485 CHECK(handles); | 559 if (num_handles > kMaxHandlesPerMessage) |
| 560 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 486 | 561 |
| 487 if (num_handles > kMaxHandlesPerMessage) | 562 for (size_t i = 0; i < num_handles; ++i) { |
| 488 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 563 if (handles[i] == message_pipe_handle) |
| 564 return MOJO_RESULT_BUSY; |
| 565 } |
| 489 | 566 |
| 490 for (size_t i = 0; i < num_handles; ++i) { | 567 { |
| 491 if (message_pipe_handle == handles[i]) | 568 base::AutoLock lock(handles_lock_); |
| 492 return MOJO_RESULT_BUSY; | 569 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers); |
| 570 if (rv != MOJO_RESULT_OK) { |
| 571 handles_.CancelTransit(dispatchers); |
| 572 return rv; |
| 573 } |
| 574 } |
| 575 DCHECK_EQ(num_handles, dispatchers.size()); |
| 576 |
| 577 rv = MessageForTransit::Create( |
| 578 &msg, num_bytes, dispatchers.data(), num_handles); |
| 493 } | 579 } |
| 494 | 580 |
| 495 std::vector<Dispatcher::DispatcherInTransit> dispatchers; | 581 std::unique_ptr<MessageForTransit> message(msg); |
| 496 { | 582 if (rv == MOJO_RESULT_OK) { |
| 497 base::AutoLock lock(handles_lock_); | 583 DCHECK(message); |
| 498 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers); | 584 if (num_bytes) |
| 499 if (rv != MOJO_RESULT_OK) { | 585 memcpy(message->mutable_bytes(), bytes, num_bytes); |
| 500 handles_.CancelTransit(dispatchers); | 586 |
| 501 return rv; | 587 rv = WriteMessageNew(message_pipe_handle, |
| 502 } | 588 reinterpret_cast<MojoMessageHandle>(message.release()), |
| 589 flags); |
| 503 } | 590 } |
| 504 DCHECK_EQ(num_handles, dispatchers.size()); | |
| 505 | 591 |
| 506 MojoResult rv = dispatcher->WriteMessage( | 592 if (num_handles) { |
| 507 bytes, num_bytes, dispatchers.data(), num_handles, flags); | |
| 508 | |
| 509 { | |
| 510 base::AutoLock lock(handles_lock_); | 593 base::AutoLock lock(handles_lock_); |
| 511 if (rv == MOJO_RESULT_OK) { | 594 if (rv == MOJO_RESULT_OK) { |
| 512 handles_.CompleteTransitAndClose(dispatchers); | 595 handles_.CompleteTransitAndClose(dispatchers); |
| 513 } else { | 596 } else { |
| 514 handles_.CancelTransit(dispatchers); | 597 handles_.CancelTransit(dispatchers); |
| 515 } | 598 } |
| 516 } | 599 } |
| 517 | 600 |
| 518 return rv; | 601 return rv; |
| 519 } | 602 } |
| 520 | 603 |
| 604 MojoResult Core::WriteMessageNew(MojoHandle message_pipe_handle, |
| 605 MojoMessageHandle message, |
| 606 MojoWriteMessageFlags flags) { |
| 607 RequestContext request_context; |
| 608 std::unique_ptr<MessageForTransit> message_for_transit( |
| 609 reinterpret_cast<MessageForTransit*>(message)); |
| 610 auto dispatcher = GetDispatcher(message_pipe_handle); |
| 611 if (!dispatcher) |
| 612 return MOJO_RESULT_INVALID_ARGUMENT; |
| 613 |
| 614 return dispatcher->WriteMessage(std::move(message_for_transit), flags); |
| 615 } |
| 616 |
| 521 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, | 617 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, |
| 522 void* bytes, | 618 void* bytes, |
| 523 uint32_t* num_bytes, | 619 uint32_t* num_bytes, |
| 524 MojoHandle* handles, | 620 MojoHandle* handles, |
| 525 uint32_t* num_handles, | 621 uint32_t* num_handles, |
| 526 MojoReadMessageFlags flags) { | 622 MojoReadMessageFlags flags) { |
| 527 RequestContext request_context; | |
| 528 CHECK((!num_handles || !*num_handles || handles) && | 623 CHECK((!num_handles || !*num_handles || handles) && |
| 529 (!num_bytes || !*num_bytes || bytes)); | 624 (!num_bytes || !*num_bytes || bytes)); |
| 625 RequestContext request_context; |
| 530 auto dispatcher = GetDispatcher(message_pipe_handle); | 626 auto dispatcher = GetDispatcher(message_pipe_handle); |
| 531 if (!dispatcher) | 627 if (!dispatcher) |
| 532 return MOJO_RESULT_INVALID_ARGUMENT; | 628 return MOJO_RESULT_INVALID_ARGUMENT; |
| 533 return dispatcher->ReadMessage(bytes, num_bytes, handles, num_handles, flags); | 629 std::unique_ptr<MessageForTransit> message; |
| 630 MojoResult rv = |
| 631 dispatcher->ReadMessage(&message, num_bytes, handles, num_handles, flags, |
| 632 false /* ignore_num_bytes */); |
| 633 if (rv != MOJO_RESULT_OK) |
| 634 return rv; |
| 635 |
| 636 if (message && message->num_bytes()) |
| 637 memcpy(bytes, message->bytes(), message->num_bytes()); |
| 638 |
| 639 return MOJO_RESULT_OK; |
| 640 } |
| 641 |
| 642 MojoResult Core::ReadMessageNew(MojoHandle message_pipe_handle, |
| 643 MojoMessageHandle* message, |
| 644 uint32_t* num_bytes, |
| 645 MojoHandle* handles, |
| 646 uint32_t* num_handles, |
| 647 MojoReadMessageFlags flags) { |
| 648 CHECK(message); |
| 649 CHECK(!num_handles || !*num_handles || handles); |
| 650 RequestContext request_context; |
| 651 auto dispatcher = GetDispatcher(message_pipe_handle); |
| 652 if (!dispatcher) |
| 653 return MOJO_RESULT_INVALID_ARGUMENT; |
| 654 std::unique_ptr<MessageForTransit> msg; |
| 655 MojoResult rv = |
| 656 dispatcher->ReadMessage(&msg, num_bytes, handles, num_handles, flags, |
| 657 true /* ignore_num_bytes */); |
| 658 if (rv != MOJO_RESULT_OK) |
| 659 return rv; |
| 660 *message = reinterpret_cast<MojoMessageHandle>(msg.release()); |
| 661 return MOJO_RESULT_OK; |
| 534 } | 662 } |
| 535 | 663 |
| 536 MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) { | 664 MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) { |
| 537 RequestContext request_context; | 665 RequestContext request_context; |
| 538 scoped_refptr<Dispatcher> dispatcher0; | 666 scoped_refptr<Dispatcher> dispatcher0; |
| 539 scoped_refptr<Dispatcher> dispatcher1; | 667 scoped_refptr<Dispatcher> dispatcher1; |
| 540 | 668 |
| 541 bool valid_handles = true; | 669 bool valid_handles = true; |
| 542 { | 670 { |
| 543 base::AutoLock lock(handles_lock_); | 671 base::AutoLock lock(handles_lock_); |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 scoped_ptr<NodeController> node_controller) { | 993 scoped_ptr<NodeController> node_controller) { |
| 866 // It's OK to leak this reference. At this point we know the IO loop is still | 994 // It's OK to leak this reference. At this point we know the IO loop is still |
| 867 // running, and we know the NodeController will observe its eventual | 995 // running, and we know the NodeController will observe its eventual |
| 868 // destruction. This tells the NodeController to delete itself when that | 996 // destruction. This tells the NodeController to delete itself when that |
| 869 // happens. | 997 // happens. |
| 870 node_controller.release()->DestroyOnIOThreadShutdown(); | 998 node_controller.release()->DestroyOnIOThreadShutdown(); |
| 871 } | 999 } |
| 872 | 1000 |
| 873 } // namespace edk | 1001 } // namespace edk |
| 874 } // namespace mojo | 1002 } // namespace mojo |
| OLD | NEW |