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

Side by Side Diff: mojo/edk/system/data_pipe.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
(Empty)
1 // Copyright 2015 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/data_pipe.h"
6
7 #include <string.h>
8
9 #include "mojo/edk/system/configuration.h"
10 #include "mojo/edk/system/options_validation.h"
11 #include "mojo/edk/system/raw_channel.h"
12 #include "mojo/edk/system/transport_data.h"
13
14 namespace mojo {
15 namespace edk {
16
17 namespace {
18
19 const size_t kInvalidDataPipeHandleIndex = static_cast<size_t>(-1);
20
21 struct MOJO_ALIGNAS(8) SerializedDataPipeHandleDispatcher {
22 size_t platform_handle_index; // (Or |kInvalidDataPipeHandleIndex|.)
23
24 // These are from MojoCreateDataPipeOptions
25 MojoCreateDataPipeOptionsFlags flags;
26 uint32_t element_num_bytes;
27 uint32_t capacity_num_bytes;
28
29 size_t shared_memory_handle_index; // (Or |kInvalidDataPipeHandleIndex|.)
30 uint32_t shared_memory_size;
31 };
32
33 } // namespace
34
35 MojoCreateDataPipeOptions DataPipe::GetDefaultCreateOptions() {
36 MojoCreateDataPipeOptions result = {
37 static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)),
38 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
39 1u,
40 static_cast<uint32_t>(
41 GetConfiguration().default_data_pipe_capacity_bytes)};
42 return result;
43 }
44
45 MojoResult DataPipe::ValidateCreateOptions(
46 const MojoCreateDataPipeOptions* in_options,
47 MojoCreateDataPipeOptions* out_options) {
48 const MojoCreateDataPipeOptionsFlags kKnownFlags =
49 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
50
51 *out_options = GetDefaultCreateOptions();
52 if (!in_options)
53 return MOJO_RESULT_OK;
54
55 UserOptionsReader<MojoCreateDataPipeOptions> reader(in_options);
56 if (!reader.is_valid())
57 return MOJO_RESULT_INVALID_ARGUMENT;
58
59 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, flags, reader))
60 return MOJO_RESULT_OK;
61 if ((reader.options().flags & ~kKnownFlags))
62 return MOJO_RESULT_UNIMPLEMENTED;
63 out_options->flags = reader.options().flags;
64
65 // Checks for fields beyond |flags|:
66
67 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, element_num_bytes,
68 reader))
69 return MOJO_RESULT_OK;
70 if (reader.options().element_num_bytes == 0)
71 return MOJO_RESULT_INVALID_ARGUMENT;
72 out_options->element_num_bytes = reader.options().element_num_bytes;
73
74 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, capacity_num_bytes,
75 reader) ||
76 reader.options().capacity_num_bytes == 0) {
77 // Round the default capacity down to a multiple of the element size (but at
78 // least one element).
79 size_t default_data_pipe_capacity_bytes =
80 GetConfiguration().default_data_pipe_capacity_bytes;
81 out_options->capacity_num_bytes =
82 std::max(static_cast<uint32_t>(default_data_pipe_capacity_bytes -
83 (default_data_pipe_capacity_bytes %
84 out_options->element_num_bytes)),
85 out_options->element_num_bytes);
86 return MOJO_RESULT_OK;
87 }
88 if (reader.options().capacity_num_bytes % out_options->element_num_bytes != 0)
89 return MOJO_RESULT_INVALID_ARGUMENT;
90 if (reader.options().capacity_num_bytes >
91 GetConfiguration().max_data_pipe_capacity_bytes)
92 return MOJO_RESULT_RESOURCE_EXHAUSTED;
93 out_options->capacity_num_bytes = reader.options().capacity_num_bytes;
94
95 return MOJO_RESULT_OK;
96 }
97
98 void DataPipe::StartSerialize(bool have_channel_handle,
99 bool have_shared_memory,
100 size_t* max_size,
101 size_t* max_platform_handles) {
102 *max_size = sizeof(SerializedDataPipeHandleDispatcher);
103 *max_platform_handles = 0;
104 if (have_channel_handle)
105 (*max_platform_handles)++;
106 if (have_shared_memory)
107 (*max_platform_handles)++;
108 DCHECK_LE(*max_size, TransportData::kMaxSerializedDispatcherSize);
109 }
110
111 void DataPipe::EndSerialize(const MojoCreateDataPipeOptions& options,
112 ScopedPlatformHandle channel_handle,
113 ScopedPlatformHandle shared_memory_handle,
114 size_t shared_memory_size,
115 void* destination,
116 size_t* actual_size,
117 PlatformHandleVector* platform_handles) {
118 SerializedDataPipeHandleDispatcher* serialization =
119 static_cast<SerializedDataPipeHandleDispatcher*>(destination);
120 if (channel_handle.is_valid()) {
121 serialization->platform_handle_index = platform_handles->size();
122 platform_handles->push_back(channel_handle.release());
123 } else {
124 serialization->platform_handle_index = kInvalidDataPipeHandleIndex;
125 }
126
127 serialization->flags = options.flags;
128 serialization->element_num_bytes = options.element_num_bytes;
129 serialization->capacity_num_bytes = options.capacity_num_bytes;
130
131 serialization->shared_memory_size = static_cast<uint32_t>(shared_memory_size);
132 if (serialization->shared_memory_size) {
133 serialization->shared_memory_handle_index = platform_handles->size();
134 platform_handles->push_back(shared_memory_handle.release());
135 }
136
137 *actual_size = sizeof(SerializedDataPipeHandleDispatcher);
138 }
139
140 ScopedPlatformHandle DataPipe::Deserialize(
141 const void* source,
142 size_t size,
143 PlatformHandleVector* platform_handles,
144 MojoCreateDataPipeOptions* options,
145 ScopedPlatformHandle* shared_memory_handle,
146 size_t* shared_memory_size) {
147 if (size != sizeof(SerializedDataPipeHandleDispatcher)) {
148 LOG(ERROR) << "Invalid serialized platform handle dispatcher (bad size)";
149 return ScopedPlatformHandle();
150 }
151
152 const SerializedDataPipeHandleDispatcher* serialization =
153 static_cast<const SerializedDataPipeHandleDispatcher*>(source);
154 size_t platform_handle_index = serialization->platform_handle_index;
155
156 // Starts off invalid, which is what we want.
157 PlatformHandle platform_handle;
158 if (platform_handle_index != kInvalidDataPipeHandleIndex) {
159 if (!platform_handles ||
160 platform_handle_index >= platform_handles->size()) {
161 LOG(ERROR)
162 << "Invalid serialized platform handle dispatcher (missing handles)";
163 return ScopedPlatformHandle();
164 }
165
166 // We take ownership of the handle, so we have to invalidate the one in
167 // |platform_handles|.
168 std::swap(platform_handle, (*platform_handles)[platform_handle_index]);
169 }
170
171 options->struct_size = sizeof(MojoCreateDataPipeOptions);
172 options->flags = serialization->flags;
173 options->element_num_bytes = serialization->element_num_bytes;
174 options->capacity_num_bytes = serialization->capacity_num_bytes;
175
176 if (shared_memory_size) {
177 *shared_memory_size = serialization->shared_memory_size;
178 if (*shared_memory_size) {
179 DCHECK(serialization->shared_memory_handle_index !=
180 kInvalidDataPipeHandleIndex);
181 if (!serialization->shared_memory_handle_index ||
182 serialization->shared_memory_handle_index >=
183 platform_handles->size()) {
184 LOG(ERROR) << "Invalid serialized platform handle dispatcher "
185 << "(missing handles)";
186 return ScopedPlatformHandle();
187 }
188
189 PlatformHandle temp_shared_memory_handle;
190 std::swap(temp_shared_memory_handle,
191 (*platform_handles)[serialization->shared_memory_handle_index]);
192 *shared_memory_handle =
193 ScopedPlatformHandle(temp_shared_memory_handle);
194 }
195 }
196
197 size -= sizeof(SerializedDataPipeHandleDispatcher);
198
199 return ScopedPlatformHandle(platform_handle);
200 }
201
202 } // namespace edk
203 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698