Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/edk/system/channel.h" | 5 #include "mojo/edk/system/channel.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| 11 #include <utility> | |
| 11 | 12 |
| 12 #include "base/macros.h" | 13 #include "base/macros.h" |
| 13 #include "base/memory/aligned_memory.h" | 14 #include "base/memory/aligned_memory.h" |
| 14 #include "mojo/edk/embedder/platform_handle.h" | 15 #include "mojo/edk/embedder/platform_handle.h" |
| 15 | 16 |
| 17 #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
| |
| 18 #include "base/mac/mach_logging.h" | |
| 19 #endif | |
| 20 | |
| 16 namespace mojo { | 21 namespace mojo { |
| 17 namespace edk { | 22 namespace edk { |
| 18 | 23 |
| 19 namespace { | 24 namespace { |
| 20 | 25 |
| 21 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, | 26 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, |
| 22 "Invalid Header size."); | 27 "Invalid Header size."); |
| 23 | 28 |
| 24 #if defined(OS_CHROMEOS) | 29 #if defined(OS_CHROMEOS) |
| 25 static_assert(sizeof(Channel::Message::Header) == 8, | 30 static_assert(sizeof(Channel::Message::Header) == 8, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 36 Channel::Message::Message(size_t payload_size, | 41 Channel::Message::Message(size_t payload_size, |
| 37 size_t max_handles, | 42 size_t max_handles, |
| 38 Header::MessageType message_type) | 43 Header::MessageType message_type) |
| 39 : max_handles_(max_handles) { | 44 : max_handles_(max_handles) { |
| 40 DCHECK_LE(max_handles_, kMaxAttachedHandles); | 45 DCHECK_LE(max_handles_, kMaxAttachedHandles); |
| 41 | 46 |
| 42 size_t extra_header_size = 0; | 47 size_t extra_header_size = 0; |
| 43 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
| 44 // On Windows we serialize platform handles into the extra header space. | 49 // On Windows we serialize platform handles into the extra header space. |
| 45 extra_header_size = max_handles_ * sizeof(PlatformHandle); | 50 extra_header_size = max_handles_ * sizeof(PlatformHandle); |
| 51 #elif defined(OS_MACOSX) | |
| 52 // On OSX, some of the platform handles may be mach ports, which are | |
| 53 // serialised into the message buffer. Since there could be a mix of fds and | |
| 54 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t), | |
| 55 // so that the original ordering of handles can be re-created. | |
| 56 extra_header_size = max_handles * sizeof(MachPortsEntry); | |
| 46 #endif | 57 #endif |
| 47 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. | 58 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. |
| 48 if (extra_header_size % kChannelMessageAlignment) { | 59 if (extra_header_size % kChannelMessageAlignment) { |
| 49 extra_header_size += kChannelMessageAlignment - | 60 extra_header_size += kChannelMessageAlignment - |
| 50 (extra_header_size % kChannelMessageAlignment); | 61 (extra_header_size % kChannelMessageAlignment); |
| 51 } | 62 } |
| 52 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment); | 63 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment); |
| 53 #if defined(OS_CHROMEOS) | 64 #if defined(OS_CHROMEOS) |
| 54 DCHECK_EQ(0u, extra_header_size); | 65 DCHECK_EQ(0u, extra_header_size); |
| 55 #endif | 66 #endif |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 66 DCHECK_LE(sizeof(Header) + extra_header_size, | 77 DCHECK_LE(sizeof(Header) + extra_header_size, |
| 67 std::numeric_limits<uint16_t>::max()); | 78 std::numeric_limits<uint16_t>::max()); |
| 68 header_->message_type = message_type; | 79 header_->message_type = message_type; |
| 69 #if defined(OS_CHROMEOS) | 80 #if defined(OS_CHROMEOS) |
| 70 header_->num_handles = static_cast<uint16_t>(max_handles); | 81 header_->num_handles = static_cast<uint16_t>(max_handles); |
| 71 #else | 82 #else |
| 72 header_->num_header_bytes = | 83 header_->num_header_bytes = |
| 73 static_cast<uint16_t>(sizeof(Header) + extra_header_size); | 84 static_cast<uint16_t>(sizeof(Header) + extra_header_size); |
| 74 #endif | 85 #endif |
| 75 | 86 |
| 87 if (max_handles_ > 0) { | |
| 76 #if defined(OS_WIN) | 88 #if defined(OS_WIN) |
| 77 if (max_handles_ > 0) { | |
| 78 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header()); | 89 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header()); |
| 79 // Initialize all handles to invalid values. | 90 // Initialize all handles to invalid values. |
| 80 for (size_t i = 0; i < max_handles_; ++i) | 91 for (size_t i = 0; i < max_handles_; ++i) |
| 81 handles()[i] = PlatformHandle(); | 92 handles()[i] = PlatformHandle(); |
| 93 #elif defined(OS_MACOSX) && !defined(OS_IOS) | |
| 94 mach_ports_ = reinterpret_cast<MachPortsEntry*>(mutable_extra_header()); | |
| 95 // Initialize all handles to invalid values. | |
| 96 for (size_t i = 0; i < max_handles_; ++i) | |
| 97 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)}; | |
| 98 #endif | |
| 82 } | 99 } |
| 83 #endif | |
| 84 } | 100 } |
| 85 | 101 |
| 86 Channel::Message::~Message() { | 102 Channel::Message::~Message() { |
| 87 #if defined(OS_WIN) | 103 #if defined(OS_WIN) |
| 88 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us. | 104 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us. |
| 89 for (size_t i = 0; i < header_->num_handles; ++i) | 105 for (size_t i = 0; i < header_->num_handles; ++i) |
| 90 handles()[i].CloseIfNecessary(); | 106 handles()[i].CloseIfNecessary(); |
| 91 #endif | 107 #endif |
| 92 base::AlignedFree(data_); | 108 base::AlignedFree(data_); |
| 93 } | 109 } |
| 94 | 110 |
| 95 // static | 111 // static |
| 96 Channel::MessagePtr Channel::Message::Deserialize(const void* data, | 112 Channel::MessagePtr Channel::Message::Deserialize(const void* data, |
| 97 size_t data_num_bytes) { | 113 size_t data_num_bytes) { |
| 98 #if !defined(OS_WIN) | 114 #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.
| |
| 99 // We only serialize messages into other messages when performing message | 115 // We only serialize messages into other messages when performing message |
| 100 // relay on Windows. | 116 // relay on Windows and OSX. |
| 101 NOTREACHED(); | 117 NOTREACHED(); |
| 102 return nullptr; | 118 return nullptr; |
| 103 #else | 119 #else |
| 104 if (data_num_bytes < sizeof(Header)) | 120 if (data_num_bytes < sizeof(Header)) |
| 105 return nullptr; | 121 return nullptr; |
| 106 | 122 |
| 107 const Header* header = reinterpret_cast<const Header*>(data); | 123 const Header* header = reinterpret_cast<const Header*>(data); |
| 108 if (header->num_bytes != data_num_bytes) { | 124 if (header->num_bytes != data_num_bytes) { |
| 109 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes | 125 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes |
| 110 << " != " << data_num_bytes; | 126 << " != " << data_num_bytes; |
| 111 return nullptr; | 127 return nullptr; |
| 112 } | 128 } |
| 113 | 129 |
| 114 if (header->num_bytes < header->num_header_bytes) { | 130 if (header->num_bytes < header->num_header_bytes) { |
| 115 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " | 131 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " |
| 116 << header->num_header_bytes; | 132 << header->num_header_bytes; |
| 117 return nullptr; | 133 return nullptr; |
| 118 } | 134 } |
| 119 | 135 |
| 120 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); | 136 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); |
| 137 #if defined(OS_WIN) | |
| 121 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); | 138 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); |
| 139 #elif defined(OS_MACOSX) | |
| 140 uint32_t max_handles = extra_header_size / sizeof(MachPortsEntry); | |
| 141 #endif | |
| 122 if (header->num_handles > max_handles) { | 142 if (header->num_handles > max_handles) { |
| 123 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles << " > " | 143 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles |
| 124 << max_handles; | 144 << " > " << max_handles; |
| 125 return nullptr; | 145 return nullptr; |
| 126 } | 146 } |
| 127 | 147 |
| 128 MessagePtr message( | 148 MessagePtr message(new Message(data_num_bytes - header->num_header_bytes, |
| 129 new Message(data_num_bytes - header->num_header_bytes, max_handles)); | 149 max_handles)); |
| 130 | |
| 131 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); | 150 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); |
| 132 DCHECK_EQ(message->extra_header_size(), extra_header_size); | 151 DCHECK_EQ(message->extra_header_size(), extra_header_size); |
| 133 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); | 152 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); |
| 134 | 153 |
| 135 // Copy all payload bytes. | 154 // Copy all payload bytes. |
| 136 memcpy(message->mutable_payload(), | 155 memcpy(message->mutable_payload(), |
| 137 static_cast<const char*>(data) + header->num_header_bytes, | 156 static_cast<const char*>(data) + header->num_header_bytes, |
| 138 data_num_bytes - header->num_header_bytes); | 157 data_num_bytes - header->num_header_bytes); |
| 139 // Copy extra header bytes. | 158 // Copy extra header bytes. |
| 140 memcpy(message->mutable_extra_header(), | 159 memcpy(message->mutable_extra_header(), |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 205 CHECK(new_handles && new_handles->size() <= max_handles_); | 224 CHECK(new_handles && new_handles->size() <= max_handles_); |
| 206 header_->num_handles = static_cast<uint16_t>(new_handles->size()); | 225 header_->num_handles = static_cast<uint16_t>(new_handles->size()); |
| 207 #if defined(OS_WIN) | 226 #if defined(OS_WIN) |
| 208 memcpy(handles(), new_handles->data(), | 227 memcpy(handles(), new_handles->data(), |
| 209 sizeof(PlatformHandle) * new_handles->size()); | 228 sizeof(PlatformHandle) * new_handles->size()); |
| 210 new_handles->clear(); | 229 new_handles->clear(); |
| 211 #else | 230 #else |
| 212 std::swap(handle_vector_, new_handles); | 231 std::swap(handle_vector_, new_handles); |
| 213 #endif // defined(OS_WIN) | 232 #endif // defined(OS_WIN) |
| 214 #endif // defined(OS_CHROMEOS) | 233 #endif // defined(OS_CHROMEOS) |
| 234 | |
| 235 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
| 236 size_t mach_port_index = 0; | |
| 237 for (size_t i = 0; i < max_handles_; ++i) | |
| 238 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)}; | |
| 239 for (size_t i = 0; i < handle_vector_->size(); i++) { | |
| 240 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH) { | |
| 241 mach_port_t port = (*handle_vector_)[i].port; | |
| 242 mach_ports_[mach_port_index].index = i; | |
| 243 mach_ports_[mach_port_index].mach_port = port; | |
| 244 mach_port_index++; | |
| 245 } | |
| 246 } | |
| 247 #endif | |
| 215 } | 248 } |
| 216 | 249 |
| 217 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { | 250 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { |
| 218 #if defined(OS_WIN) | 251 #if defined(OS_WIN) |
| 219 if (header_->num_handles == 0) | 252 if (header_->num_handles == 0) |
| 220 return ScopedPlatformHandleVectorPtr(); | 253 return ScopedPlatformHandleVectorPtr(); |
| 221 ScopedPlatformHandleVectorPtr moved_handles( | 254 ScopedPlatformHandleVectorPtr moved_handles( |
| 222 new PlatformHandleVector(header_->num_handles)); | 255 new PlatformHandleVector(header_->num_handles)); |
| 223 for (size_t i = 0; i < header_->num_handles; ++i) | 256 for (size_t i = 0; i < header_->num_handles; ++i) |
| 224 std::swap(moved_handles->at(i), handles()[i]); | 257 std::swap(moved_handles->at(i), handles()[i]); |
| 258 header_->num_handles = 0; | |
| 225 return moved_handles; | 259 return moved_handles; |
| 260 #elif defined(OS_MACOSX) && !defined(OS_IOS) | |
| 261 for (size_t i = 0; i < max_handles_; ++i) | |
| 262 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)}; | |
| 263 header_->num_handles = 0; | |
| 264 return std::move(handle_vector_); | |
| 265 #else | |
| 266 header_->num_handles = 0; | |
| 267 return std::move(handle_vector_); | |
| 268 #endif | |
| 269 } | |
| 270 | |
| 271 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() { | |
| 272 #if defined(OS_WIN) | |
| 273 // Not necessary on Windows. | |
| 274 NOTREACHED(); | |
| 275 return nullptr; | |
| 276 #elif defined(OS_MACOSX) && !defined(OS_IOS) | |
| 277 if (handle_vector_) { | |
| 278 for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) { | |
| 279 if (it->type == PlatformHandle::Type::MACH) { | |
| 280 it = handle_vector_->erase(it); | |
| 281 } else { | |
| 282 ++it; | |
| 283 } | |
| 284 } | |
| 285 } | |
| 286 return std::move(handle_vector_); | |
| 226 #else | 287 #else |
| 227 return std::move(handle_vector_); | 288 return std::move(handle_vector_); |
| 228 #endif | 289 #endif |
| 229 } | 290 } |
| 230 | 291 |
| 231 #if defined(OS_WIN) | 292 #if defined(OS_WIN) |
| 232 // static | 293 // static |
| 233 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, | 294 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, |
| 234 base::ProcessHandle to_process, | 295 base::ProcessHandle to_process, |
| 235 PlatformHandle* handles, | 296 PlatformHandle* handles, |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 return true; | 503 return true; |
| 443 } | 504 } |
| 444 | 505 |
| 445 void Channel::OnError() { | 506 void Channel::OnError() { |
| 446 if (delegate_) | 507 if (delegate_) |
| 447 delegate_->OnChannelError(); | 508 delegate_->OnChannelError(); |
| 448 } | 509 } |
| 449 | 510 |
| 450 } // namespace edk | 511 } // namespace edk |
| 451 } // namespace mojo | 512 } // namespace mojo |
| OLD | NEW |