OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/system/message_in_transit.h" | 5 #include "mojo/system/message_in_transit.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <new> | 9 #include <new> |
10 | 10 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 MessageInTransit::kTypeChannel; | 48 MessageInTransit::kTypeChannel; |
49 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype | 49 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
50 MessageInTransit::kSubtypeMessagePipeEndpointData; | 50 MessageInTransit::kSubtypeMessagePipeEndpointData; |
51 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype | 51 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
52 MessageInTransit::kSubtypeMessagePipePeerClosed; | 52 MessageInTransit::kSubtypeMessagePipePeerClosed; |
53 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId | 53 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId |
54 MessageInTransit::kInvalidEndpointId; | 54 MessageInTransit::kInvalidEndpointId; |
55 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment; | 55 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment; |
56 STATIC_CONST_MEMBER_DEFINITION const size_t | 56 STATIC_CONST_MEMBER_DEFINITION const size_t |
57 MessageInTransit::kMaxSerializedDispatcherSize; | 57 MessageInTransit::kMaxSerializedDispatcherSize; |
| 58 STATIC_CONST_MEMBER_DEFINITION const size_t |
| 59 MessageInTransit::kMaxSerializedDispatcherPlatformHandles; |
58 | 60 |
59 // For each attached (Mojo) handle, there'll be a handle table entry and | 61 // For each attached (Mojo) handle, there'll be a handle table entry and |
60 // serialized dispatcher data. | 62 // serialized dispatcher data. |
61 // static | 63 // static |
62 const size_t MessageInTransit::kMaxSecondaryBufferSize = kMaxMessageNumHandles * | 64 const size_t MessageInTransit::kMaxSecondaryBufferSize = kMaxMessageNumHandles * |
63 (sizeof(HandleTableEntry) + kMaxSerializedDispatcherSize); | 65 (sizeof(HandleTableEntry) + kMaxSerializedDispatcherSize); |
64 | 66 |
| 67 const size_t MessageInTransit::kMaxPlatformHandles = |
| 68 kMaxMessageNumHandles * kMaxSerializedDispatcherPlatformHandles; |
| 69 |
65 MessageInTransit::View::View(size_t message_size, const void* buffer) | 70 MessageInTransit::View::View(size_t message_size, const void* buffer) |
66 : buffer_(buffer) { | 71 : buffer_(buffer) { |
67 size_t next_message_size = 0; | 72 size_t next_message_size = 0; |
68 DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size, | 73 DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size, |
69 &next_message_size)); | 74 &next_message_size)); |
70 DCHECK_EQ(message_size, next_message_size); | 75 DCHECK_EQ(message_size, next_message_size); |
71 // This should be equivalent. | 76 // This should be equivalent. |
72 DCHECK_EQ(message_size, total_size()); | 77 DCHECK_EQ(message_size, total_size()); |
73 } | 78 } |
74 | 79 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 CHECK_EQ(num_handles(), | 214 CHECK_EQ(num_handles(), |
210 dispatchers_ ? dispatchers_->size() : static_cast<size_t>(0)); | 215 dispatchers_ ? dispatchers_->size() : static_cast<size_t>(0)); |
211 | 216 |
212 if (!num_handles()) | 217 if (!num_handles()) |
213 return; | 218 return; |
214 | 219 |
215 size_t handle_table_size = num_handles() * sizeof(HandleTableEntry); | 220 size_t handle_table_size = num_handles() * sizeof(HandleTableEntry); |
216 // The size of the secondary buffer. We'll start with the size of the handle | 221 // The size of the secondary buffer. We'll start with the size of the handle |
217 // table, and add to it as we go along. | 222 // table, and add to it as we go along. |
218 size_t size = handle_table_size; | 223 size_t size = handle_table_size; |
219 for (size_t i = 0; i < dispatchers_->size(); i++) { | 224 size_t num_platform_handles = 0; |
| 225 #if DCHECK_IS_ON |
| 226 std::vector<size_t> all_max_sizes(num_handles()); |
| 227 std::vector<size_t> all_max_platform_handles(num_handles()); |
| 228 #endif |
| 229 for (size_t i = 0; i < num_handles(); i++) { |
220 if (Dispatcher* dispatcher = (*dispatchers_)[i].get()) { | 230 if (Dispatcher* dispatcher = (*dispatchers_)[i].get()) { |
221 size_t max_serialized_size = | 231 size_t max_size = 0; |
222 Dispatcher::MessageInTransitAccess::GetMaximumSerializedSize( | 232 size_t max_platform_handles = 0; |
223 dispatcher, channel); | 233 Dispatcher::MessageInTransitAccess::StartSerialize( |
224 DCHECK_LE(max_serialized_size, kMaxSerializedDispatcherSize); | 234 dispatcher, channel, &max_size, &max_platform_handles); |
225 size += RoundUpMessageAlignment(max_serialized_size); | 235 |
| 236 DCHECK_LE(max_size, kMaxSerializedDispatcherSize); |
| 237 size += RoundUpMessageAlignment(max_size); |
226 DCHECK_LE(size, kMaxSecondaryBufferSize); | 238 DCHECK_LE(size, kMaxSecondaryBufferSize); |
| 239 |
| 240 DCHECK_LE(max_platform_handles, |
| 241 kMaxSerializedDispatcherPlatformHandles); |
| 242 num_platform_handles += max_platform_handles; |
| 243 DCHECK_LE(num_platform_handles, kMaxPlatformHandles); |
| 244 |
| 245 #if DCHECK_IS_ON |
| 246 all_max_sizes[i] = max_size; |
| 247 all_max_platform_handles[i] = max_platform_handles; |
| 248 #endif |
227 } | 249 } |
228 } | 250 } |
229 | 251 |
230 secondary_buffer_ = base::AlignedAlloc(size, kMessageAlignment); | 252 secondary_buffer_ = base::AlignedAlloc(size, kMessageAlignment); |
231 secondary_buffer_size_ = static_cast<uint32_t>(size); | 253 secondary_buffer_size_ = static_cast<uint32_t>(size); |
232 // Entirely clear out the secondary buffer, since then we won't have to worry | 254 // Entirely clear out the secondary buffer, since then we won't have to worry |
233 // about clearing padding or unused space (e.g., if a dispatcher fails to | 255 // about clearing padding or unused space (e.g., if a dispatcher fails to |
234 // serialize). | 256 // serialize). |
235 memset(secondary_buffer_, 0, size); | 257 memset(secondary_buffer_, 0, size); |
236 | 258 |
| 259 if (num_platform_handles > 0) { |
| 260 DCHECK(!platform_handles_); |
| 261 platform_handles_.reset(new std::vector<embedder::PlatformHandle>()); |
| 262 } |
| 263 |
237 HandleTableEntry* handle_table = | 264 HandleTableEntry* handle_table = |
238 static_cast<HandleTableEntry*>(secondary_buffer_); | 265 static_cast<HandleTableEntry*>(secondary_buffer_); |
239 size_t current_offset = handle_table_size; | 266 size_t current_offset = handle_table_size; |
240 for (size_t i = 0; i < dispatchers_->size(); i++) { | 267 for (size_t i = 0; i < num_handles(); i++) { |
241 Dispatcher* dispatcher = (*dispatchers_)[i].get(); | 268 Dispatcher* dispatcher = (*dispatchers_)[i].get(); |
242 if (!dispatcher) { | 269 if (!dispatcher) { |
243 COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0, | 270 COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0, |
244 value_of_Dispatcher_kTypeUnknown_must_be_zero); | 271 value_of_Dispatcher_kTypeUnknown_must_be_zero); |
245 continue; | 272 continue; |
246 } | 273 } |
247 | 274 |
| 275 #if DCHECK_IS_ON |
| 276 size_t old_platform_handles_size = |
| 277 platform_handles_ ? platform_handles_->size() : 0; |
| 278 #endif |
| 279 |
248 void* destination = static_cast<char*>(secondary_buffer_) + current_offset; | 280 void* destination = static_cast<char*>(secondary_buffer_) + current_offset; |
249 size_t actual_size = 0; | 281 size_t actual_size = 0; |
250 if (Dispatcher::MessageInTransitAccess::SerializeAndClose( | 282 if (Dispatcher::MessageInTransitAccess::EndSerializeAndClose( |
251 dispatcher, channel, destination, &actual_size)) { | 283 dispatcher, channel, destination, &actual_size, |
| 284 platform_handles_.get())) { |
252 handle_table[i].type = static_cast<int32_t>(dispatcher->GetType()); | 285 handle_table[i].type = static_cast<int32_t>(dispatcher->GetType()); |
253 handle_table[i].offset = static_cast<uint32_t>(current_offset); | 286 handle_table[i].offset = static_cast<uint32_t>(current_offset); |
254 handle_table[i].size = static_cast<uint32_t>(actual_size); | 287 handle_table[i].size = static_cast<uint32_t>(actual_size); |
| 288 |
| 289 #if DCHECK_IS_ON |
| 290 DCHECK_LE(actual_size, all_max_sizes[i]); |
| 291 DCHECK_LE(platform_handles_ ? (platform_handles_->size() - |
| 292 old_platform_handles_size) : 0, |
| 293 all_max_platform_handles[i]); |
| 294 #endif |
255 } else { | 295 } else { |
256 // Nothing to do on failure, since |secondary_buffer_| was cleared, and | 296 // Nothing to do on failure, since |secondary_buffer_| was cleared, and |
257 // |kTypeUnknown| is zero. The handle was simply closed. | 297 // |kTypeUnknown| is zero. The handle was simply closed. |
258 LOG(ERROR) << "Failed to serialize handle to remote message pipe"; | 298 LOG(ERROR) << "Failed to serialize handle to remote message pipe"; |
259 } | 299 } |
260 | 300 |
261 current_offset += RoundUpMessageAlignment(actual_size); | 301 current_offset += RoundUpMessageAlignment(actual_size); |
262 DCHECK_LE(current_offset, size); | 302 DCHECK_LE(current_offset, size); |
| 303 DCHECK_LE(platform_handles_ ? platform_handles_->size() : 0, |
| 304 num_platform_handles); |
263 } | 305 } |
264 | 306 |
265 UpdateTotalSize(); | 307 UpdateTotalSize(); |
266 } | 308 } |
267 | 309 |
268 // Note: The message's secondary buffer should have been checked by calling | 310 // Note: The message's secondary buffer should have been checked by calling |
269 // |View::IsValid()| (on the |View|) first. | 311 // |View::IsValid()| (on the |View|) first. |
270 void MessageInTransit::DeserializeDispatchers(Channel* channel) { | 312 void MessageInTransit::DeserializeDispatchers(Channel* channel) { |
271 DCHECK(!dispatchers_); | 313 DCHECK(!dispatchers_); |
272 | 314 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 | 395 |
354 void MessageInTransit::UpdateTotalSize() { | 396 void MessageInTransit::UpdateTotalSize() { |
355 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); | 397 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); |
356 DCHECK_EQ(secondary_buffer_size_ % kMessageAlignment, 0u); | 398 DCHECK_EQ(secondary_buffer_size_ % kMessageAlignment, 0u); |
357 header()->total_size = | 399 header()->total_size = |
358 static_cast<uint32_t>(main_buffer_size_ + secondary_buffer_size_); | 400 static_cast<uint32_t>(main_buffer_size_ + secondary_buffer_size_); |
359 } | 401 } |
360 | 402 |
361 } // namespace system | 403 } // namespace system |
362 } // namespace mojo | 404 } // namespace mojo |
OLD | NEW |