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

Side by Side Diff: mojo/edk/system/transport_data.cc

Issue 1350023003: Add a Mojo EDK for Chrome that uses one OS pipe per message pipe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more cleanup Created 5 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "third_party/mojo/src/mojo/edk/system/transport_data.h" 5 #include "mojo/edk/system/transport_data.h"
6
7 #include <string.h>
8 6
9 #include "base/logging.h" 7 #include "base/logging.h"
10 #include "third_party/mojo/src/mojo/edk/system/channel.h" 8 #include "mojo/edk/system/configuration.h"
11 #include "third_party/mojo/src/mojo/edk/system/configuration.h" 9 #include "mojo/edk/system/message_in_transit.h"
12 #include "third_party/mojo/src/mojo/edk/system/message_in_transit.h" 10 #include "mojo/edk/system/raw_channel.h"
13 11
14 namespace mojo { 12 namespace mojo {
15 namespace system { 13 namespace edk {
16 14
17 // The maximum amount of space needed per platform handle. 15 // The maximum amount of space needed per platform handle.
18 // (|{Channel,RawChannel}::GetSerializedPlatformHandleSize()| should always 16 // (|{Channel,RawChannel}::GetSerializedPlatformHandleSize()| should always
19 // return a value which is at most this. This is only used to calculate 17 // return a value which is at most this. This is only used to calculate
20 // |TransportData::kMaxBufferSize|. This value should be a multiple of the 18 // |TransportData::kMaxBufferSize|. This value should be a multiple of the
21 // alignment in order to simplify calculations, even though the actual amount of 19 // alignment in order to simplify calculations, even though the actual amount of
22 // space needed need not be a multiple of the alignment. 20 // space needed need not be a multiple of the alignment.
23 const size_t kMaxSizePerPlatformHandle = 16; 21 const size_t kMaxSizePerPlatformHandle = 16;
24 static_assert(kMaxSizePerPlatformHandle % MessageInTransit::kMessageAlignment == 22 static_assert(kMaxSizePerPlatformHandle % MessageInTransit::kMessageAlignment ==
25 0, 23 0,
(...skipping 27 matching lines...) Expand all
53 MessageInTransit::kMessageAlignment == 51 MessageInTransit::kMessageAlignment ==
54 0, 52 0,
55 "kMaxSerializedDispatcherSize not a multiple of alignment"); 53 "kMaxSerializedDispatcherSize not a multiple of alignment");
56 static_assert(sizeof(HandleTableEntry) % 54 static_assert(sizeof(HandleTableEntry) %
57 MessageInTransit::kMessageAlignment == 55 MessageInTransit::kMessageAlignment ==
58 0, 56 0,
59 "sizeof(MessageInTransit::HandleTableEntry) not a multiple of " 57 "sizeof(MessageInTransit::HandleTableEntry) not a multiple of "
60 "alignment"); 58 "alignment");
61 }; 59 };
62 60
63 TransportData::TransportData(scoped_ptr<DispatcherVector> dispatchers, 61 TransportData::TransportData(scoped_ptr<DispatcherVector> dispatchers)
64 Channel* channel)
65 : buffer_size_() { 62 : buffer_size_() {
66 DCHECK(dispatchers); 63 DCHECK(dispatchers);
67 DCHECK(channel);
68 64
69 const size_t num_handles = dispatchers->size(); 65 const size_t num_handles = dispatchers->size();
70 DCHECK_GT(num_handles, 0u); 66 DCHECK_GT(num_handles, 0u);
71 67
72 // The offset to the start of the (Mojo) handle table. 68 // The offset to the start of the (Mojo) handle table.
73 const size_t handle_table_start_offset = sizeof(Header); 69 const size_t handle_table_start_offset = sizeof(Header);
74 // The offset to the start of the serialized dispatcher data. 70 // The offset to the start of the serialized dispatcher data.
75 const size_t serialized_dispatcher_start_offset = 71 const size_t serialized_dispatcher_start_offset =
76 handle_table_start_offset + num_handles * sizeof(HandleTableEntry); 72 handle_table_start_offset + num_handles * sizeof(HandleTableEntry);
77 // The estimated size of the secondary buffer. We compute this estimate below. 73 // The estimated size of the secondary buffer. We compute this estimate below.
78 // It must be at least as big as the (eventual) actual size. 74 // It must be at least as big as the (eventual) actual size.
79 size_t estimated_size = serialized_dispatcher_start_offset; 75 size_t estimated_size = serialized_dispatcher_start_offset;
80 size_t estimated_num_platform_handles = 0; 76 size_t estimated_num_platform_handles = 0;
81 #if DCHECK_IS_ON() 77 #if DCHECK_IS_ON()
82 std::vector<size_t> all_max_sizes(num_handles); 78 std::vector<size_t> all_max_sizes(num_handles);
83 std::vector<size_t> all_max_platform_handles(num_handles); 79 std::vector<size_t> all_max_platform_handles(num_handles);
84 #endif 80 #endif
85 for (size_t i = 0; i < num_handles; i++) { 81 for (size_t i = 0; i < num_handles; i++) {
86 if (Dispatcher* dispatcher = (*dispatchers)[i].get()) { 82 if (Dispatcher* dispatcher = (*dispatchers)[i].get()) {
87 size_t max_size = 0; 83 size_t max_size = 0;
88 size_t max_platform_handles = 0; 84 size_t max_platform_handles = 0;
89 Dispatcher::TransportDataAccess::StartSerialize( 85 Dispatcher::TransportDataAccess::StartSerialize(
90 dispatcher, channel, &max_size, &max_platform_handles); 86 dispatcher, &max_size, &max_platform_handles);
91 87
92 DCHECK_LE(max_size, kMaxSerializedDispatcherSize); 88 DCHECK_LE(max_size, kMaxSerializedDispatcherSize);
93 estimated_size += MessageInTransit::RoundUpMessageAlignment(max_size); 89 estimated_size += MessageInTransit::RoundUpMessageAlignment(max_size);
94 DCHECK_LE(estimated_size, GetMaxBufferSize()); 90 DCHECK_LE(estimated_size, GetMaxBufferSize());
95 91
96 DCHECK_LE(max_platform_handles, kMaxSerializedDispatcherPlatformHandles); 92 DCHECK_LE(max_platform_handles, kMaxSerializedDispatcherPlatformHandles);
97 estimated_num_platform_handles += max_platform_handles; 93 estimated_num_platform_handles += max_platform_handles;
98 DCHECK_LE(estimated_num_platform_handles, GetMaxPlatformHandles()); 94 DCHECK_LE(estimated_num_platform_handles, GetMaxPlatformHandles());
99 95
100 #if DCHECK_IS_ON() 96 #if DCHECK_IS_ON()
101 all_max_sizes[i] = max_size; 97 all_max_sizes[i] = max_size;
102 all_max_platform_handles[i] = max_platform_handles; 98 all_max_platform_handles[i] = max_platform_handles;
103 #endif 99 #endif
104 } 100 }
105 } 101 }
106 102
107 size_t size_per_platform_handle = 0; 103 size_t size_per_platform_handle = 0;
108 if (estimated_num_platform_handles > 0) { 104 if (estimated_num_platform_handles > 0) {
109 size_per_platform_handle = channel->GetSerializedPlatformHandleSize(); 105 size_per_platform_handle = RawChannel::GetSerializedPlatformHandleSize();
110 DCHECK_LE(size_per_platform_handle, kMaxSizePerPlatformHandle); 106 DCHECK_LE(size_per_platform_handle, kMaxSizePerPlatformHandle);
111 estimated_size += estimated_num_platform_handles * size_per_platform_handle; 107 estimated_size += estimated_num_platform_handles * size_per_platform_handle;
112 estimated_size = MessageInTransit::RoundUpMessageAlignment(estimated_size); 108 estimated_size = MessageInTransit::RoundUpMessageAlignment(estimated_size);
113 DCHECK_LE(estimated_size, GetMaxBufferSize()); 109 DCHECK_LE(estimated_size, GetMaxBufferSize());
114 } 110 }
115 111
116 buffer_.reset(static_cast<char*>( 112 buffer_.reset(static_cast<char*>(
117 base::AlignedAlloc(estimated_size, MessageInTransit::kMessageAlignment))); 113 base::AlignedAlloc(estimated_size, MessageInTransit::kMessageAlignment)));
118 // Entirely clear out the secondary buffer, since then we won't have to worry 114 // Entirely clear out the secondary buffer, since then we won't have to worry
119 // about clearing padding or unused space (e.g., if a dispatcher fails to 115 // about clearing padding or unused space (e.g., if a dispatcher fails to
120 // serialize). 116 // serialize).
121 memset(buffer_.get(), 0, estimated_size); 117 memset(buffer_.get(), 0, estimated_size);
122 118
123 if (estimated_num_platform_handles > 0) { 119 if (estimated_num_platform_handles > 0) {
124 DCHECK(!platform_handles_); 120 DCHECK(!platform_handles_);
125 platform_handles_.reset(new embedder::PlatformHandleVector()); 121 platform_handles_.reset(new PlatformHandleVector());
126 } 122 }
127 123
128 Header* header = reinterpret_cast<Header*>(buffer_.get()); 124 Header* header = reinterpret_cast<Header*>(buffer_.get());
129 header->num_handles = static_cast<uint32_t>(num_handles); 125 header->num_handles = static_cast<uint32_t>(num_handles);
130 // (Okay to leave |platform_handle_table_offset|, |num_platform_handles|, and 126 // (Okay to leave |platform_handle_table_offset|, |num_platform_handles|, and
131 // |unused| be zero; we'll set the former two later if necessary.) 127 // |unused| be zero; we'll set the former two later if necessary.)
132 128
133 HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>( 129 HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>(
134 buffer_.get() + handle_table_start_offset); 130 buffer_.get() + handle_table_start_offset);
135 size_t current_offset = serialized_dispatcher_start_offset; 131 size_t current_offset = serialized_dispatcher_start_offset;
136 for (size_t i = 0; i < num_handles; i++) { 132 for (size_t i = 0; i < num_handles; i++) {
137 Dispatcher* dispatcher = (*dispatchers)[i].get(); 133 Dispatcher* dispatcher = (*dispatchers)[i].get();
138 if (!dispatcher) { 134 if (!dispatcher) {
139 static_assert(static_cast<int32_t>(Dispatcher::Type::UNKNOWN) == 0, 135 static_assert(static_cast<int32_t>(Dispatcher::Type::UNKNOWN) == 0,
140 "Value of Dispatcher::Type::UNKNOWN must be 0"); 136 "Value of Dispatcher::Type::UNKNOWN must be 0");
141 continue; 137 continue;
142 } 138 }
143 139
144 #if DCHECK_IS_ON() 140 #if DCHECK_IS_ON()
145 size_t old_platform_handles_size = 141 size_t old_platform_handles_size =
146 platform_handles_ ? platform_handles_->size() : 0; 142 platform_handles_ ? platform_handles_->size() : 0;
147 #endif 143 #endif
148 144
149 void* destination = buffer_.get() + current_offset; 145 void* destination = buffer_.get() + current_offset;
150 size_t actual_size = 0; 146 size_t actual_size = 0;
151 if (Dispatcher::TransportDataAccess::EndSerializeAndClose( 147 if (Dispatcher::TransportDataAccess::EndSerializeAndClose(
152 dispatcher, channel, destination, &actual_size, 148 dispatcher, destination, &actual_size,
153 platform_handles_.get())) { 149 platform_handles_.get())) {
154 handle_table[i].type = static_cast<int32_t>(dispatcher->GetType()); 150 handle_table[i].type = static_cast<int32_t>(dispatcher->GetType());
155 handle_table[i].offset = static_cast<uint32_t>(current_offset); 151 handle_table[i].offset = static_cast<uint32_t>(current_offset);
156 handle_table[i].size = static_cast<uint32_t>(actual_size); 152 handle_table[i].size = static_cast<uint32_t>(actual_size);
157 // (Okay to not set |unused| since we cleared the entire buffer.) 153 // (Okay to not set |unused| since we cleared the entire buffer.)
158 154
159 #if DCHECK_IS_ON() 155 #if DCHECK_IS_ON()
160 DCHECK_LE(actual_size, all_max_sizes[i]); 156 DCHECK_LE(actual_size, all_max_sizes[i]);
161 DCHECK_LE(platform_handles_ 157 DCHECK_LE(platform_handles_
162 ? (platform_handles_->size() - old_platform_handles_size) 158 ? (platform_handles_->size() - old_platform_handles_size)
(...skipping 22 matching lines...) Expand all
185 } 181 }
186 182
187 // There's no aligned realloc, so it's no good way to release unused space (if 183 // There's no aligned realloc, so it's no good way to release unused space (if
188 // we overshot our estimated space requirements). 184 // we overshot our estimated space requirements).
189 buffer_size_ = current_offset; 185 buffer_size_ = current_offset;
190 186
191 // |dispatchers_| will be destroyed as it goes out of scope. 187 // |dispatchers_| will be destroyed as it goes out of scope.
192 } 188 }
193 189
194 TransportData::TransportData( 190 TransportData::TransportData(
195 embedder::ScopedPlatformHandleVectorPtr platform_handles, 191 ScopedPlatformHandleVectorPtr platform_handles,
196 size_t serialized_platform_handle_size) 192 size_t serialized_platform_handle_size)
197 : buffer_size_(), platform_handles_(platform_handles.Pass()) { 193 : buffer_size_(), platform_handles_(platform_handles.Pass()) {
198 buffer_size_ = MessageInTransit::RoundUpMessageAlignment( 194 buffer_size_ = MessageInTransit::RoundUpMessageAlignment(
199 sizeof(Header) + 195 sizeof(Header) +
200 platform_handles_->size() * serialized_platform_handle_size); 196 platform_handles_->size() * serialized_platform_handle_size);
201 buffer_.reset(static_cast<char*>( 197 buffer_.reset(static_cast<char*>(
202 base::AlignedAlloc(buffer_size_, MessageInTransit::kMessageAlignment))); 198 base::AlignedAlloc(buffer_size_, MessageInTransit::kMessageAlignment)));
203 memset(buffer_.get(), 0, buffer_size_); 199 memset(buffer_.get(), 0, buffer_size_);
204 200
205 Header* header = reinterpret_cast<Header*>(buffer_.get()); 201 Header* header = reinterpret_cast<Header*>(buffer_.get());
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 const Header* header = static_cast<const Header*>(transport_data_buffer); 298 const Header* header = static_cast<const Header*>(transport_data_buffer);
303 *num_platform_handles = header->num_platform_handles; 299 *num_platform_handles = header->num_platform_handles;
304 *platform_handle_table = static_cast<const char*>(transport_data_buffer) + 300 *platform_handle_table = static_cast<const char*>(transport_data_buffer) +
305 header->platform_handle_table_offset; 301 header->platform_handle_table_offset;
306 } 302 }
307 303
308 // static 304 // static
309 scoped_ptr<DispatcherVector> TransportData::DeserializeDispatchers( 305 scoped_ptr<DispatcherVector> TransportData::DeserializeDispatchers(
310 const void* buffer, 306 const void* buffer,
311 size_t buffer_size, 307 size_t buffer_size,
312 embedder::ScopedPlatformHandleVectorPtr platform_handles, 308 ScopedPlatformHandleVectorPtr platform_handles) {
313 Channel* channel) {
314 DCHECK(buffer); 309 DCHECK(buffer);
315 DCHECK_GT(buffer_size, 0u); 310 DCHECK_GT(buffer_size, 0u);
316 DCHECK(channel);
317 311
318 const Header* header = static_cast<const Header*>(buffer); 312 const Header* header = static_cast<const Header*>(buffer);
319 const size_t num_handles = header->num_handles; 313 const size_t num_handles = header->num_handles;
320 scoped_ptr<DispatcherVector> dispatchers(new DispatcherVector(num_handles)); 314 scoped_ptr<DispatcherVector> dispatchers(new DispatcherVector(num_handles));
321 315
322 const HandleTableEntry* handle_table = 316 const HandleTableEntry* handle_table =
323 reinterpret_cast<const HandleTableEntry*>( 317 reinterpret_cast<const HandleTableEntry*>(
324 static_cast<const char*>(buffer) + sizeof(Header)); 318 static_cast<const char*>(buffer) + sizeof(Header));
325 for (size_t i = 0; i < num_handles; i++) { 319 for (size_t i = 0; i < num_handles; i++) {
326 size_t offset = handle_table[i].offset; 320 size_t offset = handle_table[i].offset;
327 size_t size = handle_table[i].size; 321 size_t size = handle_table[i].size;
328 // Should already have been checked by |ValidateBuffer()|: 322 // Should already have been checked by |ValidateBuffer()|:
329 DCHECK_EQ(offset % MessageInTransit::kMessageAlignment, 0u); 323 DCHECK_EQ(offset % MessageInTransit::kMessageAlignment, 0u);
330 DCHECK_LE(offset, buffer_size); 324 DCHECK_LE(offset, buffer_size);
331 DCHECK_LE(offset + size, buffer_size); 325 DCHECK_LE(offset + size, buffer_size);
332 326
333 const void* source = static_cast<const char*>(buffer) + offset; 327 const void* source = static_cast<const char*>(buffer) + offset;
334 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize( 328 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize(
335 channel, handle_table[i].type, source, size, platform_handles.get()); 329 handle_table[i].type, source, size, platform_handles.get());
336 } 330 }
337 331
338 return dispatchers.Pass(); 332 return dispatchers.Pass();
339 } 333 }
340 334
341 } // namespace system 335 } // namespace edk
342 } // namespace mojo 336 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698