14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/message_in_transit.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string.h>
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/compiler_specific.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "mojo/system/constants.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/system/transport_data.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace mojo {
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace system {
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    MessageInTransit::kTypeMessagePipeEndpoint;
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    MessageInTransit::kTypeMessagePipe;
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    MessageInTransit::kTypeChannel;
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MessageInTransit::kTypeRawChannel;
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    MessageInTransit::kSubtypeMessagePipeEndpointData;
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint;
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint;
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck;
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles;
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    MessageInTransit::kInvalidEndpointId;
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSTATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment;
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct MessageInTransit::PrivateStructForCompileAsserts {
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // The size of |Header| must be a multiple of the alignment.
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  COMPILE_ASSERT(sizeof(Header) % kMessageAlignment == 0,
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 sizeof_MessageInTransit_Header_invalid);
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Avoid dangerous situations, but making sure that the size of the "header" +
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the size of the data fits into a 31-bit number.
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  COMPILE_ASSERT(static_cast<uint64_t>(sizeof(Header)) + kMaxMessageNumBytes <=
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     0x7fffffffULL,
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 kMaxMessageNumBytes_too_big);
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // We assume (to avoid extra rounding code) that the maximum message (data)
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // size is a multiple of the alignment.
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  COMPILE_ASSERT(kMaxMessageNumBytes % kMessageAlignment == 0,
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 kMessageAlignment_not_a_multiple_of_alignment);
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MessageInTransit::View::View(size_t message_size, const void* buffer)
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : buffer_(buffer) {
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t next_message_size = 0;
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size,
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              &next_message_size));
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(message_size, next_message_size);
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This should be equivalent.
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(message_size, total_size());
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MessageInTransit::View::IsValid(size_t serialized_platform_handle_size,
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     const char** error_message) const {
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Note: This also implies a check on the |main_buffer_size()|, which is just
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |RoundUpMessageAlignment(sizeof(Header) + num_bytes())|.
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (num_bytes() > kMaxMessageNumBytes) {
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *error_message = "Message data payload too large";
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (transport_data_buffer_size() > 0) {
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const char* e =
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        TransportData::ValidateBuffer(serialized_platform_handle_size,
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      transport_data_buffer(),
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      transport_data_buffer_size());
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (e) {
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      *error_message = e;
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return true;
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MessageInTransit::MessageInTransit(Type type,
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   Subtype subtype,
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   uint32_t num_bytes,
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   const void* bytes)
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)),
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_,
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                         kMessageAlignment))) {
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_LE(num_bytes, kMaxMessageNumBytes);
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |total_size| is updated below, from the other values.
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header()->type = type;
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header()->subtype = subtype;
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header()->source_id = kInvalidEndpointId;
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header()->destination_id = kInvalidEndpointId;
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header()->num_bytes = num_bytes;
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  header()->unused = 0;
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Note: If dispatchers are subsequently attached, then |total_size| will have
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // to be adjusted.
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  UpdateTotalSize();
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (bytes) {
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memcpy(MessageInTransit::bytes(), bytes, num_bytes);
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0,
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           main_buffer_size_ - sizeof(Header) - num_bytes);
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header));
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MessageInTransit::MessageInTransit(const View& message_view)
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : main_buffer_size_(message_view.main_buffer_size()),
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_,
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                         kMessageAlignment))) {
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_GE(main_buffer_size_, sizeof(Header));
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  memcpy(main_buffer_.get(), message_view.main_buffer(), main_buffer_size_);
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(main_buffer_size_,
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            RoundUpMessageAlignment(sizeof(Header) + num_bytes()));
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MessageInTransit::~MessageInTransit() {
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (dispatchers_) {
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (size_t i = 0; i < dispatchers_->size(); i++) {
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (!(*dispatchers_)[i])
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        continue;
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK((*dispatchers_)[i]->HasOneRef());
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      (*dispatchers_)[i]->Close();
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MessageInTransit::GetNextMessageSize(const void* buffer,
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                          size_t buffer_size,
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                          size_t* next_message_size) {
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(next_message_size);
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!buffer_size)
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(buffer);
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(reinterpret_cast<uintptr_t>(buffer) %
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                MessageInTransit::kMessageAlignment, 0u);
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (buffer_size < sizeof(Header))
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const Header* header = static_cast<const Header*>(buffer);
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  *next_message_size = header->total_size;
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(*next_message_size % kMessageAlignment, 0u);
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MessageInTransit::SetDispatchers(
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<DispatcherVector> dispatchers) {
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(dispatchers);
164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(!dispatchers_);
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!transport_data_);
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dispatchers_ = dispatchers.Pass();
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef NDEBUG
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < dispatchers_->size(); i++)
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(!(*dispatchers_)[i] || (*dispatchers_)[i]->HasOneRef());
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void MessageInTransit::SetTransportData(
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<TransportData> transport_data) {
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(transport_data);
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!transport_data_);
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!dispatchers_);
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  transport_data_ = transport_data.Pass();
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) {
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(channel);
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(!transport_data_);
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!dispatchers_ || !dispatchers_->size())
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  transport_data_.reset(new TransportData(dispatchers_.Pass(), channel));
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Update the sizes in the message header.
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  UpdateTotalSize();
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MessageInTransit::UpdateTotalSize() {
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  header()->total_size = static_cast<uint32_t>(main_buffer_size_);
199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (transport_data_) {
200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    header()->total_size +=
201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        static_cast<uint32_t>(transport_data_->buffer_size());
202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace system
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace mojo
207