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 |