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 |