| Index: mojo/edk/system/channel.cc
|
| diff --git a/mojo/edk/system/channel.cc b/mojo/edk/system/channel.cc
|
| index 1621bbfe15da813d2bdcd82c8affd0a46a78fdde..8a44d36024e2346b3eab90a48f1eb77a35adcd63 100644
|
| --- a/mojo/edk/system/channel.cc
|
| +++ b/mojo/edk/system/channel.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "mojo/edk/system/channel.h"
|
|
|
| +#include <stddef.h>
|
| #include <string.h>
|
|
|
| #include <algorithm>
|
| @@ -26,13 +27,23 @@ namespace edk {
|
|
|
| namespace {
|
|
|
| -static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0,
|
| - "Invalid Header size.");
|
| +static_assert(
|
| + IsAlignedForChannelMessage(sizeof(Channel::Message::LegacyHeader)),
|
| + "Invalid LegacyHeader size.");
|
|
|
| -#if defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| -static_assert(sizeof(Channel::Message::Header) == 8,
|
| - "Header must be 8 bytes on ChromeOS and Android");
|
| -#endif
|
| +static_assert(IsAlignedForChannelMessage(sizeof(Channel::Message::Header)),
|
| + "Invalid Header size.");
|
| +
|
| +static_assert(sizeof(Channel::Message::LegacyHeader) == 8,
|
| + "LegacyHeader must be 8 bytes on ChromeOS and Android");
|
| +
|
| +static_assert(offsetof(Channel::Message::LegacyHeader, num_bytes) ==
|
| + offsetof(Channel::Message::Header, num_bytes),
|
| + "num_bytes should be at the same offset in both Header structs.");
|
| +static_assert(offsetof(Channel::Message::LegacyHeader, message_type) ==
|
| + offsetof(Channel::Message::Header, message_type),
|
| + "message_type should be at the same offset in both Header "
|
| + "structs.");
|
|
|
| } // namespace
|
|
|
| @@ -41,12 +52,22 @@ const size_t kMaxUnusedReadBufferCapacity = 4096;
|
| const size_t kMaxChannelMessageSize = 256 * 1024 * 1024;
|
| const size_t kMaxAttachedHandles = 128;
|
|
|
| +Channel::Message::Message(size_t payload_size, size_t max_handles)
|
| +#if defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| + : Message(payload_size, max_handles, MessageType::NORMAL_LEGACY) {
|
| +}
|
| +#else
|
| + : Message(payload_size, max_handles, MessageType::NORMAL) {
|
| +}
|
| +#endif
|
| +
|
| Channel::Message::Message(size_t payload_size,
|
| size_t max_handles,
|
| - Header::MessageType message_type)
|
| + MessageType message_type)
|
| : max_handles_(max_handles) {
|
| DCHECK_LE(max_handles_, kMaxAttachedHandles);
|
|
|
| + const bool is_legacy_message = (message_type == MessageType::NORMAL_LEGACY);
|
| size_t extra_header_size = 0;
|
| #if defined(OS_WIN)
|
| // On Windows we serialize HANDLEs into the extra header space.
|
| @@ -62,16 +83,16 @@ Channel::Message::Message(size_t payload_size,
|
| }
|
| #endif
|
| // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes.
|
| - if (extra_header_size % kChannelMessageAlignment) {
|
| + if (!IsAlignedForChannelMessage(extra_header_size)) {
|
| extra_header_size += kChannelMessageAlignment -
|
| (extra_header_size % kChannelMessageAlignment);
|
| }
|
| - DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment);
|
| -#if defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| - DCHECK_EQ(0u, extra_header_size);
|
| -#endif
|
| + DCHECK(IsAlignedForChannelMessage(extra_header_size));
|
| + const size_t header_size =
|
| + is_legacy_message ? sizeof(LegacyHeader) : sizeof(Header);
|
| + DCHECK(extra_header_size == 0 || !is_legacy_message);
|
|
|
| - size_ = sizeof(Header) + extra_header_size + payload_size;
|
| + size_ = header_size + extra_header_size + payload_size;
|
| data_ = static_cast<char*>(base::AlignedAlloc(size_,
|
| kChannelMessageAlignment));
|
| // Only zero out the header and not the payload. Since the payload is going to
|
| @@ -79,21 +100,21 @@ Channel::Message::Message(size_t payload_size,
|
| // performance issue when dealing with large messages. Any sanitizer errors
|
| // complaining about an uninitialized read in the payload area should be
|
| // treated as an error and fixed.
|
| - memset(data_, 0, sizeof(Header) + extra_header_size);
|
| - header_ = reinterpret_cast<Header*>(data_);
|
| + memset(data_, 0, header_size + extra_header_size);
|
|
|
| DCHECK_LE(size_, std::numeric_limits<uint32_t>::max());
|
| - header_->num_bytes = static_cast<uint32_t>(size_);
|
| + legacy_header()->num_bytes = static_cast<uint32_t>(size_);
|
|
|
| - DCHECK_LE(sizeof(Header) + extra_header_size,
|
| + DCHECK_LE(header_size + extra_header_size,
|
| std::numeric_limits<uint16_t>::max());
|
| - header_->message_type = message_type;
|
| -#if defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| - header_->num_handles = static_cast<uint16_t>(max_handles);
|
| -#else
|
| - header_->num_header_bytes =
|
| - static_cast<uint16_t>(sizeof(Header) + extra_header_size);
|
| -#endif
|
| + legacy_header()->message_type = message_type;
|
| +
|
| + if (is_legacy_message) {
|
| + legacy_header()->num_handles = static_cast<uint16_t>(max_handles);
|
| + } else {
|
| + header()->num_header_bytes =
|
| + static_cast<uint16_t>(header_size + extra_header_size);
|
| + }
|
|
|
| if (max_handles_ > 0) {
|
| #if defined(OS_WIN)
|
| @@ -121,77 +142,91 @@ Channel::Message::~Message() {
|
| // static
|
| Channel::MessagePtr Channel::Message::Deserialize(const void* data,
|
| size_t data_num_bytes) {
|
| - if (data_num_bytes < sizeof(Header))
|
| + if (data_num_bytes < sizeof(LegacyHeader))
|
| return nullptr;
|
|
|
| - const Header* header = reinterpret_cast<const Header*>(data);
|
| - if (header->num_bytes != data_num_bytes) {
|
| - DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes
|
| + const LegacyHeader* legacy_header =
|
| + reinterpret_cast<const LegacyHeader*>(data);
|
| + if (legacy_header->num_bytes != data_num_bytes) {
|
| + DLOG(ERROR) << "Decoding invalid message: " << legacy_header->num_bytes
|
| << " != " << data_num_bytes;
|
| return nullptr;
|
| }
|
|
|
| -#if defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| - size_t payload_size = data_num_bytes - sizeof(Header);
|
| - const char* payload = static_cast<const char*>(data) + sizeof(Header);
|
| -#else
|
| - if (header->num_bytes < header->num_header_bytes ||
|
| - header->num_header_bytes < sizeof(Header)) {
|
| - DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
|
| - << header->num_header_bytes;
|
| - return nullptr;
|
| + const Header* header = nullptr;
|
| + if (legacy_header->message_type == MessageType::NORMAL)
|
| + header = reinterpret_cast<const Header*>(data);
|
| +
|
| + uint32_t extra_header_size = 0;
|
| + size_t payload_size = 0;
|
| + const char* payload = nullptr;
|
| + if (!header) {
|
| + payload_size = data_num_bytes - sizeof(LegacyHeader);
|
| + payload = static_cast<const char*>(data) + sizeof(LegacyHeader);
|
| + } else {
|
| + if (header->num_bytes < header->num_header_bytes ||
|
| + header->num_header_bytes < sizeof(Header)) {
|
| + DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
|
| + << header->num_header_bytes;
|
| + return nullptr;
|
| + }
|
| + extra_header_size = header->num_header_bytes - sizeof(Header);
|
| + payload_size = data_num_bytes - header->num_header_bytes;
|
| + payload = static_cast<const char*>(data) + header->num_header_bytes;
|
| }
|
|
|
| - uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
|
| - size_t payload_size = data_num_bytes - header->num_header_bytes;
|
| - const char* payload =
|
| - static_cast<const char*>(data) + header->num_header_bytes;
|
| -#endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| -
|
| #if defined(OS_WIN)
|
| uint32_t max_handles = extra_header_size / sizeof(HandleEntry);
|
| #elif defined(OS_MACOSX) && !defined(OS_IOS)
|
| - if (extra_header_size < sizeof(MachPortsExtraHeader)) {
|
| + if (extra_header_size > 0 &&
|
| + extra_header_size < sizeof(MachPortsExtraHeader)) {
|
| DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < "
|
| << sizeof(MachPortsExtraHeader);
|
| return nullptr;
|
| }
|
| - uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) /
|
| - sizeof(MachPortsEntry);
|
| + uint32_t max_handles =
|
| + extra_header_size == 0
|
| + ? 0
|
| + : (extra_header_size - sizeof(MachPortsExtraHeader)) /
|
| + sizeof(MachPortsEntry);
|
| #else
|
| const uint32_t max_handles = 0;
|
| #endif // defined(OS_WIN)
|
|
|
| - if (header->num_handles > max_handles || max_handles > kMaxAttachedHandles) {
|
| - DLOG(ERROR) << "Decoding invalid message:" << header->num_handles
|
| - << " > " << max_handles;
|
| + const uint16_t num_handles =
|
| + header ? header->num_handles : legacy_header->num_handles;
|
| + if (num_handles > max_handles || max_handles > kMaxAttachedHandles) {
|
| + DLOG(ERROR) << "Decoding invalid message: " << num_handles << " > "
|
| + << max_handles;
|
| return nullptr;
|
| }
|
|
|
| - MessagePtr message(new Message(payload_size, max_handles));
|
| + MessagePtr message(
|
| + new Message(payload_size, max_handles, legacy_header->message_type));
|
| DCHECK_EQ(message->data_num_bytes(), data_num_bytes);
|
|
|
| // Copy all payload bytes.
|
| if (payload_size)
|
| memcpy(message->mutable_payload(), payload, payload_size);
|
|
|
| -#if !defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| - DCHECK_EQ(message->extra_header_size(), extra_header_size);
|
| - DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes);
|
| + if (header) {
|
| + DCHECK_EQ(message->extra_header_size(), extra_header_size);
|
| + DCHECK_EQ(message->header()->num_header_bytes, header->num_header_bytes);
|
|
|
| - if (message->extra_header_size()) {
|
| - // Copy extra header bytes.
|
| - memcpy(message->mutable_extra_header(),
|
| - static_cast<const char*>(data) + sizeof(Header),
|
| - message->extra_header_size());
|
| + if (message->extra_header_size()) {
|
| + // Copy extra header bytes.
|
| + memcpy(message->mutable_extra_header(),
|
| + static_cast<const char*>(data) + sizeof(Header),
|
| + message->extra_header_size());
|
| + }
|
| + message->header()->num_handles = header->num_handles;
|
| + } else {
|
| + message->legacy_header()->num_handles = legacy_header->num_handles;
|
| }
|
| -#endif
|
|
|
| - message->header_->num_handles = header->num_handles;
|
| #if defined(OS_WIN)
|
| - ScopedPlatformHandleVectorPtr handles(
|
| - new PlatformHandleVector(header->num_handles));
|
| - for (size_t i = 0; i < header->num_handles; i++) {
|
| + ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector(num_handles));
|
| + for (size_t i = 0; i < num_handles; i++) {
|
| (*handles)[i].handle =
|
| base::win::Uint32ToHandle(message->handles_[i].handle);
|
| }
|
| @@ -201,12 +236,46 @@ Channel::MessagePtr Channel::Message::Deserialize(const void* data,
|
| return message;
|
| }
|
|
|
| +const void* Channel::Message::extra_header() const {
|
| + DCHECK(!is_legacy_message());
|
| + return data_ + sizeof(Header);
|
| +}
|
| +
|
| +void* Channel::Message::mutable_extra_header() {
|
| + DCHECK(!is_legacy_message());
|
| + return data_ + sizeof(Header);
|
| +}
|
| +
|
| +size_t Channel::Message::extra_header_size() const {
|
| + return header()->num_header_bytes - sizeof(Header);
|
| +}
|
| +
|
| +void* Channel::Message::mutable_payload() {
|
| + if (is_legacy_message())
|
| + return static_cast<void*>(legacy_header() + 1);
|
| + return data_ + header()->num_header_bytes;
|
| +}
|
| +
|
| +const void* Channel::Message::payload() const {
|
| + if (is_legacy_message())
|
| + return static_cast<const void*>(legacy_header() + 1);
|
| + return data_ + header()->num_header_bytes;
|
| +}
|
| +
|
| size_t Channel::Message::payload_size() const {
|
| -#if defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| - return header_->num_bytes - sizeof(Header);
|
| -#else
|
| - return size_ - header_->num_header_bytes;
|
| -#endif
|
| + if (is_legacy_message())
|
| + return legacy_header()->num_bytes - sizeof(LegacyHeader);
|
| + return size_ - header()->num_header_bytes;
|
| +}
|
| +
|
| +size_t Channel::Message::num_handles() const {
|
| + return is_legacy_message() ? legacy_header()->num_handles
|
| + : header()->num_handles;
|
| +}
|
| +
|
| +bool Channel::Message::has_handles() const {
|
| + return (is_legacy_message() ? legacy_header()->num_handles
|
| + : header()->num_handles) > 0;
|
| }
|
|
|
| #if defined(OS_MACOSX) && !defined(OS_IOS)
|
| @@ -224,31 +293,44 @@ bool Channel::Message::has_mach_ports() const {
|
| }
|
| #endif
|
|
|
| +bool Channel::Message::is_legacy_message() const {
|
| + return legacy_header()->message_type == MessageType::NORMAL_LEGACY;
|
| +}
|
| +
|
| +Channel::Message::LegacyHeader* Channel::Message::legacy_header() const {
|
| + return reinterpret_cast<LegacyHeader*>(data_);
|
| +}
|
| +
|
| +Channel::Message::Header* Channel::Message::header() const {
|
| + DCHECK(!is_legacy_message());
|
| + return reinterpret_cast<Header*>(data_);
|
| +}
|
| +
|
| void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) {
|
| -#if defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| - // Old semantics for ChromeOS and Android
|
| - if (header_->num_handles == 0) {
|
| - CHECK(!new_handles || new_handles->size() == 0);
|
| + if (is_legacy_message()) {
|
| + // Old semantics for ChromeOS and Android
|
| + if (legacy_header()->num_handles == 0) {
|
| + CHECK(!new_handles || new_handles->size() == 0);
|
| + return;
|
| + }
|
| + CHECK(new_handles && new_handles->size() == legacy_header()->num_handles);
|
| + std::swap(handle_vector_, new_handles);
|
| 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());
|
| + header()->num_handles = static_cast<uint16_t>(new_handles->size());
|
| std::swap(handle_vector_, new_handles);
|
| #if defined(OS_WIN)
|
| memset(handles_, 0, extra_header_size());
|
| for (size_t i = 0; i < handle_vector_->size(); i++)
|
| handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle);
|
| #endif // defined(OS_WIN)
|
| -#endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
|
|
|
| #if defined(OS_MACOSX) && !defined(OS_IOS)
|
| size_t mach_port_index = 0;
|
| @@ -280,12 +362,12 @@ ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
|
| }
|
| mach_ports_header_->num_ports = 0;
|
| }
|
| - header_->num_handles = 0;
|
| - return std::move(handle_vector_);
|
| -#else
|
| - header_->num_handles = 0;
|
| - return std::move(handle_vector_);
|
| #endif
|
| + if (is_legacy_message())
|
| + legacy_header()->num_handles = 0;
|
| + else
|
| + header()->num_handles = 0;
|
| + return std::move(handle_vector_);
|
| }
|
|
|
| ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() {
|
| @@ -491,58 +573,71 @@ char* Channel::GetReadBuffer(size_t *buffer_capacity) {
|
| bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) {
|
| bool did_dispatch_message = false;
|
| read_buffer_->Claim(bytes_read);
|
| - while (read_buffer_->num_occupied_bytes() >= sizeof(Message::Header)) {
|
| + while (read_buffer_->num_occupied_bytes() >= sizeof(Message::LegacyHeader)) {
|
| // Ensure the occupied data is properly aligned. If it isn't, a SIGBUS could
|
| // happen on architectures that don't allow misaligned words access (i.e.
|
| // anything other than x86). Only re-align when necessary to avoid copies.
|
| - if (reinterpret_cast<uintptr_t>(read_buffer_->occupied_bytes()) %
|
| - kChannelMessageAlignment != 0)
|
| + if (!IsAlignedForChannelMessage(
|
| + reinterpret_cast<uintptr_t>(read_buffer_->occupied_bytes()))) {
|
| read_buffer_->Realign();
|
| + }
|
| +
|
| + // We have at least enough data available for a LegacyHeader.
|
| + const Message::LegacyHeader* legacy_header =
|
| + reinterpret_cast<const Message::LegacyHeader*>(
|
| + read_buffer_->occupied_bytes());
|
|
|
| - // We have at least enough data available for a MessageHeader.
|
| - const Message::Header* header = reinterpret_cast<const Message::Header*>(
|
| - read_buffer_->occupied_bytes());
|
| - if (header->num_bytes < sizeof(Message::Header) ||
|
| - header->num_bytes > kMaxChannelMessageSize) {
|
| - LOG(ERROR) << "Invalid message size: " << header->num_bytes;
|
| + if (legacy_header->num_bytes < sizeof(Message::LegacyHeader) ||
|
| + legacy_header->num_bytes > kMaxChannelMessageSize) {
|
| + LOG(ERROR) << "Invalid message size: " << legacy_header->num_bytes;
|
| return false;
|
| }
|
|
|
| - if (read_buffer_->num_occupied_bytes() < header->num_bytes) {
|
| + if (read_buffer_->num_occupied_bytes() < legacy_header->num_bytes) {
|
| // Not enough data available to read the full message. Hint to the
|
| // implementation that it should try reading the full size of the message.
|
| *next_read_size_hint =
|
| - header->num_bytes - read_buffer_->num_occupied_bytes();
|
| + legacy_header->num_bytes - read_buffer_->num_occupied_bytes();
|
| return true;
|
| }
|
|
|
| -#if defined(MOJO_EDK_LEGACY_PROTOCOL)
|
| + const Message::Header* header = nullptr;
|
| + if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY) {
|
| + header = reinterpret_cast<const Message::Header*>(legacy_header);
|
| + }
|
| +
|
| 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
|
| - if (header->num_header_bytes < sizeof(Message::Header) ||
|
| - header->num_header_bytes > header->num_bytes) {
|
| - LOG(ERROR) << "Invalid message header size: " << header->num_header_bytes;
|
| - return false;
|
| + size_t payload_size = 0;
|
| + void* payload = nullptr;
|
| + if (header) {
|
| + if (header->num_header_bytes < sizeof(Message::Header) ||
|
| + header->num_header_bytes > header->num_bytes) {
|
| + LOG(ERROR) << "Invalid message header size: "
|
| + << header->num_header_bytes;
|
| + return false;
|
| + }
|
| + extra_header_size = header->num_header_bytes - sizeof(Message::Header);
|
| + extra_header = extra_header_size ? header + 1 : nullptr;
|
| + payload_size = header->num_bytes - header->num_header_bytes;
|
| + payload = payload_size
|
| + ? reinterpret_cast<Message::Header*>(
|
| + const_cast<char*>(read_buffer_->occupied_bytes()) +
|
| + header->num_header_bytes)
|
| + : nullptr;
|
| + } else {
|
| + payload_size = legacy_header->num_bytes - sizeof(Message::LegacyHeader);
|
| + payload = payload_size
|
| + ? const_cast<Message::LegacyHeader*>(&legacy_header[1])
|
| + : nullptr;
|
| }
|
| - size_t extra_header_size =
|
| - header->num_header_bytes - sizeof(Message::Header);
|
| - const void* extra_header = extra_header_size ? header + 1 : nullptr;
|
| - 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 // defined(MOJO_EDK_LEGACY_PROTOCOL)
|
|
|
| + const uint16_t num_handles =
|
| + header ? header->num_handles : legacy_header->num_handles;
|
| ScopedPlatformHandleVectorPtr handles;
|
| - if (header->num_handles > 0) {
|
| - if (!GetReadPlatformHandles(header->num_handles, extra_header,
|
| - extra_header_size, &handles)) {
|
| + if (num_handles > 0) {
|
| + if (!GetReadPlatformHandles(num_handles, extra_header, extra_header_size,
|
| + &handles)) {
|
| return false;
|
| }
|
|
|
| @@ -553,8 +648,9 @@ bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) {
|
| }
|
|
|
| // We've got a complete message! Dispatch it and try another.
|
| - if (header->message_type != Message::Header::MessageType::NORMAL) {
|
| - if (!OnControlMessage(header->message_type, payload, payload_size,
|
| + if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY &&
|
| + legacy_header->message_type != Message::MessageType::NORMAL) {
|
| + if (!OnControlMessage(legacy_header->message_type, payload, payload_size,
|
| std::move(handles))) {
|
| return false;
|
| }
|
| @@ -564,7 +660,7 @@ bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) {
|
| did_dispatch_message = true;
|
| }
|
|
|
| - read_buffer_->Discard(header->num_bytes);
|
| + read_buffer_->Discard(legacy_header->num_bytes);
|
| }
|
|
|
| *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize;
|
| @@ -576,7 +672,7 @@ void Channel::OnError() {
|
| delegate_->OnChannelError();
|
| }
|
|
|
| -bool Channel::OnControlMessage(Message::Header::MessageType message_type,
|
| +bool Channel::OnControlMessage(Message::MessageType message_type,
|
| const void* payload,
|
| size_t payload_size,
|
| ScopedPlatformHandleVectorPtr handles) {
|
|
|