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

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

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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/message_in_transit.h ('k') | mojo/edk/system/message_in_transit_queue.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "mojo/edk/system/message_in_transit.h"
6
7 #include <string.h>
8
9 #include "base/compiler_specific.h"
10 #include "base/logging.h"
11 #include "mojo/edk/system/configuration.h"
12 #include "mojo/edk/system/transport_data.h"
13
14 namespace mojo {
15 namespace system {
16
17 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
18 MessageInTransit::kTypeEndpoint;
19 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
20 MessageInTransit::kTypeChannel;
21 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
22 MessageInTransit::kTypeRawChannel;
23 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
24 MessageInTransit::kSubtypeEndpointData;
25 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
26 MessageInTransit::kSubtypeChannelAttachAndRunEndpoint;
27 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
28 MessageInTransit::kSubtypeChannelRemoveEndpoint;
29 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
30 MessageInTransit::kSubtypeChannelRemoveEndpointAck;
31 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
32 MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles;
33 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment;
34
35 struct MessageInTransit::PrivateStructForCompileAsserts {
36 // The size of |Header| must be a multiple of the alignment.
37 static_assert(sizeof(Header) % kMessageAlignment == 0,
38 "sizeof(MessageInTransit::Header) invalid");
39 };
40
41 MessageInTransit::View::View(size_t message_size, const void* buffer)
42 : buffer_(buffer) {
43 size_t next_message_size = 0;
44 DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size,
45 &next_message_size));
46 DCHECK_EQ(message_size, next_message_size);
47 // This should be equivalent.
48 DCHECK_EQ(message_size, total_size());
49 }
50
51 bool MessageInTransit::View::IsValid(size_t serialized_platform_handle_size,
52 const char** error_message) const {
53 size_t max_message_num_bytes = GetConfiguration().max_message_num_bytes;
54 // Avoid dangerous situations, but making sure that the size of the "header" +
55 // the size of the data fits into a 31-bit number.
56 DCHECK_LE(static_cast<uint64_t>(sizeof(Header)) + max_message_num_bytes,
57 0x7fffffffULL)
58 << "GetConfiguration().max_message_num_bytes too big";
59
60 // We assume (to avoid extra rounding code) that the maximum message (data)
61 // size is a multiple of the alignment.
62 DCHECK_EQ(max_message_num_bytes % kMessageAlignment, 0U)
63 << "GetConfiguration().max_message_num_bytes not a multiple of alignment";
64
65 // Note: This also implies a check on the |main_buffer_size()|, which is just
66 // |RoundUpMessageAlignment(sizeof(Header) + num_bytes())|.
67 if (num_bytes() > max_message_num_bytes) {
68 *error_message = "Message data payload too large";
69 return false;
70 }
71
72 if (transport_data_buffer_size() > 0) {
73 const char* e = TransportData::ValidateBuffer(
74 serialized_platform_handle_size, transport_data_buffer(),
75 transport_data_buffer_size());
76 if (e) {
77 *error_message = e;
78 return false;
79 }
80 }
81
82 return true;
83 }
84
85 MessageInTransit::MessageInTransit(Type type,
86 Subtype subtype,
87 uint32_t num_bytes,
88 const void* bytes)
89 : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)),
90 main_buffer_(static_cast<char*>(
91 base::AlignedAlloc(main_buffer_size_, kMessageAlignment))) {
92 ConstructorHelper(type, subtype, num_bytes);
93 if (bytes) {
94 memcpy(MessageInTransit::bytes(), bytes, num_bytes);
95 memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0,
96 main_buffer_size_ - sizeof(Header) - num_bytes);
97 } else {
98 memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header));
99 }
100 }
101
102 MessageInTransit::MessageInTransit(Type type,
103 Subtype subtype,
104 uint32_t num_bytes,
105 UserPointer<const void> bytes)
106 : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)),
107 main_buffer_(static_cast<char*>(
108 base::AlignedAlloc(main_buffer_size_, kMessageAlignment))) {
109 ConstructorHelper(type, subtype, num_bytes);
110 bytes.GetArray(MessageInTransit::bytes(), num_bytes);
111 memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0,
112 main_buffer_size_ - sizeof(Header) - num_bytes);
113 }
114
115 MessageInTransit::MessageInTransit(const View& message_view)
116 : main_buffer_size_(message_view.main_buffer_size()),
117 main_buffer_(static_cast<char*>(
118 base::AlignedAlloc(main_buffer_size_, kMessageAlignment))) {
119 DCHECK_GE(main_buffer_size_, sizeof(Header));
120 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
121
122 memcpy(main_buffer_.get(), message_view.main_buffer(), main_buffer_size_);
123 DCHECK_EQ(main_buffer_size_,
124 RoundUpMessageAlignment(sizeof(Header) + num_bytes()));
125 }
126
127 MessageInTransit::~MessageInTransit() {
128 if (dispatchers_) {
129 for (size_t i = 0; i < dispatchers_->size(); i++) {
130 if (!(*dispatchers_)[i])
131 continue;
132
133 DCHECK((*dispatchers_)[i]->HasOneRef());
134 (*dispatchers_)[i]->Close();
135 }
136 }
137 }
138
139 // static
140 bool MessageInTransit::GetNextMessageSize(const void* buffer,
141 size_t buffer_size,
142 size_t* next_message_size) {
143 DCHECK(next_message_size);
144 if (!buffer_size)
145 return false;
146 DCHECK(buffer);
147 DCHECK_EQ(
148 reinterpret_cast<uintptr_t>(buffer) % MessageInTransit::kMessageAlignment,
149 0u);
150
151 if (buffer_size < sizeof(Header))
152 return false;
153
154 const Header* header = static_cast<const Header*>(buffer);
155 *next_message_size = header->total_size;
156 DCHECK_EQ(*next_message_size % kMessageAlignment, 0u);
157 return true;
158 }
159
160 void MessageInTransit::SetDispatchers(
161 scoped_ptr<DispatcherVector> dispatchers) {
162 DCHECK(dispatchers);
163 DCHECK(!dispatchers_);
164 DCHECK(!transport_data_);
165
166 dispatchers_ = dispatchers.Pass();
167 #ifndef NDEBUG
168 for (size_t i = 0; i < dispatchers_->size(); i++)
169 DCHECK(!(*dispatchers_)[i] || (*dispatchers_)[i]->HasOneRef());
170 #endif
171 }
172
173 void MessageInTransit::SetTransportData(
174 scoped_ptr<TransportData> transport_data) {
175 DCHECK(transport_data);
176 DCHECK(!transport_data_);
177 DCHECK(!dispatchers_);
178
179 transport_data_ = transport_data.Pass();
180 UpdateTotalSize();
181 }
182
183 void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) {
184 DCHECK(channel);
185 DCHECK(!transport_data_);
186
187 if (!dispatchers_ || !dispatchers_->size())
188 return;
189
190 transport_data_.reset(new TransportData(dispatchers_.Pass(), channel));
191
192 // Update the sizes in the message header.
193 UpdateTotalSize();
194 }
195
196 void MessageInTransit::ConstructorHelper(Type type,
197 Subtype subtype,
198 uint32_t num_bytes) {
199 DCHECK_LE(num_bytes, GetConfiguration().max_message_num_bytes);
200
201 // |total_size| is updated below, from the other values.
202 header()->type = type;
203 header()->subtype = subtype;
204 header()->source_id = ChannelEndpointId();
205 header()->destination_id = ChannelEndpointId();
206 header()->num_bytes = num_bytes;
207 header()->unused = 0;
208 // Note: If dispatchers are subsequently attached, then |total_size| will have
209 // to be adjusted.
210 UpdateTotalSize();
211 }
212
213 void MessageInTransit::UpdateTotalSize() {
214 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
215 header()->total_size = static_cast<uint32_t>(main_buffer_size_);
216 if (transport_data_) {
217 header()->total_size +=
218 static_cast<uint32_t>(transport_data_->buffer_size());
219 }
220 }
221
222 } // namespace system
223 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/message_in_transit.h ('k') | mojo/edk/system/message_in_transit_queue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698