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

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: make VS happy 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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698