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) { |