| Index: mojo/edk/system/core.cc
|
| diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
|
| index a3a5823f7463e94745964ac7ad690f4a8849bf3c..77e7bc46cacf53f50957832a61822eb1c18b0fac 100644
|
| --- a/mojo/edk/system/core.cc
|
| +++ b/mojo/edk/system/core.cc
|
| @@ -28,6 +28,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"
|
| @@ -361,6 +362,76 @@ MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) {
|
| return dispatcher->CancelWatch(context);
|
| }
|
|
|
| +MojoResult Core::AllocMessage(uint32_t num_bytes,
|
| + const MojoHandle* handles,
|
| + uint32_t num_handles,
|
| + MojoAllocMessageFlags flags,
|
| + MojoMessageHandle* message) {
|
| + if (!message)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + if (num_handles == 0) { // Fast path: no handles.
|
| + std::unique_ptr<MessageForTransit> msg;
|
| + MojoResult rv = MessageForTransit::Create(&msg, num_bytes, nullptr, 0);
|
| + if (rv != MOJO_RESULT_OK)
|
| + return rv;
|
| +
|
| + *message = reinterpret_cast<MojoMessageHandle>(msg.release());
|
| + 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());
|
| +
|
| + std::unique_ptr<MessageForTransit> msg;
|
| + 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 = reinterpret_cast<MojoMessageHandle>(msg.release());
|
| + } else {
|
| + handles_.CancelTransit(dispatchers);
|
| + }
|
| + }
|
| +
|
| + return rv;
|
| +}
|
| +
|
| +MojoResult Core::FreeMessage(MojoMessageHandle message) {
|
| + if (!message)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + delete reinterpret_cast<MessageForTransit*>(message);
|
| +
|
| + return MOJO_RESULT_OK;
|
| +}
|
| +
|
| +MojoResult Core::GetMessageBuffer(MojoMessageHandle message, void** buffer) {
|
| + if (!message)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + *buffer = reinterpret_cast<MessageForTransit*>(message)->mutable_bytes();
|
| +
|
| + return MOJO_RESULT_OK;
|
| +}
|
| +
|
| MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) {
|
| RequestContext request_context;
|
| if (!wait_set_handle)
|
| @@ -476,48 +547,36 @@ 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)
|
| + if (num_bytes && !bytes)
|
| return MOJO_RESULT_INVALID_ARGUMENT;
|
|
|
| - if (num_handles == 0) // Fast path: no handles.
|
| - return dispatcher->WriteMessage(bytes, num_bytes, nullptr, 0, flags);
|
| -
|
| - CHECK(handles);
|
| -
|
| - 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;
|
| - }
|
| -
|
| - 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;
|
| - }
|
| + MojoMessageHandle message;
|
| + MojoResult rv = AllocMessage(num_bytes, handles, num_handles,
|
| + MOJO_ALLOC_MESSAGE_FLAG_NONE, &message);
|
| + if (rv != MOJO_RESULT_OK)
|
| + return rv;
|
| +
|
| + if (num_bytes) {
|
| + void* buffer = nullptr;
|
| + rv = GetMessageBuffer(message, &buffer);
|
| + DCHECK_EQ(rv, MOJO_RESULT_OK);
|
| + memcpy(buffer, bytes, num_bytes);
|
| }
|
| - DCHECK_EQ(num_handles, dispatchers.size());
|
|
|
| - MojoResult rv = dispatcher->WriteMessage(
|
| - bytes, num_bytes, dispatchers.data(), num_handles, flags);
|
| + return WriteMessageNew(message_pipe_handle, message, flags);
|
| +}
|
|
|
| - {
|
| - base::AutoLock lock(handles_lock_);
|
| - if (rv == MOJO_RESULT_OK) {
|
| - handles_.CompleteTransitAndClose(dispatchers);
|
| - } else {
|
| - handles_.CancelTransit(dispatchers);
|
| - }
|
| - }
|
| +MojoResult Core::WriteMessageNew(MojoHandle message_pipe_handle,
|
| + MojoMessageHandle message,
|
| + MojoWriteMessageFlags flags) {
|
| + RequestContext request_context;
|
| + std::unique_ptr<MessageForTransit> message_for_transit(
|
| + reinterpret_cast<MessageForTransit*>(message));
|
| + auto dispatcher = GetDispatcher(message_pipe_handle);
|
| + if (!dispatcher)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
|
|
| - return rv;
|
| + return dispatcher->WriteMessage(std::move(message_for_transit), flags);
|
| }
|
|
|
| MojoResult Core::ReadMessage(MojoHandle message_pipe_handle,
|
| @@ -526,13 +585,45 @@ MojoResult Core::ReadMessage(MojoHandle message_pipe_handle,
|
| 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;
|
| + 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,
|
| + MojoMessageHandle* 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;
|
| - return dispatcher->ReadMessage(bytes, num_bytes, handles, num_handles, flags);
|
| + 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 = reinterpret_cast<MojoMessageHandle>(msg.release());
|
| + return MOJO_RESULT_OK;
|
| }
|
|
|
| MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) {
|
|
|