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 |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/memory/aligned_memory.h" | 13 #include "base/memory/aligned_memory.h" |
14 #include "mojo/system/constants.h" | 14 #include "mojo/system/constants.h" |
15 | 15 |
16 namespace mojo { | 16 namespace mojo { |
17 namespace system { | 17 namespace system { |
18 | 18 |
| 19 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| 20 MessageInTransit::kTypeMessagePipeEndpoint; |
| 21 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| 22 MessageInTransit::kTypeMessagePipe; |
| 23 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| 24 MessageInTransit::kTypeChannel; |
| 25 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
| 26 MessageInTransit::kSubtypeMessagePipeEndpointData; |
| 27 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
| 28 MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint; |
| 29 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
| 30 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint; |
| 31 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
| 32 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck; |
| 33 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId |
| 34 MessageInTransit::kInvalidEndpointId; |
| 35 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment; |
| 36 STATIC_CONST_MEMBER_DEFINITION const size_t |
| 37 MessageInTransit::kMaxSerializedDispatcherSize; |
| 38 STATIC_CONST_MEMBER_DEFINITION const size_t |
| 39 MessageInTransit::kMaxSerializedDispatcherPlatformHandles; |
| 40 |
19 struct MessageInTransit::PrivateStructForCompileAsserts { | 41 struct MessageInTransit::PrivateStructForCompileAsserts { |
20 // The size of |Header| must be a multiple of the alignment. | 42 // The size of |Header| must be a multiple of the alignment. |
21 COMPILE_ASSERT(sizeof(Header) % kMessageAlignment == 0, | 43 COMPILE_ASSERT(sizeof(Header) % kMessageAlignment == 0, |
22 sizeof_MessageInTransit_Header_invalid); | 44 sizeof_MessageInTransit_Header_invalid); |
23 // Avoid dangerous situations, but making sure that the size of the "header" + | 45 // Avoid dangerous situations, but making sure that the size of the "header" + |
24 // the size of the data fits into a 31-bit number. | 46 // the size of the data fits into a 31-bit number. |
25 COMPILE_ASSERT(static_cast<uint64_t>(sizeof(Header)) + kMaxMessageNumBytes <= | 47 COMPILE_ASSERT(static_cast<uint64_t>(sizeof(Header)) + kMaxMessageNumBytes <= |
26 0x7fffffffULL, | 48 0x7fffffffULL, |
27 kMaxMessageNumBytes_too_big); | 49 kMaxMessageNumBytes_too_big); |
28 | 50 |
29 // We assume (to avoid extra rounding code) that the maximum message (data) | 51 // We assume (to avoid extra rounding code) that the maximum message (data) |
30 // size is a multiple of the alignment. | 52 // size is a multiple of the alignment. |
31 COMPILE_ASSERT(kMaxMessageNumBytes % kMessageAlignment == 0, | 53 COMPILE_ASSERT(kMaxMessageNumBytes % kMessageAlignment == 0, |
32 kMessageAlignment_not_a_multiple_of_alignment); | 54 kMessageAlignment_not_a_multiple_of_alignment); |
33 | 55 |
34 // The maximum serialized dispatcher size must be a multiple of the alignment. | 56 // The maximum serialized dispatcher size must be a multiple of the alignment. |
35 COMPILE_ASSERT(kMaxSerializedDispatcherSize % kMessageAlignment == 0, | 57 COMPILE_ASSERT(kMaxSerializedDispatcherSize % kMessageAlignment == 0, |
36 kMaxSerializedDispatcherSize_not_a_multiple_of_alignment); | 58 kMaxSerializedDispatcherSize_not_a_multiple_of_alignment); |
37 | 59 |
38 // The size of |HandleTableEntry| must be a multiple of the alignment. | 60 // The size of |HandleTableEntry| must be a multiple of the alignment. |
39 COMPILE_ASSERT(sizeof(HandleTableEntry) % kMessageAlignment == 0, | 61 COMPILE_ASSERT(sizeof(HandleTableEntry) % kMessageAlignment == 0, |
40 sizeof_MessageInTransit_HandleTableEntry_invalid); | 62 sizeof_MessageInTransit_HandleTableEntry_invalid); |
41 }; | 63 }; |
42 | 64 |
43 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type | |
44 MessageInTransit::kTypeMessagePipeEndpoint; | |
45 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type | |
46 MessageInTransit::kTypeMessagePipe; | |
47 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type | |
48 MessageInTransit::kTypeChannel; | |
49 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype | |
50 MessageInTransit::kSubtypeMessagePipeEndpointData; | |
51 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype | |
52 MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint; | |
53 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype | |
54 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint; | |
55 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype | |
56 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck; | |
57 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId | |
58 MessageInTransit::kInvalidEndpointId; | |
59 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment; | |
60 STATIC_CONST_MEMBER_DEFINITION const size_t | |
61 MessageInTransit::kMaxSerializedDispatcherSize; | |
62 STATIC_CONST_MEMBER_DEFINITION const size_t | |
63 MessageInTransit::kMaxSerializedDispatcherPlatformHandles; | |
64 | |
65 // For each attached (Mojo) handle, there'll be a handle table entry and | 65 // For each attached (Mojo) handle, there'll be a handle table entry and |
66 // serialized dispatcher data. | 66 // serialized dispatcher data. |
67 // static | 67 // static |
68 const size_t MessageInTransit::kMaxSecondaryBufferSize = kMaxMessageNumHandles * | 68 const size_t MessageInTransit::kMaxSecondaryBufferSize = kMaxMessageNumHandles * |
69 (sizeof(HandleTableEntry) + kMaxSerializedDispatcherSize); | 69 (sizeof(HandleTableEntry) + kMaxSerializedDispatcherSize); |
70 | 70 |
| 71 // static |
71 const size_t MessageInTransit::kMaxPlatformHandles = | 72 const size_t MessageInTransit::kMaxPlatformHandles = |
72 kMaxMessageNumHandles * kMaxSerializedDispatcherPlatformHandles; | 73 kMaxMessageNumHandles * kMaxSerializedDispatcherPlatformHandles; |
73 | 74 |
74 MessageInTransit::View::View(size_t message_size, const void* buffer) | 75 MessageInTransit::View::View(size_t message_size, const void* buffer) |
75 : buffer_(buffer) { | 76 : buffer_(buffer) { |
76 size_t next_message_size = 0; | 77 size_t next_message_size = 0; |
77 DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size, | 78 DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size, |
78 &next_message_size)); | 79 &next_message_size)); |
79 DCHECK_EQ(message_size, next_message_size); | 80 DCHECK_EQ(message_size, next_message_size); |
80 // This should be equivalent. | 81 // This should be equivalent. |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 215 |
215 void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) { | 216 void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) { |
216 DCHECK(channel); | 217 DCHECK(channel); |
217 DCHECK(!secondary_buffer_); | 218 DCHECK(!secondary_buffer_); |
218 CHECK_EQ(num_handles(), | 219 CHECK_EQ(num_handles(), |
219 dispatchers_ ? dispatchers_->size() : static_cast<size_t>(0)); | 220 dispatchers_ ? dispatchers_->size() : static_cast<size_t>(0)); |
220 | 221 |
221 if (!num_handles()) | 222 if (!num_handles()) |
222 return; | 223 return; |
223 | 224 |
224 size_t handle_table_size = num_handles() * sizeof(HandleTableEntry); | 225 // The offset to the start of the (Mojo) handle table. |
225 // The size of the secondary buffer. We'll start with the size of the handle | 226 // TODO(vtl): Add a header to the secondary buffer. |
226 // table, and add to it as we go along. | 227 const size_t handle_table_start_offset = 0; |
227 size_t size = handle_table_size; | 228 // The offset to the start of the serialized dispatcher data. |
| 229 const size_t serialized_dispatcher_start_offset = |
| 230 handle_table_start_offset + num_handles() * sizeof(HandleTableEntry); |
| 231 // The size of the secondary buffer we'll add to this as we go along). |
| 232 size_t size = serialized_dispatcher_start_offset; |
228 size_t num_platform_handles = 0; | 233 size_t num_platform_handles = 0; |
229 #if DCHECK_IS_ON | 234 #if DCHECK_IS_ON |
230 std::vector<size_t> all_max_sizes(num_handles()); | 235 std::vector<size_t> all_max_sizes(num_handles()); |
231 std::vector<size_t> all_max_platform_handles(num_handles()); | 236 std::vector<size_t> all_max_platform_handles(num_handles()); |
232 #endif | 237 #endif |
233 for (size_t i = 0; i < num_handles(); i++) { | 238 for (size_t i = 0; i < num_handles(); i++) { |
234 if (Dispatcher* dispatcher = (*dispatchers_)[i].get()) { | 239 if (Dispatcher* dispatcher = (*dispatchers_)[i].get()) { |
235 size_t max_size = 0; | 240 size_t max_size = 0; |
236 size_t max_platform_handles = 0; | 241 size_t max_platform_handles = 0; |
237 Dispatcher::MessageInTransitAccess::StartSerialize( | 242 Dispatcher::MessageInTransitAccess::StartSerialize( |
(...skipping 20 matching lines...) Expand all Loading... |
258 // Entirely clear out the secondary buffer, since then we won't have to worry | 263 // Entirely clear out the secondary buffer, since then we won't have to worry |
259 // about clearing padding or unused space (e.g., if a dispatcher fails to | 264 // about clearing padding or unused space (e.g., if a dispatcher fails to |
260 // serialize). | 265 // serialize). |
261 memset(secondary_buffer_, 0, size); | 266 memset(secondary_buffer_, 0, size); |
262 | 267 |
263 if (num_platform_handles > 0) { | 268 if (num_platform_handles > 0) { |
264 DCHECK(!platform_handles_); | 269 DCHECK(!platform_handles_); |
265 platform_handles_.reset(new std::vector<embedder::PlatformHandle>()); | 270 platform_handles_.reset(new std::vector<embedder::PlatformHandle>()); |
266 } | 271 } |
267 | 272 |
268 HandleTableEntry* handle_table = | 273 HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>( |
269 static_cast<HandleTableEntry*>(secondary_buffer_); | 274 static_cast<char*>(secondary_buffer_) + handle_table_start_offset); |
270 size_t current_offset = handle_table_size; | 275 size_t current_offset = serialized_dispatcher_start_offset; |
271 for (size_t i = 0; i < num_handles(); i++) { | 276 for (size_t i = 0; i < num_handles(); i++) { |
272 Dispatcher* dispatcher = (*dispatchers_)[i].get(); | 277 Dispatcher* dispatcher = (*dispatchers_)[i].get(); |
273 if (!dispatcher) { | 278 if (!dispatcher) { |
274 COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0, | 279 COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0, |
275 value_of_Dispatcher_kTypeUnknown_must_be_zero); | 280 value_of_Dispatcher_kTypeUnknown_must_be_zero); |
276 continue; | 281 continue; |
277 } | 282 } |
278 | 283 |
279 #if DCHECK_IS_ON | 284 #if DCHECK_IS_ON |
280 size_t old_platform_handles_size = | 285 size_t old_platform_handles_size = |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 | 404 |
400 void MessageInTransit::UpdateTotalSize() { | 405 void MessageInTransit::UpdateTotalSize() { |
401 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); | 406 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); |
402 DCHECK_EQ(secondary_buffer_size_ % kMessageAlignment, 0u); | 407 DCHECK_EQ(secondary_buffer_size_ % kMessageAlignment, 0u); |
403 header()->total_size = | 408 header()->total_size = |
404 static_cast<uint32_t>(main_buffer_size_ + secondary_buffer_size_); | 409 static_cast<uint32_t>(main_buffer_size_ + secondary_buffer_size_); |
405 } | 410 } |
406 | 411 |
407 } // namespace system | 412 } // namespace system |
408 } // namespace mojo | 413 } // namespace mojo |
OLD | NEW |