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" | |
14 #include "mojo/system/constants.h" | 13 #include "mojo/system/constants.h" |
15 | 14 |
16 namespace mojo { | 15 namespace mojo { |
17 namespace system { | 16 namespace system { |
18 | 17 |
19 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type | 18 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
20 MessageInTransit::kTypeMessagePipeEndpoint; | 19 MessageInTransit::kTypeMessagePipeEndpoint; |
21 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type | 20 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
22 MessageInTransit::kTypeMessagePipe; | 21 MessageInTransit::kTypeMessagePipe; |
23 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type | 22 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 | 98 |
100 return true; | 99 return true; |
101 } | 100 } |
102 | 101 |
103 MessageInTransit::MessageInTransit(Type type, | 102 MessageInTransit::MessageInTransit(Type type, |
104 Subtype subtype, | 103 Subtype subtype, |
105 uint32_t num_bytes, | 104 uint32_t num_bytes, |
106 uint32_t num_handles, | 105 uint32_t num_handles, |
107 const void* bytes) | 106 const void* bytes) |
108 : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)), | 107 : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)), |
109 main_buffer_(base::AlignedAlloc(main_buffer_size_, kMessageAlignment)), | 108 main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_, |
110 secondary_buffer_size_(0), | 109 kMessageAlignment))), |
111 secondary_buffer_(NULL) { | 110 secondary_buffer_size_(0) { |
112 DCHECK_LE(num_bytes, kMaxMessageNumBytes); | 111 DCHECK_LE(num_bytes, kMaxMessageNumBytes); |
113 DCHECK_LE(num_handles, kMaxMessageNumHandles); | 112 DCHECK_LE(num_handles, kMaxMessageNumHandles); |
114 | 113 |
115 // |total_size| is updated below, from the other values. | 114 // |total_size| is updated below, from the other values. |
116 header()->type = type; | 115 header()->type = type; |
117 header()->subtype = subtype; | 116 header()->subtype = subtype; |
118 header()->source_id = kInvalidEndpointId; | 117 header()->source_id = kInvalidEndpointId; |
119 header()->destination_id = kInvalidEndpointId; | 118 header()->destination_id = kInvalidEndpointId; |
120 header()->num_bytes = num_bytes; | 119 header()->num_bytes = num_bytes; |
121 header()->num_handles = num_handles; | 120 header()->num_handles = num_handles; |
122 // Note: If dispatchers are subsequently attached (in particular, if | 121 // Note: If dispatchers are subsequently attached (in particular, if |
123 // |num_handles| is nonzero), then |total_size| will have to be adjusted. | 122 // |num_handles| is nonzero), then |total_size| will have to be adjusted. |
124 UpdateTotalSize(); | 123 UpdateTotalSize(); |
125 | 124 |
126 if (bytes) { | 125 if (bytes) { |
127 memcpy(MessageInTransit::bytes(), bytes, num_bytes); | 126 memcpy(MessageInTransit::bytes(), bytes, num_bytes); |
128 memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0, | 127 memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0, |
129 main_buffer_size_ - sizeof(Header) - num_bytes); | 128 main_buffer_size_ - sizeof(Header) - num_bytes); |
130 } else { | 129 } else { |
131 memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header)); | 130 memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header)); |
132 } | 131 } |
133 } | 132 } |
134 | 133 |
135 // TODO(vtl): Do I really want/need to copy the secondary buffer here, or should | 134 // TODO(vtl): Do I really want/need to copy the secondary buffer here, or should |
136 // I just create (deserialize) the dispatchers right away? | 135 // I just create (deserialize) the dispatchers right away? |
137 MessageInTransit::MessageInTransit(const View& message_view) | 136 MessageInTransit::MessageInTransit(const View& message_view) |
138 : main_buffer_size_(message_view.main_buffer_size()), | 137 : main_buffer_size_(message_view.main_buffer_size()), |
139 main_buffer_(base::AlignedAlloc(main_buffer_size_, kMessageAlignment)), | 138 main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_, |
139 kMessageAlignment))), | |
140 secondary_buffer_size_(message_view.secondary_buffer_size()), | 140 secondary_buffer_size_(message_view.secondary_buffer_size()), |
141 secondary_buffer_(secondary_buffer_size_ ? | 141 secondary_buffer_(secondary_buffer_size_ ? |
142 base::AlignedAlloc(secondary_buffer_size_, | 142 static_cast<char*>( |
143 kMessageAlignment) : NULL) { | 143 base::AlignedAlloc(secondary_buffer_size_, |
144 kMessageAlignment)) : NULL) { | |
144 DCHECK_GE(main_buffer_size_, sizeof(Header)); | 145 DCHECK_GE(main_buffer_size_, sizeof(Header)); |
145 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); | 146 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); |
146 | 147 |
147 memcpy(main_buffer_, message_view.main_buffer(), main_buffer_size_); | 148 memcpy(main_buffer_.get(), message_view.main_buffer(), main_buffer_size_); |
148 memcpy(secondary_buffer_, message_view.secondary_buffer(), | 149 memcpy(secondary_buffer_.get(), message_view.secondary_buffer(), |
149 secondary_buffer_size_); | 150 secondary_buffer_size_); |
150 | 151 |
151 DCHECK_EQ(main_buffer_size_, | 152 DCHECK_EQ(main_buffer_size_, |
152 RoundUpMessageAlignment(sizeof(Header) + num_bytes())); | 153 RoundUpMessageAlignment(sizeof(Header) + num_bytes())); |
153 } | 154 } |
154 | 155 |
155 MessageInTransit::~MessageInTransit() { | 156 MessageInTransit::~MessageInTransit() { |
156 base::AlignedFree(main_buffer_); | |
157 base::AlignedFree(secondary_buffer_); // Okay if null. | |
158 | |
159 if (dispatchers_) { | 157 if (dispatchers_) { |
160 for (size_t i = 0; i < dispatchers_->size(); i++) { | 158 for (size_t i = 0; i < dispatchers_->size(); i++) { |
161 if (!(*dispatchers_)[i]) | 159 if (!(*dispatchers_)[i]) |
162 continue; | 160 continue; |
163 | 161 |
164 DCHECK((*dispatchers_)[i]->HasOneRef()); | 162 DCHECK((*dispatchers_)[i]->HasOneRef()); |
165 (*dispatchers_)[i]->Close(); | 163 (*dispatchers_)[i]->Close(); |
166 } | 164 } |
167 } | 165 } |
168 | 166 |
169 if (platform_handles_) { | 167 if (platform_handles_) { |
170 for (size_t i = 0; i < platform_handles_->size(); i++) | 168 for (size_t i = 0; i < platform_handles_->size(); i++) |
171 (*platform_handles_)[i].CloseIfNecessary(); | 169 (*platform_handles_)[i].CloseIfNecessary(); |
172 } | 170 } |
173 | 171 |
174 #ifndef NDEBUG | 172 #ifndef NDEBUG |
175 main_buffer_size_ = 0; | |
176 main_buffer_ = NULL; | |
177 secondary_buffer_size_ = 0; | 173 secondary_buffer_size_ = 0; |
178 secondary_buffer_ = NULL; | |
179 dispatchers_.reset(); | 174 dispatchers_.reset(); |
180 platform_handles_.reset(); | 175 platform_handles_.reset(); |
181 #endif | 176 #endif |
182 } | 177 } |
183 | 178 |
184 // static | 179 // static |
185 bool MessageInTransit::GetNextMessageSize(const void* buffer, | 180 bool MessageInTransit::GetNextMessageSize(const void* buffer, |
186 size_t buffer_size, | 181 size_t buffer_size, |
187 size_t* next_message_size) { | 182 size_t* next_message_size) { |
188 DCHECK(next_message_size); | 183 DCHECK(next_message_size); |
(...skipping 20 matching lines...) Expand all Loading... | |
209 dispatchers_ = dispatchers.Pass(); | 204 dispatchers_ = dispatchers.Pass(); |
210 #ifndef NDEBUG | 205 #ifndef NDEBUG |
211 for (size_t i = 0; i < dispatchers_->size(); i++) | 206 for (size_t i = 0; i < dispatchers_->size(); i++) |
212 DCHECK(!(*dispatchers_)[i] || (*dispatchers_)[i]->HasOneRef()); | 207 DCHECK(!(*dispatchers_)[i] || (*dispatchers_)[i]->HasOneRef()); |
213 #endif | 208 #endif |
214 } | 209 } |
215 | 210 |
216 void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) { | 211 void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) { |
217 DCHECK(channel); | 212 DCHECK(channel); |
218 DCHECK(!secondary_buffer_); | 213 DCHECK(!secondary_buffer_); |
219 CHECK_EQ(num_handles(), | |
220 dispatchers_ ? dispatchers_->size() : static_cast<size_t>(0)); | |
221 | 214 |
222 if (!num_handles()) | 215 const size_t num_handles = dispatchers_ ? dispatchers_->size() : 0; |
216 if (!num_handles) | |
223 return; | 217 return; |
224 | 218 |
225 // The offset to the start of the (Mojo) handle table. | 219 // The offset to the start of the (Mojo) handle table. |
226 // TODO(vtl): Add a header to the secondary buffer. | 220 // TODO(vtl): Add a header to the secondary buffer. |
227 const size_t handle_table_start_offset = 0; | 221 const size_t handle_table_start_offset = 0; |
228 // The offset to the start of the serialized dispatcher data. | 222 // The offset to the start of the serialized dispatcher data. |
229 const size_t serialized_dispatcher_start_offset = | 223 const size_t serialized_dispatcher_start_offset = |
230 handle_table_start_offset + num_handles() * sizeof(HandleTableEntry); | 224 handle_table_start_offset + num_handles * sizeof(HandleTableEntry); |
231 // The size of the secondary buffer we'll add to this as we go along). | 225 // The estimated size of the secondary buffer. We compute this estimate below. |
232 size_t size = serialized_dispatcher_start_offset; | 226 // It must be at least as big as the (eventual) actual size. |
227 size_t estimated_size = serialized_dispatcher_start_offset; | |
233 size_t num_platform_handles = 0; | 228 size_t num_platform_handles = 0; |
234 #if DCHECK_IS_ON | 229 #if DCHECK_IS_ON |
235 std::vector<size_t> all_max_sizes(num_handles()); | 230 std::vector<size_t> all_max_sizes(num_handles); |
236 std::vector<size_t> all_max_platform_handles(num_handles()); | 231 std::vector<size_t> all_max_platform_handles(num_handles); |
237 #endif | 232 #endif |
238 for (size_t i = 0; i < num_handles(); i++) { | 233 for (size_t i = 0; i < num_handles; i++) { |
239 if (Dispatcher* dispatcher = (*dispatchers_)[i].get()) { | 234 if (Dispatcher* dispatcher = (*dispatchers_)[i].get()) { |
240 size_t max_size = 0; | 235 size_t max_size = 0; |
241 size_t max_platform_handles = 0; | 236 size_t max_platform_handles = 0; |
242 Dispatcher::MessageInTransitAccess::StartSerialize( | 237 Dispatcher::MessageInTransitAccess::StartSerialize( |
243 dispatcher, channel, &max_size, &max_platform_handles); | 238 dispatcher, channel, &max_size, &max_platform_handles); |
244 | 239 |
245 DCHECK_LE(max_size, kMaxSerializedDispatcherSize); | 240 DCHECK_LE(max_size, kMaxSerializedDispatcherSize); |
246 size += RoundUpMessageAlignment(max_size); | 241 estimated_size += RoundUpMessageAlignment(max_size); |
247 DCHECK_LE(size, kMaxSecondaryBufferSize); | 242 DCHECK_LE(estimated_size, kMaxSecondaryBufferSize); |
248 | 243 |
249 DCHECK_LE(max_platform_handles, | 244 DCHECK_LE(max_platform_handles, |
250 kMaxSerializedDispatcherPlatformHandles); | 245 kMaxSerializedDispatcherPlatformHandles); |
251 num_platform_handles += max_platform_handles; | 246 num_platform_handles += max_platform_handles; |
252 DCHECK_LE(num_platform_handles, kMaxPlatformHandles); | 247 DCHECK_LE(num_platform_handles, kMaxPlatformHandles); |
253 | 248 |
254 #if DCHECK_IS_ON | 249 #if DCHECK_IS_ON |
255 all_max_sizes[i] = max_size; | 250 all_max_sizes[i] = max_size; |
256 all_max_platform_handles[i] = max_platform_handles; | 251 all_max_platform_handles[i] = max_platform_handles; |
257 #endif | 252 #endif |
258 } | 253 } |
259 } | 254 } |
260 | 255 |
261 secondary_buffer_ = base::AlignedAlloc(size, kMessageAlignment); | 256 secondary_buffer_.reset(static_cast<char*>( |
262 secondary_buffer_size_ = static_cast<uint32_t>(size); | 257 base::AlignedAlloc(estimated_size, kMessageAlignment))); |
263 // Entirely clear out the secondary buffer, since then we won't have to worry | 258 // Entirely clear out the secondary buffer, since then we won't have to worry |
264 // about clearing padding or unused space (e.g., if a dispatcher fails to | 259 // about clearing padding or unused space (e.g., if a dispatcher fails to |
265 // serialize). | 260 // serialize). |
266 memset(secondary_buffer_, 0, size); | 261 memset(secondary_buffer_.get(), 0, estimated_size); |
267 | 262 |
268 if (num_platform_handles > 0) { | 263 if (num_platform_handles > 0) { |
269 DCHECK(!platform_handles_); | 264 DCHECK(!platform_handles_); |
270 platform_handles_.reset(new std::vector<embedder::PlatformHandle>()); | 265 platform_handles_.reset(new std::vector<embedder::PlatformHandle>()); |
271 } | 266 } |
272 | 267 |
273 HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>( | 268 HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>( |
274 static_cast<char*>(secondary_buffer_) + handle_table_start_offset); | 269 secondary_buffer_.get() + handle_table_start_offset); |
275 size_t current_offset = serialized_dispatcher_start_offset; | 270 size_t current_offset = serialized_dispatcher_start_offset; |
276 for (size_t i = 0; i < num_handles(); i++) { | 271 for (size_t i = 0; i < num_handles; i++) { |
277 Dispatcher* dispatcher = (*dispatchers_)[i].get(); | 272 Dispatcher* dispatcher = (*dispatchers_)[i].get(); |
278 if (!dispatcher) { | 273 if (!dispatcher) { |
279 COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0, | 274 COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0, |
280 value_of_Dispatcher_kTypeUnknown_must_be_zero); | 275 value_of_Dispatcher_kTypeUnknown_must_be_zero); |
281 continue; | 276 continue; |
282 } | 277 } |
283 | 278 |
284 #if DCHECK_IS_ON | 279 #if DCHECK_IS_ON |
285 size_t old_platform_handles_size = | 280 size_t old_platform_handles_size = |
286 platform_handles_ ? platform_handles_->size() : 0; | 281 platform_handles_ ? platform_handles_->size() : 0; |
287 #endif | 282 #endif |
288 | 283 |
289 void* destination = static_cast<char*>(secondary_buffer_) + current_offset; | 284 void* destination = secondary_buffer_.get() + current_offset; |
290 size_t actual_size = 0; | 285 size_t actual_size = 0; |
291 if (Dispatcher::MessageInTransitAccess::EndSerializeAndClose( | 286 if (Dispatcher::MessageInTransitAccess::EndSerializeAndClose( |
292 dispatcher, channel, destination, &actual_size, | 287 dispatcher, channel, destination, &actual_size, |
293 platform_handles_.get())) { | 288 platform_handles_.get())) { |
294 handle_table[i].type = static_cast<int32_t>(dispatcher->GetType()); | 289 handle_table[i].type = static_cast<int32_t>(dispatcher->GetType()); |
295 handle_table[i].offset = static_cast<uint32_t>(current_offset); | 290 handle_table[i].offset = static_cast<uint32_t>(current_offset); |
296 handle_table[i].size = static_cast<uint32_t>(actual_size); | 291 handle_table[i].size = static_cast<uint32_t>(actual_size); |
297 | 292 |
298 #if DCHECK_IS_ON | 293 #if DCHECK_IS_ON |
299 DCHECK_LE(actual_size, all_max_sizes[i]); | 294 DCHECK_LE(actual_size, all_max_sizes[i]); |
300 DCHECK_LE(platform_handles_ ? (platform_handles_->size() - | 295 DCHECK_LE(platform_handles_ ? (platform_handles_->size() - |
301 old_platform_handles_size) : 0, | 296 old_platform_handles_size) : 0, |
302 all_max_platform_handles[i]); | 297 all_max_platform_handles[i]); |
303 #endif | 298 #endif |
304 } else { | 299 } else { |
305 // Nothing to do on failure, since |secondary_buffer_| was cleared, and | 300 // Nothing to do on failure, since |secondary_buffer_| was cleared, and |
306 // |kTypeUnknown| is zero. The handle was simply closed. | 301 // |kTypeUnknown| is zero. The handle was simply closed. |
307 LOG(ERROR) << "Failed to serialize handle to remote message pipe"; | 302 LOG(ERROR) << "Failed to serialize handle to remote message pipe"; |
308 } | 303 } |
309 | 304 |
310 current_offset += RoundUpMessageAlignment(actual_size); | 305 current_offset += RoundUpMessageAlignment(actual_size); |
311 DCHECK_LE(current_offset, size); | 306 DCHECK_LE(current_offset, estimated_size); |
312 DCHECK_LE(platform_handles_ ? platform_handles_->size() : 0, | 307 DCHECK_LE(platform_handles_ ? platform_handles_->size() : 0, |
313 num_platform_handles); | 308 num_platform_handles); |
314 } | 309 } |
315 | 310 |
311 // There's no aligned realloc, so it's no good way to release unused space (if | |
darin (slow to review)
2014/05/01 04:13:50
would it be worth trying to invent an aligned real
| |
312 // we overshot our estimated space requirements). | |
313 secondary_buffer_size_ = current_offset; | |
314 | |
315 // The dispatchers (which we "owned") were closed. We can dispose of them now. | |
316 dispatchers_.reset(); | |
317 | |
318 // Update the sizes in the message header. | |
316 UpdateTotalSize(); | 319 UpdateTotalSize(); |
317 } | 320 } |
318 | 321 |
319 // Note: The message's secondary buffer should have been checked by calling | 322 // Note: The message's secondary buffer should have been checked by calling |
320 // |View::IsValid()| (on the |View|) first. | 323 // |View::IsValid()| (on the |View|) first. |
321 void MessageInTransit::DeserializeDispatchers(Channel* channel) { | 324 void MessageInTransit::DeserializeDispatchers(Channel* channel) { |
322 DCHECK(!dispatchers_); | 325 DCHECK(!dispatchers_); |
323 | 326 |
324 // Already checked by |View::IsValid()|: | 327 // Already checked by |View::IsValid()|: |
325 DCHECK_LE(num_handles(), kMaxMessageNumHandles); | 328 DCHECK_LE(num_handles(), kMaxMessageNumHandles); |
326 | 329 |
327 if (!num_handles()) | 330 if (!num_handles()) |
328 return; | 331 return; |
329 | 332 |
330 dispatchers_.reset( | 333 dispatchers_.reset( |
331 new std::vector<scoped_refptr<Dispatcher> >(num_handles())); | 334 new std::vector<scoped_refptr<Dispatcher> >(num_handles())); |
332 | 335 |
333 size_t handle_table_size = num_handles() * sizeof(HandleTableEntry); | 336 size_t handle_table_size = num_handles() * sizeof(HandleTableEntry); |
334 // Already checked by |View::IsValid()|: | 337 // Already checked by |View::IsValid()|: |
335 DCHECK_LE(handle_table_size, secondary_buffer_size_); | 338 DCHECK_LE(handle_table_size, secondary_buffer_size_); |
336 | 339 |
337 const HandleTableEntry* handle_table = | 340 const HandleTableEntry* handle_table = |
338 static_cast<const HandleTableEntry*>(secondary_buffer_); | 341 reinterpret_cast<const HandleTableEntry*>(secondary_buffer_.get()); |
339 for (size_t i = 0; i < num_handles(); i++) { | 342 for (size_t i = 0; i < num_handles(); i++) { |
340 size_t offset = handle_table[i].offset; | 343 size_t offset = handle_table[i].offset; |
341 size_t size = handle_table[i].size; | 344 size_t size = handle_table[i].size; |
342 // Already checked by |View::IsValid()|: | 345 // Already checked by |View::IsValid()|: |
343 DCHECK_EQ(offset % kMessageAlignment, 0u); | 346 DCHECK_EQ(offset % kMessageAlignment, 0u); |
344 DCHECK_LE(offset, secondary_buffer_size_); | 347 DCHECK_LE(offset, secondary_buffer_size_); |
345 DCHECK_LE(offset + size, secondary_buffer_size_); | 348 DCHECK_LE(offset + size, secondary_buffer_size_); |
346 | 349 |
347 const void* source = static_cast<const char*>(secondary_buffer_) + offset; | 350 const void* source = secondary_buffer_.get() + offset; |
348 (*dispatchers_)[i] = Dispatcher::MessageInTransitAccess::Deserialize( | 351 (*dispatchers_)[i] = Dispatcher::MessageInTransitAccess::Deserialize( |
349 channel, handle_table[i].type, source, size); | 352 channel, handle_table[i].type, source, size); |
350 } | 353 } |
351 } | 354 } |
352 | 355 |
353 // Validates the secondary buffer. Returns null on success, or a human-readable | 356 // Validates the secondary buffer. Returns null on success, or a human-readable |
354 // error message on error. | 357 // error message on error. |
355 // static | 358 // static |
356 const char* MessageInTransit::ValidateSecondaryBuffer( | 359 const char* MessageInTransit::ValidateSecondaryBuffer( |
357 size_t num_handles, | 360 size_t num_handles, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 | 407 |
405 void MessageInTransit::UpdateTotalSize() { | 408 void MessageInTransit::UpdateTotalSize() { |
406 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); | 409 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); |
407 DCHECK_EQ(secondary_buffer_size_ % kMessageAlignment, 0u); | 410 DCHECK_EQ(secondary_buffer_size_ % kMessageAlignment, 0u); |
408 header()->total_size = | 411 header()->total_size = |
409 static_cast<uint32_t>(main_buffer_size_ + secondary_buffer_size_); | 412 static_cast<uint32_t>(main_buffer_size_ + secondary_buffer_size_); |
410 } | 413 } |
411 | 414 |
412 } // namespace system | 415 } // namespace system |
413 } // namespace mojo | 416 } // namespace mojo |
OLD | NEW |