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