Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: mojo/edk/system/core.cc

Issue 1880823005: [mojo-edk] Add explicit message object APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 } 351 }
351 352
352 MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) { 353 MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) {
353 RequestContext request_context; 354 RequestContext request_context;
354 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); 355 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle);
355 if (!dispatcher) 356 if (!dispatcher)
356 return MOJO_RESULT_INVALID_ARGUMENT; 357 return MOJO_RESULT_INVALID_ARGUMENT;
357 return dispatcher->CancelWatch(context); 358 return dispatcher->CancelWatch(context);
358 } 359 }
359 360
361 MojoResult Core::CreateMessage(uint32_t num_bytes,
362 const MojoHandle* handles,
363 uint32_t num_handles,
364 MojoCreateMessageFlags flags,
365 void** message) {
366 if (!message)
367 return MOJO_RESULT_INVALID_ARGUMENT;
368
369 if (num_handles == 0) { // Fast path: no handles.
370 MessageForTransit* msg;
371 MojoResult rv = MessageForTransit::Create(&msg, num_bytes, nullptr, 0);
372 if (rv != MOJO_RESULT_OK)
373 return rv;
374
375 *message = static_cast<void*>(msg);
376 return MOJO_RESULT_OK;
377 }
378
379 if (!handles)
380 return MOJO_RESULT_INVALID_ARGUMENT;
381
382 if (num_handles > kMaxHandlesPerMessage)
383 return MOJO_RESULT_RESOURCE_EXHAUSTED;
384
385 std::vector<Dispatcher::DispatcherInTransit> dispatchers;
386 {
387 base::AutoLock lock(handles_lock_);
388 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers);
389 if (rv != MOJO_RESULT_OK) {
390 handles_.CancelTransit(dispatchers);
391 return rv;
392 }
393 }
394 DCHECK_EQ(num_handles, dispatchers.size());
395
396 MessageForTransit* msg = nullptr;
397 MojoResult rv = MessageForTransit::Create(
398 &msg, num_bytes, dispatchers.data(), num_handles);
399
400 {
401 base::AutoLock lock(handles_lock_);
402 if (rv == MOJO_RESULT_OK) {
403 handles_.CompleteTransitAndClose(dispatchers);
404 *message = static_cast<void*>(msg);
405 } else {
406 handles_.CancelTransit(dispatchers);
407 }
408 }
409
410 return rv;
411 }
412
413 MojoResult Core::DestroyMessage(void* message_ptr) {
414 if (!message_ptr)
415 return MOJO_RESULT_INVALID_ARGUMENT;
416
417 MessageForTransit* message = static_cast<MessageForTransit*>(message_ptr);
418 delete message;
419
420 return MOJO_RESULT_OK;
421 }
422
423 MojoResult Core::GetMessageBuffer(void* message_ptr, void** buffer) {
424 if (!message_ptr)
425 return MOJO_RESULT_INVALID_ARGUMENT;
426
427 MessageForTransit* message = static_cast<MessageForTransit*>(message_ptr);
428 *buffer = message->mutable_bytes();
429 return MOJO_RESULT_OK;
430 }
431
360 MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) { 432 MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) {
361 RequestContext request_context; 433 RequestContext request_context;
362 if (!wait_set_handle) 434 if (!wait_set_handle)
363 return MOJO_RESULT_INVALID_ARGUMENT; 435 return MOJO_RESULT_INVALID_ARGUMENT;
364 436
365 scoped_refptr<WaitSetDispatcher> dispatcher = new WaitSetDispatcher(); 437 scoped_refptr<WaitSetDispatcher> dispatcher = new WaitSetDispatcher();
366 MojoHandle h = AddDispatcher(dispatcher); 438 MojoHandle h = AddDispatcher(dispatcher);
367 if (h == MOJO_HANDLE_INVALID) { 439 if (h == MOJO_HANDLE_INVALID) {
368 LOG(ERROR) << "Handle table full"; 440 LOG(ERROR) << "Handle table full";
369 dispatcher->Close(); 441 dispatcher->Close();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 537
466 return MOJO_RESULT_OK; 538 return MOJO_RESULT_OK;
467 } 539 }
468 540
469 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, 541 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle,
470 const void* bytes, 542 const void* bytes,
471 uint32_t num_bytes, 543 uint32_t num_bytes,
472 const MojoHandle* handles, 544 const MojoHandle* handles,
473 uint32_t num_handles, 545 uint32_t num_handles,
474 MojoWriteMessageFlags flags) { 546 MojoWriteMessageFlags flags) {
475 RequestContext request_context; 547 MessageForTransit* msg = nullptr;
476 auto dispatcher = GetDispatcher(message_pipe_handle); 548 MojoResult rv = MOJO_RESULT_OK;
477 if (!dispatcher) 549 std::vector<Dispatcher::DispatcherInTransit> dispatchers;
478 return MOJO_RESULT_INVALID_ARGUMENT;
479 550
480 if (num_handles == 0) // Fast path: no handles. 551 if (num_handles == 0) { // Fast path: no handles.
481 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, 0, flags); 552 rv = MessageForTransit::Create(&msg, num_bytes, nullptr, 0);
553 if (rv != MOJO_RESULT_OK)
554 return rv;
555 } else {
556 CHECK(handles);
482 557
483 CHECK(handles); 558 if (num_handles > kMaxHandlesPerMessage)
559 return MOJO_RESULT_RESOURCE_EXHAUSTED;
484 560
485 if (num_handles > kMaxHandlesPerMessage) 561 for (size_t i = 0; i < num_handles; ++i) {
486 return MOJO_RESULT_RESOURCE_EXHAUSTED; 562 if (handles[i] == message_pipe_handle)
563 return MOJO_RESULT_BUSY;
564 }
487 565
488 for (size_t i = 0; i < num_handles; ++i) { 566 {
489 if (message_pipe_handle == handles[i]) 567 base::AutoLock lock(handles_lock_);
490 return MOJO_RESULT_BUSY; 568 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers);
569 if (rv != MOJO_RESULT_OK) {
570 handles_.CancelTransit(dispatchers);
571 return rv;
572 }
573 }
574 DCHECK_EQ(num_handles, dispatchers.size());
575
576 rv = MessageForTransit::Create(
577 &msg, num_bytes, dispatchers.data(), num_handles);
491 } 578 }
492 579
493 std::vector<Dispatcher::DispatcherInTransit> dispatchers; 580 std::unique_ptr<MessageForTransit> message(msg);
494 { 581 if (rv == MOJO_RESULT_OK) {
495 base::AutoLock lock(handles_lock_); 582 DCHECK(message);
496 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers); 583 if (num_bytes)
497 if (rv != MOJO_RESULT_OK) { 584 memcpy(message->mutable_bytes(), bytes, num_bytes);
498 handles_.CancelTransit(dispatchers); 585
499 return rv; 586 rv = WriteMessageNew(
500 } 587 message_pipe_handle, static_cast<void*>(message.release()), flags);
501 } 588 }
502 DCHECK_EQ(num_handles, dispatchers.size());
503 589
504 MojoResult rv = dispatcher->WriteMessage( 590 if (num_handles) {
505 bytes, num_bytes, dispatchers.data(), num_handles, flags);
506
507 {
508 base::AutoLock lock(handles_lock_); 591 base::AutoLock lock(handles_lock_);
509 if (rv == MOJO_RESULT_OK) { 592 if (rv == MOJO_RESULT_OK) {
510 handles_.CompleteTransitAndClose(dispatchers); 593 handles_.CompleteTransitAndClose(dispatchers);
511 } else { 594 } else {
512 handles_.CancelTransit(dispatchers); 595 handles_.CancelTransit(dispatchers);
513 } 596 }
514 } 597 }
515 598
516 return rv; 599 return rv;
517 } 600 }
518 601
602 MojoResult Core::WriteMessageNew(MojoHandle message_pipe_handle,
603 void* message_ptr,
604 MojoWriteMessageFlags flags) {
605 RequestContext request_context;
606 std::unique_ptr<MessageForTransit> message(
607 static_cast<MessageForTransit*>(message_ptr));
608 auto dispatcher = GetDispatcher(message_pipe_handle);
609 if (!dispatcher)
610 return MOJO_RESULT_INVALID_ARGUMENT;
611
612 return dispatcher->WriteMessage(std::move(message), flags);
613 }
614
519 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, 615 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle,
520 void* bytes, 616 void* bytes,
521 uint32_t* num_bytes, 617 uint32_t* num_bytes,
522 MojoHandle* handles, 618 MojoHandle* handles,
523 uint32_t* num_handles, 619 uint32_t* num_handles,
524 MojoReadMessageFlags flags) { 620 MojoReadMessageFlags flags) {
525 RequestContext request_context;
526 CHECK((!num_handles || !*num_handles || handles) && 621 CHECK((!num_handles || !*num_handles || handles) &&
527 (!num_bytes || !*num_bytes || bytes)); 622 (!num_bytes || !*num_bytes || bytes));
623 RequestContext request_context;
528 auto dispatcher = GetDispatcher(message_pipe_handle); 624 auto dispatcher = GetDispatcher(message_pipe_handle);
529 if (!dispatcher) 625 if (!dispatcher)
530 return MOJO_RESULT_INVALID_ARGUMENT; 626 return MOJO_RESULT_INVALID_ARGUMENT;
531 return dispatcher->ReadMessage(bytes, num_bytes, handles, num_handles, flags); 627 std::unique_ptr<MessageForTransit> message;
628 MojoResult rv =
629 dispatcher->ReadMessage(&message, num_bytes, handles, num_handles, flags,
630 false /* ignore_num_bytes */);
631 if (rv != MOJO_RESULT_OK)
632 return rv;
633
634 if (message && message->num_bytes())
635 memcpy(bytes, message->bytes(), message->num_bytes());
636
637 return MOJO_RESULT_OK;
638 }
639
640 MojoResult Core::ReadMessageNew(MojoHandle message_pipe_handle,
641 void** message,
642 uint32_t* num_bytes,
643 MojoHandle* handles,
644 uint32_t* num_handles,
645 MojoReadMessageFlags flags) {
646 CHECK(message);
647 CHECK(!num_handles || !*num_handles || handles);
648 RequestContext request_context;
649 auto dispatcher = GetDispatcher(message_pipe_handle);
650 if (!dispatcher)
651 return MOJO_RESULT_INVALID_ARGUMENT;
652 std::unique_ptr<MessageForTransit> msg;
653 MojoResult rv =
654 dispatcher->ReadMessage(&msg, num_bytes, handles, num_handles, flags,
655 true /* ignore_num_bytes */);
656 if (rv != MOJO_RESULT_OK)
657 return rv;
658 *message = static_cast<void*>(msg.release());
659 return MOJO_RESULT_OK;
532 } 660 }
533 661
534 MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) { 662 MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) {
535 RequestContext request_context; 663 RequestContext request_context;
536 scoped_refptr<Dispatcher> dispatcher0; 664 scoped_refptr<Dispatcher> dispatcher0;
537 scoped_refptr<Dispatcher> dispatcher1; 665 scoped_refptr<Dispatcher> dispatcher1;
538 666
539 bool valid_handles = true; 667 bool valid_handles = true;
540 { 668 {
541 base::AutoLock lock(handles_lock_); 669 base::AutoLock lock(handles_lock_);
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 scoped_ptr<NodeController> node_controller) { 991 scoped_ptr<NodeController> node_controller) {
864 // It's OK to leak this reference. At this point we know the IO loop is still 992 // It's OK to leak this reference. At this point we know the IO loop is still
865 // running, and we know the NodeController will observe its eventual 993 // running, and we know the NodeController will observe its eventual
866 // destruction. This tells the NodeController to delete itself when that 994 // destruction. This tells the NodeController to delete itself when that
867 // happens. 995 // happens.
868 node_controller.release()->DestroyOnIOThreadShutdown(); 996 node_controller.release()->DestroyOnIOThreadShutdown();
869 } 997 }
870 998
871 } // namespace edk 999 } // namespace edk
872 } // namespace mojo 1000 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698