| Index: mojo/edk/system/core.cc
|
| diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
|
| index b3602d7c5f4a166aee775a7edf0f5daaef43187c..41b8eecf6df1035d16638cbc9d42a4a48ad81232 100644
|
| --- a/mojo/edk/system/core.cc
|
| +++ b/mojo/edk/system/core.cc
|
| @@ -27,6 +27,7 @@
|
| #include "mojo/edk/system/data_pipe_consumer_dispatcher.h"
|
| #include "mojo/edk/system/data_pipe_producer_dispatcher.h"
|
| #include "mojo/edk/system/handle_signals_state.h"
|
| +#include "mojo/edk/system/message_for_transit.h"
|
| #include "mojo/edk/system/message_pipe_dispatcher.h"
|
| #include "mojo/edk/system/platform_handle_dispatcher.h"
|
| #include "mojo/edk/system/ports/node.h"
|
| @@ -357,6 +358,77 @@ MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) {
|
| return dispatcher->CancelWatch(context);
|
| }
|
|
|
| +MojoResult Core::CreateMessage(uint32_t num_bytes,
|
| + const MojoHandle* handles,
|
| + uint32_t num_handles,
|
| + MojoCreateMessageFlags flags,
|
| + void** message) {
|
| + if (!message)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + if (num_handles == 0) { // Fast path: no handles.
|
| + MessageForTransit* msg;
|
| + MojoResult rv = MessageForTransit::Create(&msg, num_bytes, nullptr, 0);
|
| + if (rv != MOJO_RESULT_OK)
|
| + return rv;
|
| +
|
| + *message = static_cast<void*>(msg);
|
| + return MOJO_RESULT_OK;
|
| + }
|
| +
|
| + if (!handles)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + if (num_handles > kMaxHandlesPerMessage)
|
| + return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
| +
|
| + std::vector<Dispatcher::DispatcherInTransit> dispatchers;
|
| + {
|
| + base::AutoLock lock(handles_lock_);
|
| + MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers);
|
| + if (rv != MOJO_RESULT_OK) {
|
| + handles_.CancelTransit(dispatchers);
|
| + return rv;
|
| + }
|
| + }
|
| + DCHECK_EQ(num_handles, dispatchers.size());
|
| +
|
| + MessageForTransit* msg = nullptr;
|
| + MojoResult rv = MessageForTransit::Create(
|
| + &msg, num_bytes, dispatchers.data(), num_handles);
|
| +
|
| + {
|
| + base::AutoLock lock(handles_lock_);
|
| + if (rv == MOJO_RESULT_OK) {
|
| + handles_.CompleteTransitAndClose(dispatchers);
|
| + *message = static_cast<void*>(msg);
|
| + } else {
|
| + handles_.CancelTransit(dispatchers);
|
| + }
|
| + }
|
| +
|
| + return rv;
|
| +}
|
| +
|
| +MojoResult Core::DestroyMessage(void* message_ptr) {
|
| + if (!message_ptr)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + MessageForTransit* message = static_cast<MessageForTransit*>(message_ptr);
|
| + delete message;
|
| +
|
| + return MOJO_RESULT_OK;
|
| +}
|
| +
|
| +MojoResult Core::GetMessageBuffer(void* message_ptr, void** buffer) {
|
| + if (!message_ptr)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + MessageForTransit* message = static_cast<MessageForTransit*>(message_ptr);
|
| + *buffer = message->mutable_bytes();
|
| + return MOJO_RESULT_OK;
|
| +}
|
| +
|
| MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) {
|
| RequestContext request_context;
|
| if (!wait_set_handle)
|
| @@ -472,39 +544,50 @@ MojoResult Core::WriteMessage(MojoHandle message_pipe_handle,
|
| const MojoHandle* handles,
|
| uint32_t num_handles,
|
| MojoWriteMessageFlags flags) {
|
| - RequestContext request_context;
|
| - auto dispatcher = GetDispatcher(message_pipe_handle);
|
| - if (!dispatcher)
|
| - return MOJO_RESULT_INVALID_ARGUMENT;
|
| -
|
| - if (num_handles == 0) // Fast path: no handles.
|
| - return dispatcher->WriteMessage(bytes, num_bytes, nullptr, 0, flags);
|
| + MessageForTransit* msg = nullptr;
|
| + MojoResult rv = MOJO_RESULT_OK;
|
| + std::vector<Dispatcher::DispatcherInTransit> dispatchers;
|
|
|
| - CHECK(handles);
|
| + if (num_handles == 0) { // Fast path: no handles.
|
| + rv = MessageForTransit::Create(&msg, num_bytes, nullptr, 0);
|
| + if (rv != MOJO_RESULT_OK)
|
| + return rv;
|
| + } else {
|
| + CHECK(handles);
|
|
|
| - if (num_handles > kMaxHandlesPerMessage)
|
| - return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
| + if (num_handles > kMaxHandlesPerMessage)
|
| + return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
|
|
| - for (size_t i = 0; i < num_handles; ++i) {
|
| - if (message_pipe_handle == handles[i])
|
| - return MOJO_RESULT_BUSY;
|
| - }
|
| + for (size_t i = 0; i < num_handles; ++i) {
|
| + if (handles[i] == message_pipe_handle)
|
| + return MOJO_RESULT_BUSY;
|
| + }
|
|
|
| - std::vector<Dispatcher::DispatcherInTransit> dispatchers;
|
| - {
|
| - base::AutoLock lock(handles_lock_);
|
| - MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers);
|
| - if (rv != MOJO_RESULT_OK) {
|
| - handles_.CancelTransit(dispatchers);
|
| - return rv;
|
| + {
|
| + base::AutoLock lock(handles_lock_);
|
| + MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers);
|
| + if (rv != MOJO_RESULT_OK) {
|
| + handles_.CancelTransit(dispatchers);
|
| + return rv;
|
| + }
|
| }
|
| + DCHECK_EQ(num_handles, dispatchers.size());
|
| +
|
| + rv = MessageForTransit::Create(
|
| + &msg, num_bytes, dispatchers.data(), num_handles);
|
| }
|
| - DCHECK_EQ(num_handles, dispatchers.size());
|
|
|
| - MojoResult rv = dispatcher->WriteMessage(
|
| - bytes, num_bytes, dispatchers.data(), num_handles, flags);
|
| + std::unique_ptr<MessageForTransit> message(msg);
|
| + if (rv == MOJO_RESULT_OK) {
|
| + DCHECK(message);
|
| + if (num_bytes)
|
| + memcpy(message->mutable_bytes(), bytes, num_bytes);
|
|
|
| - {
|
| + rv = WriteMessageNew(
|
| + message_pipe_handle, static_cast<void*>(message.release()), flags);
|
| + }
|
| +
|
| + if (num_handles) {
|
| base::AutoLock lock(handles_lock_);
|
| if (rv == MOJO_RESULT_OK) {
|
| handles_.CompleteTransitAndClose(dispatchers);
|
| @@ -516,19 +599,64 @@ MojoResult Core::WriteMessage(MojoHandle message_pipe_handle,
|
| return rv;
|
| }
|
|
|
| +MojoResult Core::WriteMessageNew(MojoHandle message_pipe_handle,
|
| + void* message_ptr,
|
| + MojoWriteMessageFlags flags) {
|
| + RequestContext request_context;
|
| + std::unique_ptr<MessageForTransit> message(
|
| + static_cast<MessageForTransit*>(message_ptr));
|
| + auto dispatcher = GetDispatcher(message_pipe_handle);
|
| + if (!dispatcher)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + return dispatcher->WriteMessage(std::move(message), flags);
|
| +}
|
| +
|
| MojoResult Core::ReadMessage(MojoHandle message_pipe_handle,
|
| void* bytes,
|
| uint32_t* num_bytes,
|
| MojoHandle* handles,
|
| uint32_t* num_handles,
|
| MojoReadMessageFlags flags) {
|
| - RequestContext request_context;
|
| CHECK((!num_handles || !*num_handles || handles) &&
|
| (!num_bytes || !*num_bytes || bytes));
|
| + RequestContext request_context;
|
| auto dispatcher = GetDispatcher(message_pipe_handle);
|
| if (!dispatcher)
|
| return MOJO_RESULT_INVALID_ARGUMENT;
|
| - return dispatcher->ReadMessage(bytes, num_bytes, handles, num_handles, flags);
|
| + std::unique_ptr<MessageForTransit> message;
|
| + MojoResult rv =
|
| + dispatcher->ReadMessage(&message, num_bytes, handles, num_handles, flags,
|
| + false /* ignore_num_bytes */);
|
| + if (rv != MOJO_RESULT_OK)
|
| + return rv;
|
| +
|
| + if (message && message->num_bytes())
|
| + memcpy(bytes, message->bytes(), message->num_bytes());
|
| +
|
| + return MOJO_RESULT_OK;
|
| +}
|
| +
|
| +MojoResult Core::ReadMessageNew(MojoHandle message_pipe_handle,
|
| + void** message,
|
| + uint32_t* num_bytes,
|
| + MojoHandle* handles,
|
| + uint32_t* num_handles,
|
| + MojoReadMessageFlags flags) {
|
| + CHECK(message);
|
| + CHECK(!num_handles || !*num_handles || handles);
|
| + RequestContext request_context;
|
| + auto dispatcher = GetDispatcher(message_pipe_handle);
|
| + if (!dispatcher)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| + std::unique_ptr<MessageForTransit> msg;
|
| + MojoResult rv =
|
| + dispatcher->ReadMessage(&msg, num_bytes, handles, num_handles, flags,
|
| + true /* ignore_num_bytes */);
|
| + if (rv != MOJO_RESULT_OK)
|
| + return rv;
|
| + *message = static_cast<void*>(msg.release());
|
| + return MOJO_RESULT_OK;
|
| }
|
|
|
| MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) {
|
|
|