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

Unified Diff: mojo/edk/system/channel.cc

Issue 1759033002: Re-land: [mojo-edk] Serialise windows handles into an "extra header" section. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: mojo/edk/system/channel.cc
diff --git a/mojo/edk/system/channel.cc b/mojo/edk/system/channel.cc
index 2d6142e3a6abc4d1741e2d0b491b6893b8b5b813..375d65ba715298a1d64e3fb31b9d4991196b681e 100644
--- a/mojo/edk/system/channel.cc
+++ b/mojo/edk/system/channel.cc
@@ -21,21 +21,40 @@ namespace {
static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0,
"Invalid Header size.");
+#if defined(OS_CHROMEOS)
+static_assert(sizeof(Channel::Message::Header) == 8,
+ "Header must be 8 bytes on ChromeOS");
+#endif
+
} // namespace
const size_t kReadBufferSize = 4096;
const size_t kMaxUnusedReadBufferCapacity = 256 * 1024;
const size_t kMaxChannelMessageSize = 256 * 1024 * 1024;
+const size_t kMaxAttachedHandles = 128;
Channel::Message::Message(size_t payload_size,
- size_t num_handles,
- Header::MessageType message_type) {
- size_ = payload_size + sizeof(Header);
+ size_t max_handles,
+ Header::MessageType message_type)
+ : max_handles_(max_handles) {
+ DCHECK_LE(max_handles_, kMaxAttachedHandles);
+
+ size_t extra_header_size = 0;
#if defined(OS_WIN)
- // On Windows we serialize platform handles directly into the message buffer.
- size_ += num_handles * sizeof(PlatformHandle);
+ // On Windows we serialize platform handles into the extra header space.
+ extra_header_size = max_handles_ * sizeof(PlatformHandle);
+#endif
+ // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes.
+ if (extra_header_size % kChannelMessageAlignment) {
+ extra_header_size += kChannelMessageAlignment -
+ (extra_header_size % kChannelMessageAlignment);
+ }
+ DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment);
+#if defined(OS_CHROMEOS)
+ DCHECK_EQ(0u, extra_header_size);
#endif
+ size_ = sizeof(Header) + extra_header_size + payload_size;
data_ = static_cast<char*>(base::AlignedAlloc(size_,
kChannelMessageAlignment));
memset(data_, 0, size_);
@@ -44,17 +63,21 @@ Channel::Message::Message(size_t payload_size,
DCHECK_LE(size_, std::numeric_limits<uint32_t>::max());
header_->num_bytes = static_cast<uint32_t>(size_);
- DCHECK_LE(num_handles, std::numeric_limits<uint16_t>::max());
- header_->num_handles = static_cast<uint16_t>(num_handles);
-
+ DCHECK_LE(sizeof(Header) + extra_header_size,
+ std::numeric_limits<uint16_t>::max());
header_->message_type = message_type;
+#if defined(OS_CHROMEOS)
+ header_->num_handles = static_cast<uint16_t>(max_handles);
+#else
+ header_->num_header_bytes =
+ static_cast<uint16_t>(sizeof(Header) + extra_header_size);
+#endif
#if defined(OS_WIN)
- if (num_handles > 0) {
- handles_ = reinterpret_cast<PlatformHandle*>(
- data_ + sizeof(Header) + payload_size);
+ if (max_handles_ > 0) {
+ handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header());
// Initialize all handles to invalid values.
- for (size_t i = 0; i < header_->num_handles; ++i)
+ for (size_t i = 0; i < max_handles_; ++i)
handles()[i] = PlatformHandle();
}
#endif
@@ -76,7 +99,8 @@ Channel::MessagePtr Channel::Message::Deserialize(const void* data,
// We only serialize messages into other messages when performing message
// relay on Windows.
NOTREACHED();
-#endif
+ return nullptr;
+#else
if (data_num_bytes < sizeof(Header))
return nullptr;
@@ -87,63 +111,107 @@ Channel::MessagePtr Channel::Message::Deserialize(const void* data,
return nullptr;
}
- uint32_t handles_size = header->num_handles * sizeof(PlatformHandle);
- if (data_num_bytes < sizeof(Header) + handles_size) {
- DLOG(ERROR) << "Decoding invalid message:" << data_num_bytes
- << " < " << (sizeof(Header) + handles_size);
+ if (header->num_bytes < header->num_header_bytes) {
+ DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
+ << header->num_header_bytes;
return nullptr;
}
- DCHECK_LE(handles_size, data_num_bytes - sizeof(Header));
+ uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
+ uint32_t max_handles = extra_header_size / sizeof(PlatformHandle);
+ if (header->num_handles > max_handles) {
+ DLOG(ERROR) << "Decoding invalid message:" << header->num_handles << " > "
+ << max_handles;
+ return nullptr;
+ }
- MessagePtr message(new Message(data_num_bytes - sizeof(Header) - handles_size,
- header->num_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);
- // Copy all bytes, including the serialized handles.
+ // Copy all payload bytes.
memcpy(message->mutable_payload(),
+ static_cast<const char*>(data) + header->num_header_bytes,
+ data_num_bytes - header->num_header_bytes);
+ // Copy extra header bytes.
+ memcpy(message->mutable_extra_header(),
static_cast<const char*>(data) + sizeof(Header),
- data_num_bytes - sizeof(Header));
+ message->extra_header_size());
+ message->header_->num_handles = header->num_handles;
return message;
+#endif
}
size_t Channel::Message::payload_size() const {
-#if defined(OS_WIN)
- return size_ - sizeof(Header) -
- sizeof(PlatformHandle) * header_->num_handles;
-#else
+#if defined(OS_CHROMEOS)
return header_->num_bytes - sizeof(Header);
+#else
+ return size_ - header_->num_header_bytes;
#endif
}
PlatformHandle* Channel::Message::handles() {
+#if defined(OS_CHROMEOS)
+ // Old semantics for ChromeOS.
if (header_->num_handles == 0)
return nullptr;
+ CHECK(handle_vector_);
+ return handle_vector_->data();
+#else
+ if (max_handles_ == 0)
+ return nullptr;
#if defined(OS_WIN)
- return reinterpret_cast<PlatformHandle*>(static_cast<char*>(data_) +
- sizeof(Header) + payload_size());
+ return handles_;
#else
CHECK(handle_vector_);
return handle_vector_->data();
-#endif
+#endif // defined(OS_WIN)
+#endif // defined(OS_CHROMEOS)
+}
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+bool Channel::Message::has_mach_ports() const {
+ if (!has_handles())
+ return false;
+
+ for (const auto& handle : (*handle_vector_)) {
+ if (handle.type == PlatformHandle::Type::MACH)
+ return true;
+ }
+ return false;
}
+#endif
void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) {
+#if defined(OS_CHROMEOS)
+ // Old semantics for ChromeOS.
if (header_->num_handles == 0) {
CHECK(!new_handles || new_handles->size() == 0);
return;
}
-
CHECK(new_handles && new_handles->size() == header_->num_handles);
+ std::swap(handle_vector_, new_handles);
+
+#else
+ if (max_handles_ == 0) {
+ CHECK(!new_handles || new_handles->size() == 0);
+ return;
+ }
+
+ CHECK(new_handles && new_handles->size() <= max_handles_);
+ header_->num_handles = static_cast<uint16_t>(new_handles->size());
#if defined(OS_WIN)
memcpy(handles(), new_handles->data(),
- sizeof(PlatformHandle) * header_->num_handles);
+ sizeof(PlatformHandle) * new_handles->size());
new_handles->clear();
#else
std::swap(handle_vector_, new_handles);
-#endif
+#endif // defined(OS_WIN)
+#endif // defined(OS_CHROMEOS)
}
ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
@@ -329,14 +397,28 @@ bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) {
return true;
}
+#if defined(OS_CHROMEOS)
+ size_t extra_header_size = 0;
+ const void* extra_header = nullptr;
size_t payload_size = header->num_bytes - sizeof(Message::Header);
void* payload = payload_size ? const_cast<Message::Header*>(&header[1])
: nullptr;
+#else
+ size_t extra_header_size =
+ header->num_header_bytes - sizeof(Message::Header);
+ const void* extra_header = header + 1;
+ size_t payload_size = header->num_bytes - header->num_header_bytes;
+ void* payload =
+ payload_size ? reinterpret_cast<Message::Header*>(
+ const_cast<char*>(read_buffer_->occupied_bytes()) +
+ header->num_header_bytes)
+ : nullptr;
+#endif
ScopedPlatformHandleVectorPtr handles;
if (header->num_handles > 0) {
- handles = GetReadPlatformHandles(header->num_handles,
- &payload, &payload_size);
+ handles = GetReadPlatformHandles(header->num_handles, extra_header,
+ extra_header_size);
if (!handles) {
// Not enough handles available for this message.
break;

Powered by Google App Engine
This is Rietveld 408576698