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

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

Issue 1956843002: EDK: Make TransportData preserve handle rights. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « mojo/edk/system/transport_data.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "mojo/edk/system/transport_data.h" 5 #include "mojo/edk/system/transport_data.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "mojo/edk/system/channel.h" 12 #include "mojo/edk/system/channel.h"
13 #include "mojo/edk/system/configuration.h" 13 #include "mojo/edk/system/configuration.h"
14 #include "mojo/edk/system/message_in_transit.h" 14 #include "mojo/edk/system/message_in_transit.h"
15 15
16 using mojo::platform::AlignedAlloc; 16 using mojo::platform::AlignedAlloc;
17 using mojo::platform::ScopedPlatformHandle; 17 using mojo::platform::ScopedPlatformHandle;
18 18
19 namespace mojo { 19 namespace mojo {
20 namespace system { 20 namespace system {
21 21
22 namespace {
23
24 // TODO(vtl): Temporary, until |TransportData| really supports handles.
25 std::unique_ptr<DispatcherVector> DispatcherVectorFromHandleVector(
26 std::unique_ptr<HandleVector> handles) {
27 DCHECK(handles);
28
29 std::unique_ptr<DispatcherVector> dispatchers(new DispatcherVector());
30 dispatchers->reserve(handles->size());
31 for (size_t i = 0; i < handles->size(); i++)
32 dispatchers->push_back(std::move(handles->at(i).dispatcher));
33 return dispatchers;
34 }
35
36 } // namespace
37
38 // The maximum amount of space needed per platform handle. 22 // The maximum amount of space needed per platform handle.
39 // (|{Channel,RawChannel}::GetSerializedPlatformHandleSize()| should always 23 // (|{Channel,RawChannel}::GetSerializedPlatformHandleSize()| should always
40 // return a value which is at most this. This is only used to calculate 24 // return a value which is at most this. This is only used to calculate
41 // |TransportData::kMaxBufferSize|. This value should be a multiple of the 25 // |TransportData::kMaxBufferSize|. This value should be a multiple of the
42 // alignment in order to simplify calculations, even though the actual amount of 26 // alignment in order to simplify calculations, even though the actual amount of
43 // space needed need not be a multiple of the alignment. 27 // space needed need not be a multiple of the alignment.
44 const size_t kMaxSizePerPlatformHandle = 8; 28 const size_t kMaxSizePerPlatformHandle = 8;
45 static_assert(kMaxSizePerPlatformHandle % MessageInTransit::kMessageAlignment == 29 static_assert(kMaxSizePerPlatformHandle % MessageInTransit::kMessageAlignment ==
46 0, 30 0,
47 "kMaxSizePerPlatformHandle not a multiple of alignment"); 31 "kMaxSizePerPlatformHandle not a multiple of alignment");
(...skipping 24 matching lines...) Expand all
72 MessageInTransit::kMessageAlignment == 56 MessageInTransit::kMessageAlignment ==
73 0, 57 0,
74 "kMaxSerializedDispatcherSize not a multiple of alignment"); 58 "kMaxSerializedDispatcherSize not a multiple of alignment");
75 static_assert(sizeof(HandleTableEntry) % 59 static_assert(sizeof(HandleTableEntry) %
76 MessageInTransit::kMessageAlignment == 60 MessageInTransit::kMessageAlignment ==
77 0, 61 0,
78 "sizeof(MessageInTransit::HandleTableEntry) not a multiple of " 62 "sizeof(MessageInTransit::HandleTableEntry) not a multiple of "
79 "alignment"); 63 "alignment");
80 }; 64 };
81 65
82 // TODO(vtl): Make this the real one.
83 TransportData::TransportData(std::unique_ptr<HandleVector> handles, 66 TransportData::TransportData(std::unique_ptr<HandleVector> handles,
84 Channel* channel) 67 Channel* channel)
85 : TransportData(DispatcherVectorFromHandleVector(std::move(handles)),
86 channel) {}
87
88 TransportData::TransportData(std::unique_ptr<DispatcherVector> dispatchers,
89 Channel* channel)
90 : buffer_size_() { 68 : buffer_size_() {
91 DCHECK(dispatchers); 69 DCHECK(handles);
92 DCHECK(channel); 70 DCHECK(channel);
93 71
94 const size_t num_handles = dispatchers->size(); 72 const size_t num_handles = handles->size();
95 DCHECK_GT(num_handles, 0u); 73 DCHECK_GT(num_handles, 0u);
96 74
97 // The offset to the start of the (Mojo) handle table. 75 // The offset to the start of the (Mojo) handle table.
98 const size_t handle_table_start_offset = sizeof(Header); 76 const size_t handle_table_start_offset = sizeof(Header);
99 // The offset to the start of the serialized dispatcher data. 77 // The offset to the start of the serialized dispatcher data.
100 const size_t serialized_dispatcher_start_offset = 78 const size_t serialized_dispatcher_start_offset =
101 handle_table_start_offset + num_handles * sizeof(HandleTableEntry); 79 handle_table_start_offset + num_handles * sizeof(HandleTableEntry);
102 // The estimated size of the secondary buffer. We compute this estimate below. 80 // The estimated size of the secondary buffer. We compute this estimate below.
103 // It must be at least as big as the (eventual) actual size. 81 // It must be at least as big as the (eventual) actual size.
104 size_t estimated_size = serialized_dispatcher_start_offset; 82 size_t estimated_size = serialized_dispatcher_start_offset;
105 size_t estimated_num_platform_handles = 0; 83 size_t estimated_num_platform_handles = 0;
106 #if DCHECK_IS_ON() 84 #if DCHECK_IS_ON()
107 std::vector<size_t> all_max_sizes(num_handles); 85 std::vector<size_t> all_max_sizes(num_handles);
108 std::vector<size_t> all_max_platform_handles(num_handles); 86 std::vector<size_t> all_max_platform_handles(num_handles);
109 #endif 87 #endif
110 for (size_t i = 0; i < num_handles; i++) { 88 for (size_t i = 0; i < num_handles; i++) {
111 if (Dispatcher* dispatcher = (*dispatchers)[i].get()) { 89 if (handles->at(i)) {
112 size_t max_size = 0; 90 size_t max_size = 0;
113 size_t max_platform_handles = 0; 91 size_t max_platform_handles = 0;
114 Dispatcher::TransportDataAccess::StartSerialize( 92 Dispatcher::TransportDataAccess::StartSerialize(
115 dispatcher, channel, &max_size, &max_platform_handles); 93 handles->at(i).dispatcher.get(), channel, &max_size,
94 &max_platform_handles);
116 95
117 DCHECK_LE(max_size, kMaxSerializedDispatcherSize); 96 DCHECK_LE(max_size, kMaxSerializedDispatcherSize);
118 estimated_size += MessageInTransit::RoundUpMessageAlignment(max_size); 97 estimated_size += MessageInTransit::RoundUpMessageAlignment(max_size);
119 DCHECK_LE(estimated_size, GetMaxBufferSize()); 98 DCHECK_LE(estimated_size, GetMaxBufferSize());
120 99
121 DCHECK_LE(max_platform_handles, kMaxSerializedDispatcherPlatformHandles); 100 DCHECK_LE(max_platform_handles, kMaxSerializedDispatcherPlatformHandles);
122 estimated_num_platform_handles += max_platform_handles; 101 estimated_num_platform_handles += max_platform_handles;
123 DCHECK_LE(estimated_num_platform_handles, GetMaxPlatformHandles()); 102 DCHECK_LE(estimated_num_platform_handles, GetMaxPlatformHandles());
124 103
125 #if DCHECK_IS_ON() 104 #if DCHECK_IS_ON()
(...skipping 26 matching lines...) Expand all
152 131
153 Header* header = reinterpret_cast<Header*>(buffer_.get()); 132 Header* header = reinterpret_cast<Header*>(buffer_.get());
154 header->num_handles = static_cast<uint32_t>(num_handles); 133 header->num_handles = static_cast<uint32_t>(num_handles);
155 // (Okay to leave |platform_handle_table_offset|, |num_platform_handles|, and 134 // (Okay to leave |platform_handle_table_offset|, |num_platform_handles|, and
156 // |unused| be zero; we'll set the former two later if necessary.) 135 // |unused| be zero; we'll set the former two later if necessary.)
157 136
158 HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>( 137 HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>(
159 buffer_.get() + handle_table_start_offset); 138 buffer_.get() + handle_table_start_offset);
160 size_t current_offset = serialized_dispatcher_start_offset; 139 size_t current_offset = serialized_dispatcher_start_offset;
161 for (size_t i = 0; i < num_handles; i++) { 140 for (size_t i = 0; i < num_handles; i++) {
162 Dispatcher* dispatcher = (*dispatchers)[i].get(); 141 Handle& handle = handles->at(i);
163 if (!dispatcher) { 142 if (!handle) {
164 static_assert(static_cast<int32_t>(Dispatcher::Type::UNKNOWN) == 0, 143 static_assert(static_cast<int32_t>(Dispatcher::Type::UNKNOWN) == 0,
165 "Value of Dispatcher::Type::UNKNOWN must be 0"); 144 "Value of Dispatcher::Type::UNKNOWN must be 0");
166 continue; 145 continue;
167 } 146 }
168 147
169 #if DCHECK_IS_ON() 148 #if DCHECK_IS_ON()
170 size_t old_platform_handles_size = 149 size_t old_platform_handles_size =
171 platform_handles_ ? platform_handles_->size() : 0; 150 platform_handles_ ? platform_handles_->size() : 0;
172 #endif 151 #endif
173 152
174 void* destination = buffer_.get() + current_offset; 153 void* destination = buffer_.get() + current_offset;
175 size_t actual_size = 0; 154 size_t actual_size = 0;
176 if (Dispatcher::TransportDataAccess::EndSerializeAndClose( 155 if (Dispatcher::TransportDataAccess::EndSerializeAndClose(
177 dispatcher, channel, destination, &actual_size, 156 handle.dispatcher.get(), channel, destination, &actual_size,
178 platform_handles_.get())) { 157 platform_handles_.get())) {
179 handle_table[i].type = static_cast<int32_t>(dispatcher->GetType()); 158 handle_table[i].type = static_cast<int32_t>(handle.dispatcher->GetType());
180 handle_table[i].offset = static_cast<uint32_t>(current_offset); 159 handle_table[i].offset = static_cast<uint32_t>(current_offset);
181 handle_table[i].size = static_cast<uint32_t>(actual_size); 160 handle_table[i].size = static_cast<uint32_t>(actual_size);
182 // (Okay to not set |unused| since we cleared the entire buffer.) 161 handle_table[i].rights = handle.rights;
183 162
184 #if DCHECK_IS_ON() 163 #if DCHECK_IS_ON()
185 DCHECK_LE(actual_size, all_max_sizes[i]); 164 DCHECK_LE(actual_size, all_max_sizes[i]);
186 DCHECK_LE(platform_handles_ 165 DCHECK_LE(platform_handles_
187 ? (platform_handles_->size() - old_platform_handles_size) 166 ? (platform_handles_->size() - old_platform_handles_size)
188 : 0, 167 : 0,
189 all_max_platform_handles[i]); 168 all_max_platform_handles[i]);
190 #endif 169 #endif
191 } else { 170 } else {
192 // Nothing to do on failure, since |buffer_| was cleared, and 171 // Nothing to do on failure, since |buffer_| was cleared, and
(...skipping 12 matching lines...) Expand all
205 static_cast<uint32_t>(current_offset); 184 static_cast<uint32_t>(current_offset);
206 header->num_platform_handles = 185 header->num_platform_handles =
207 static_cast<uint32_t>(platform_handles_->size()); 186 static_cast<uint32_t>(platform_handles_->size());
208 current_offset += platform_handles_->size() * size_per_platform_handle; 187 current_offset += platform_handles_->size() * size_per_platform_handle;
209 current_offset = MessageInTransit::RoundUpMessageAlignment(current_offset); 188 current_offset = MessageInTransit::RoundUpMessageAlignment(current_offset);
210 } 189 }
211 190
212 // There's no aligned realloc, so it's no good way to release unused space (if 191 // There's no aligned realloc, so it's no good way to release unused space (if
213 // we overshot our estimated space requirements). 192 // we overshot our estimated space requirements).
214 buffer_size_ = current_offset; 193 buffer_size_ = current_offset;
215
216 // |dispatchers_| will be destroyed as it goes out of scope.
217 } 194 }
218 195
219 TransportData::TransportData( 196 TransportData::TransportData(
220 std::unique_ptr<std::vector<ScopedPlatformHandle>> platform_handles, 197 std::unique_ptr<std::vector<ScopedPlatformHandle>> platform_handles,
221 size_t serialized_platform_handle_size) 198 size_t serialized_platform_handle_size)
222 : buffer_size_(), platform_handles_(std::move(platform_handles)) { 199 : buffer_size_(), platform_handles_(std::move(platform_handles)) {
223 buffer_size_ = MessageInTransit::RoundUpMessageAlignment( 200 buffer_size_ = MessageInTransit::RoundUpMessageAlignment(
224 sizeof(Header) + 201 sizeof(Header) +
225 platform_handles_->size() * serialized_platform_handle_size); 202 platform_handles_->size() * serialized_platform_handle_size);
226 buffer_ = 203 buffer_ =
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 DCHECK(num_platform_handles); 301 DCHECK(num_platform_handles);
325 DCHECK(platform_handle_table); 302 DCHECK(platform_handle_table);
326 303
327 const Header* header = static_cast<const Header*>(transport_data_buffer); 304 const Header* header = static_cast<const Header*>(transport_data_buffer);
328 *num_platform_handles = header->num_platform_handles; 305 *num_platform_handles = header->num_platform_handles;
329 *platform_handle_table = static_cast<const char*>(transport_data_buffer) + 306 *platform_handle_table = static_cast<const char*>(transport_data_buffer) +
330 header->platform_handle_table_offset; 307 header->platform_handle_table_offset;
331 } 308 }
332 309
333 // static 310 // static
334 std::unique_ptr<DispatcherVector> TransportData::DeserializeDispatchers( 311 std::unique_ptr<HandleVector> TransportData::DeserializeHandles(
335 const void* buffer, 312 const void* buffer,
336 size_t buffer_size, 313 size_t buffer_size,
337 std::unique_ptr<std::vector<ScopedPlatformHandle>> platform_handles, 314 std::unique_ptr<std::vector<ScopedPlatformHandle>> platform_handles,
338 Channel* channel) { 315 Channel* channel) {
339 DCHECK(buffer); 316 DCHECK(buffer);
340 DCHECK_GT(buffer_size, 0u); 317 DCHECK_GT(buffer_size, 0u);
341 DCHECK(channel); 318 DCHECK(channel);
342 319
343 const Header* header = static_cast<const Header*>(buffer); 320 const Header* header = static_cast<const Header*>(buffer);
344 const size_t num_handles = header->num_handles; 321 const size_t num_handles = header->num_handles;
345 std::unique_ptr<DispatcherVector> dispatchers( 322 std::unique_ptr<HandleVector> handles(new HandleVector(num_handles));
346 new DispatcherVector(num_handles));
347 323
348 const HandleTableEntry* handle_table = 324 const HandleTableEntry* handle_table =
349 reinterpret_cast<const HandleTableEntry*>( 325 reinterpret_cast<const HandleTableEntry*>(
350 static_cast<const char*>(buffer) + sizeof(Header)); 326 static_cast<const char*>(buffer) + sizeof(Header));
351 for (size_t i = 0; i < num_handles; i++) { 327 for (size_t i = 0; i < num_handles; i++) {
352 size_t offset = handle_table[i].offset; 328 size_t offset = handle_table[i].offset;
353 size_t size = handle_table[i].size; 329 size_t size = handle_table[i].size;
354 // Should already have been checked by |ValidateBuffer()|: 330 // Should already have been checked by |ValidateBuffer()|:
355 DCHECK_EQ(offset % MessageInTransit::kMessageAlignment, 0u); 331 DCHECK_EQ(offset % MessageInTransit::kMessageAlignment, 0u);
356 DCHECK_LE(offset, buffer_size); 332 DCHECK_LE(offset, buffer_size);
357 DCHECK_LE(offset + size, buffer_size); 333 DCHECK_LE(offset + size, buffer_size);
358 334
359 const void* source = static_cast<const char*>(buffer) + offset; 335 const void* source = static_cast<const char*>(buffer) + offset;
360 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize( 336 (*handles)[i] = Handle(Dispatcher::TransportDataAccess::Deserialize(
361 channel, handle_table[i].type, source, size, platform_handles.get()); 337 channel, handle_table[i].type, source, size,
338 platform_handles.get()),
339 handle_table[i].rights);
362 } 340 }
363 341
364 return dispatchers; 342 return handles;
365 } 343 }
366 344
367 } // namespace system 345 } // namespace system
368 } // namespace mojo 346 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/transport_data.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698