Index: mojo/edk/system/channel.cc |
diff --git a/mojo/edk/system/channel.cc b/mojo/edk/system/channel.cc |
index 375d65ba715298a1d64e3fb31b9d4991196b681e..53df40c550b315d7f0e690069ba1d39e3106bacf 100644 |
--- a/mojo/edk/system/channel.cc |
+++ b/mojo/edk/system/channel.cc |
@@ -8,11 +8,16 @@ |
#include <algorithm> |
#include <limits> |
+#include <utility> |
#include "base/macros.h" |
#include "base/memory/aligned_memory.h" |
#include "mojo/edk/embedder/platform_handle.h" |
+#if defined(OS_MACOSX) |
erikchen
2016/03/09 19:13:17
it seems you're inconsistent on whether to include
Anand Mistry (off Chromium)
2016/03/11 07:44:17
Oops. I thought I standardised these. I'll take an
|
+#include "base/mac/mach_logging.h" |
+#endif |
+ |
namespace mojo { |
namespace edk { |
@@ -43,6 +48,12 @@ Channel::Message::Message(size_t payload_size, |
#if defined(OS_WIN) |
// On Windows we serialize platform handles into the extra header space. |
extra_header_size = max_handles_ * sizeof(PlatformHandle); |
+#elif defined(OS_MACOSX) |
+ // On OSX, some of the platform handles may be mach ports, which are |
+ // serialised into the message buffer. Since there could be a mix of fds and |
+ // mach ports, we store the mach ports as an <index, port> pair (of uint32_t), |
+ // so that the original ordering of handles can be re-created. |
+ extra_header_size = max_handles * sizeof(MachPortsEntry); |
#endif |
// Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. |
if (extra_header_size % kChannelMessageAlignment) { |
@@ -73,14 +84,19 @@ Channel::Message::Message(size_t payload_size, |
static_cast<uint16_t>(sizeof(Header) + extra_header_size); |
#endif |
-#if defined(OS_WIN) |
if (max_handles_ > 0) { |
+#if defined(OS_WIN) |
handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header()); |
// Initialize all handles to invalid values. |
for (size_t i = 0; i < max_handles_; ++i) |
handles()[i] = PlatformHandle(); |
- } |
+#elif defined(OS_MACOSX) && !defined(OS_IOS) |
+ mach_ports_ = reinterpret_cast<MachPortsEntry*>(mutable_extra_header()); |
+ // Initialize all handles to invalid values. |
+ for (size_t i = 0; i < max_handles_; ++i) |
+ mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)}; |
#endif |
+ } |
} |
Channel::Message::~Message() { |
@@ -95,9 +111,9 @@ Channel::Message::~Message() { |
// static |
Channel::MessagePtr Channel::Message::Deserialize(const void* data, |
size_t data_num_bytes) { |
-#if !defined(OS_WIN) |
+#if !defined(OS_WIN) && (!defined(OS_MACOSX) || defined(OS_IOS)) |
erikchen
2016/03/09 19:13:17
could you rewrite as !(defined(OS_MACOSX) && !defi
Anand Mistry (off Chromium)
2016/03/11 07:44:17
Done.
|
// We only serialize messages into other messages when performing message |
- // relay on Windows. |
+ // relay on Windows and OSX. |
NOTREACHED(); |
return nullptr; |
#else |
@@ -118,16 +134,19 @@ Channel::MessagePtr Channel::Message::Deserialize(const void* data, |
} |
uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); |
+#if defined(OS_WIN) |
uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); |
+#elif defined(OS_MACOSX) |
+ uint32_t max_handles = extra_header_size / sizeof(MachPortsEntry); |
+#endif |
if (header->num_handles > max_handles) { |
- DLOG(ERROR) << "Decoding invalid message:" << header->num_handles << " > " |
- << max_handles; |
+ DLOG(ERROR) << "Decoding invalid message:" << header->num_handles |
+ << " > " << max_handles; |
return nullptr; |
} |
- MessagePtr message( |
- new Message(data_num_bytes - header->num_header_bytes, max_handles)); |
- |
+ MessagePtr message(new Message(data_num_bytes - header->num_header_bytes, |
+ max_handles)); |
DCHECK_EQ(message->data_num_bytes(), data_num_bytes); |
DCHECK_EQ(message->extra_header_size(), extra_header_size); |
DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); |
@@ -212,6 +231,20 @@ void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) { |
std::swap(handle_vector_, new_handles); |
#endif // defined(OS_WIN) |
#endif // defined(OS_CHROMEOS) |
+ |
+#if defined(OS_MACOSX) && !defined(OS_IOS) |
+ size_t mach_port_index = 0; |
+ for (size_t i = 0; i < max_handles_; ++i) |
+ mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)}; |
+ for (size_t i = 0; i < handle_vector_->size(); i++) { |
+ if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH) { |
+ mach_port_t port = (*handle_vector_)[i].port; |
+ mach_ports_[mach_port_index].index = i; |
+ mach_ports_[mach_port_index].mach_port = port; |
+ mach_port_index++; |
+ } |
+ } |
+#endif |
} |
ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { |
@@ -222,7 +255,35 @@ ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { |
new PlatformHandleVector(header_->num_handles)); |
for (size_t i = 0; i < header_->num_handles; ++i) |
std::swap(moved_handles->at(i), handles()[i]); |
+ header_->num_handles = 0; |
return moved_handles; |
+#elif defined(OS_MACOSX) && !defined(OS_IOS) |
+ for (size_t i = 0; i < max_handles_; ++i) |
+ mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)}; |
+ header_->num_handles = 0; |
+ return std::move(handle_vector_); |
+#else |
+ header_->num_handles = 0; |
+ return std::move(handle_vector_); |
+#endif |
+} |
+ |
+ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() { |
+#if defined(OS_WIN) |
+ // Not necessary on Windows. |
+ NOTREACHED(); |
+ return nullptr; |
+#elif defined(OS_MACOSX) && !defined(OS_IOS) |
+ if (handle_vector_) { |
+ for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) { |
+ if (it->type == PlatformHandle::Type::MACH) { |
+ it = handle_vector_->erase(it); |
+ } else { |
+ ++it; |
+ } |
+ } |
+ } |
+ return std::move(handle_vector_); |
#else |
return std::move(handle_vector_); |
#endif |