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

Side by Side Diff: mojo/edk/system/shared_buffer_dispatcher.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
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 "third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.h" 5 #include "mojo/edk/system/shared_buffer_dispatcher.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "mojo/edk/embedder/embedder_internal.h"
12 #include "mojo/edk/embedder/platform_support.h"
13 #include "mojo/edk/system/configuration.h"
14 #include "mojo/edk/system/options_validation.h"
11 #include "mojo/public/c/system/macros.h" 15 #include "mojo/public/c/system/macros.h"
12 #include "third_party/mojo/src/mojo/edk/embedder/platform_support.h"
13 #include "third_party/mojo/src/mojo/edk/system/channel.h"
14 #include "third_party/mojo/src/mojo/edk/system/configuration.h"
15 #include "third_party/mojo/src/mojo/edk/system/memory.h"
16 #include "third_party/mojo/src/mojo/edk/system/options_validation.h"
17 16
18 namespace mojo { 17 namespace mojo {
19 namespace system { 18 namespace edk {
20 19
21 namespace { 20 namespace {
22 21
23 struct SerializedSharedBufferDispatcher { 22 struct MOJO_ALIGNAS(8) SerializedSharedBufferDispatcher {
24 size_t num_bytes; 23 size_t num_bytes;
25 size_t platform_handle_index; 24 size_t platform_handle_index;
26 }; 25 };
27 26
28 } // namespace 27 } // namespace
29 28
30 // static 29 // static
31 const MojoCreateSharedBufferOptions 30 const MojoCreateSharedBufferOptions
32 SharedBufferDispatcher::kDefaultCreateOptions = { 31 SharedBufferDispatcher::kDefaultCreateOptions = {
33 static_cast<uint32_t>(sizeof(MojoCreateSharedBufferOptions)), 32 static_cast<uint32_t>(sizeof(MojoCreateSharedBufferOptions)),
34 MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE}; 33 MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE};
35 34
36 // static 35 // static
37 MojoResult SharedBufferDispatcher::ValidateCreateOptions( 36 MojoResult SharedBufferDispatcher::ValidateCreateOptions(
38 UserPointer<const MojoCreateSharedBufferOptions> in_options, 37 const MojoCreateSharedBufferOptions* in_options,
39 MojoCreateSharedBufferOptions* out_options) { 38 MojoCreateSharedBufferOptions* out_options) {
40 const MojoCreateSharedBufferOptionsFlags kKnownFlags = 39 const MojoCreateSharedBufferOptionsFlags kKnownFlags =
41 MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE; 40 MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE;
42 41
43 *out_options = kDefaultCreateOptions; 42 *out_options = kDefaultCreateOptions;
44 if (in_options.IsNull()) 43 if (!in_options)
45 return MOJO_RESULT_OK; 44 return MOJO_RESULT_OK;
46 45
47 UserOptionsReader<MojoCreateSharedBufferOptions> reader(in_options); 46 UserOptionsReader<MojoCreateSharedBufferOptions> reader(in_options);
48 if (!reader.is_valid()) 47 if (!reader.is_valid())
49 return MOJO_RESULT_INVALID_ARGUMENT; 48 return MOJO_RESULT_INVALID_ARGUMENT;
50 49
51 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateSharedBufferOptions, flags, reader)) 50 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateSharedBufferOptions, flags, reader))
52 return MOJO_RESULT_OK; 51 return MOJO_RESULT_OK;
53 if ((reader.options().flags & ~kKnownFlags)) 52 if ((reader.options().flags & ~kKnownFlags))
54 return MOJO_RESULT_UNIMPLEMENTED; 53 return MOJO_RESULT_UNIMPLEMENTED;
55 out_options->flags = reader.options().flags; 54 out_options->flags = reader.options().flags;
56 55
57 // Checks for fields beyond |flags|: 56 // Checks for fields beyond |flags|:
58 57
59 // (Nothing here yet.) 58 // (Nothing here yet.)
60 59
61 return MOJO_RESULT_OK; 60 return MOJO_RESULT_OK;
62 } 61 }
63 62
64 // static 63 // static
65 MojoResult SharedBufferDispatcher::Create( 64 MojoResult SharedBufferDispatcher::Create(
66 embedder::PlatformSupport* platform_support, 65 PlatformSupport* platform_support,
67 const MojoCreateSharedBufferOptions& /*validated_options*/, 66 const MojoCreateSharedBufferOptions& /*validated_options*/,
68 uint64_t num_bytes, 67 uint64_t num_bytes,
69 scoped_refptr<SharedBufferDispatcher>* result) { 68 scoped_refptr<SharedBufferDispatcher>* result) {
70 if (!num_bytes) 69 if (!num_bytes)
71 return MOJO_RESULT_INVALID_ARGUMENT; 70 return MOJO_RESULT_INVALID_ARGUMENT;
72 if (num_bytes > GetConfiguration().max_shared_memory_num_bytes) 71 if (num_bytes > GetConfiguration().max_shared_memory_num_bytes)
73 return MOJO_RESULT_RESOURCE_EXHAUSTED; 72 return MOJO_RESULT_RESOURCE_EXHAUSTED;
74 73
75 scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer( 74 scoped_refptr<PlatformSharedBuffer> shared_buffer(
76 platform_support->CreateSharedBuffer(static_cast<size_t>(num_bytes))); 75 platform_support->CreateSharedBuffer(static_cast<size_t>(num_bytes)));
77 if (!shared_buffer) 76 if (!shared_buffer)
78 return MOJO_RESULT_RESOURCE_EXHAUSTED; 77 return MOJO_RESULT_RESOURCE_EXHAUSTED;
79 78
80 *result = CreateInternal(shared_buffer.Pass()); 79 *result = CreateInternal(shared_buffer.Pass());
81 return MOJO_RESULT_OK; 80 return MOJO_RESULT_OK;
82 } 81 }
83 82
84 Dispatcher::Type SharedBufferDispatcher::GetType() const { 83 Dispatcher::Type SharedBufferDispatcher::GetType() const {
85 return Type::SHARED_BUFFER; 84 return Type::SHARED_BUFFER;
86 } 85 }
87 86
88 // static 87 // static
89 scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize( 88 scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize(
90 Channel* channel,
91 const void* source, 89 const void* source,
92 size_t size, 90 size_t size,
93 embedder::PlatformHandleVector* platform_handles) { 91 PlatformHandleVector* platform_handles) {
94 DCHECK(channel);
95 92
96 if (size != sizeof(SerializedSharedBufferDispatcher)) { 93 if (size != sizeof(SerializedSharedBufferDispatcher)) {
97 LOG(ERROR) << "Invalid serialized shared buffer dispatcher (bad size)"; 94 LOG(ERROR) << "Invalid serialized shared buffer dispatcher (bad size)";
98 return nullptr; 95 return nullptr;
99 } 96 }
100 97
101 const SerializedSharedBufferDispatcher* serialization = 98 const SerializedSharedBufferDispatcher* serialization =
102 static_cast<const SerializedSharedBufferDispatcher*>(source); 99 static_cast<const SerializedSharedBufferDispatcher*>(source);
103 size_t num_bytes = serialization->num_bytes; 100 size_t num_bytes = serialization->num_bytes;
104 size_t platform_handle_index = serialization->platform_handle_index; 101 size_t platform_handle_index = serialization->platform_handle_index;
105 102
106 if (!num_bytes) { 103 if (!num_bytes) {
107 LOG(ERROR) 104 LOG(ERROR)
108 << "Invalid serialized shared buffer dispatcher (invalid num_bytes)"; 105 << "Invalid serialized shared buffer dispatcher (invalid num_bytes)";
109 return nullptr; 106 return nullptr;
110 } 107 }
111 108
112 if (!platform_handles || platform_handle_index >= platform_handles->size()) { 109 if (!platform_handles || platform_handle_index >= platform_handles->size()) {
113 LOG(ERROR) 110 LOG(ERROR)
114 << "Invalid serialized shared buffer dispatcher (missing handles)"; 111 << "Invalid serialized shared buffer dispatcher (missing handles)";
115 return nullptr; 112 return nullptr;
116 } 113 }
117 114
118 // Starts off invalid, which is what we want. 115 // Starts off invalid, which is what we want.
119 embedder::PlatformHandle platform_handle; 116 PlatformHandle platform_handle;
120 // We take ownership of the handle, so we have to invalidate the one in 117 // We take ownership of the handle, so we have to invalidate the one in
121 // |platform_handles|. 118 // |platform_handles|.
122 std::swap(platform_handle, (*platform_handles)[platform_handle_index]); 119 std::swap(platform_handle, (*platform_handles)[platform_handle_index]);
123 120
124 // Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be 121 // Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be
125 // closed even if creation fails. 122 // closed even if creation fails.
126 scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer( 123 scoped_refptr<PlatformSharedBuffer> shared_buffer(
127 channel->platform_support()->CreateSharedBufferFromHandle( 124 internal::g_platform_support->CreateSharedBufferFromHandle(
128 num_bytes, embedder::ScopedPlatformHandle(platform_handle))); 125 num_bytes, ScopedPlatformHandle(platform_handle)));
129 if (!shared_buffer) { 126 if (!shared_buffer) {
130 LOG(ERROR) 127 LOG(ERROR)
131 << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)"; 128 << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)";
132 return nullptr; 129 return nullptr;
133 } 130 }
134 131
135 return CreateInternal(shared_buffer.Pass()); 132 return CreateInternal(shared_buffer.Pass());
136 } 133 }
137 134
138 SharedBufferDispatcher::SharedBufferDispatcher( 135 SharedBufferDispatcher::SharedBufferDispatcher(
139 scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer) 136 scoped_refptr<PlatformSharedBuffer> shared_buffer)
140 : shared_buffer_(shared_buffer) { 137 : shared_buffer_(shared_buffer) {
141 DCHECK(shared_buffer_); 138 DCHECK(shared_buffer_);
142 } 139 }
143 140
144 SharedBufferDispatcher::~SharedBufferDispatcher() { 141 SharedBufferDispatcher::~SharedBufferDispatcher() {
145 } 142 }
146 143
147 // static 144 // static
148 MojoResult SharedBufferDispatcher::ValidateDuplicateOptions( 145 MojoResult SharedBufferDispatcher::ValidateDuplicateOptions(
149 UserPointer<const MojoDuplicateBufferHandleOptions> in_options, 146 const MojoDuplicateBufferHandleOptions* in_options,
150 MojoDuplicateBufferHandleOptions* out_options) { 147 MojoDuplicateBufferHandleOptions* out_options) {
151 const MojoDuplicateBufferHandleOptionsFlags kKnownFlags = 148 const MojoDuplicateBufferHandleOptionsFlags kKnownFlags =
152 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE; 149 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE;
153 static const MojoDuplicateBufferHandleOptions kDefaultOptions = { 150 static const MojoDuplicateBufferHandleOptions kDefaultOptions = {
154 static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)), 151 static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)),
155 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE}; 152 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE};
156 153
157 *out_options = kDefaultOptions; 154 *out_options = kDefaultOptions;
158 if (in_options.IsNull()) 155 if (!in_options)
159 return MOJO_RESULT_OK; 156 return MOJO_RESULT_OK;
160 157
161 UserOptionsReader<MojoDuplicateBufferHandleOptions> reader(in_options); 158 UserOptionsReader<MojoDuplicateBufferHandleOptions> reader(in_options);
162 if (!reader.is_valid()) 159 if (!reader.is_valid())
163 return MOJO_RESULT_INVALID_ARGUMENT; 160 return MOJO_RESULT_INVALID_ARGUMENT;
164 161
165 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoDuplicateBufferHandleOptions, flags, 162 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoDuplicateBufferHandleOptions, flags,
166 reader)) 163 reader))
167 return MOJO_RESULT_OK; 164 return MOJO_RESULT_OK;
168 if ((reader.options().flags & ~kKnownFlags)) 165 if ((reader.options().flags & ~kKnownFlags))
169 return MOJO_RESULT_UNIMPLEMENTED; 166 return MOJO_RESULT_UNIMPLEMENTED;
170 out_options->flags = reader.options().flags; 167 out_options->flags = reader.options().flags;
171 168
172 // Checks for fields beyond |flags|: 169 // Checks for fields beyond |flags|:
173 170
174 // (Nothing here yet.) 171 // (Nothing here yet.)
175 172
176 return MOJO_RESULT_OK; 173 return MOJO_RESULT_OK;
177 } 174 }
178 175
179 void SharedBufferDispatcher::CloseImplNoLock() { 176 void SharedBufferDispatcher::CloseImplNoLock() {
180 mutex().AssertHeld(); 177 lock().AssertAcquired();
181 DCHECK(shared_buffer_); 178 DCHECK(shared_buffer_);
182 shared_buffer_ = nullptr; 179 shared_buffer_ = nullptr;
183 } 180 }
184 181
185 scoped_refptr<Dispatcher> 182 scoped_refptr<Dispatcher>
186 SharedBufferDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { 183 SharedBufferDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
187 mutex().AssertHeld(); 184 lock().AssertAcquired();
188 DCHECK(shared_buffer_); 185 DCHECK(shared_buffer_);
189 return CreateInternal(shared_buffer_.Pass()); 186 return CreateInternal(shared_buffer_.Pass());
190 } 187 }
191 188
192 MojoResult SharedBufferDispatcher::DuplicateBufferHandleImplNoLock( 189 MojoResult SharedBufferDispatcher::DuplicateBufferHandleImplNoLock(
193 UserPointer<const MojoDuplicateBufferHandleOptions> options, 190 const MojoDuplicateBufferHandleOptions* options,
194 scoped_refptr<Dispatcher>* new_dispatcher) { 191 scoped_refptr<Dispatcher>* new_dispatcher) {
195 mutex().AssertHeld(); 192 lock().AssertAcquired();
196 193
197 MojoDuplicateBufferHandleOptions validated_options; 194 MojoDuplicateBufferHandleOptions validated_options;
198 MojoResult result = ValidateDuplicateOptions(options, &validated_options); 195 MojoResult result = ValidateDuplicateOptions(options, &validated_options);
199 if (result != MOJO_RESULT_OK) 196 if (result != MOJO_RESULT_OK)
200 return result; 197 return result;
201 198
202 // Note: Since this is "duplicate", we keep our ref to |shared_buffer_|. 199 // Note: Since this is "duplicate", we keep our ref to |shared_buffer_|.
203 *new_dispatcher = CreateInternal(shared_buffer_); 200 *new_dispatcher = CreateInternal(shared_buffer_);
204 return MOJO_RESULT_OK; 201 return MOJO_RESULT_OK;
205 } 202 }
206 203
207 MojoResult SharedBufferDispatcher::MapBufferImplNoLock( 204 MojoResult SharedBufferDispatcher::MapBufferImplNoLock(
208 uint64_t offset, 205 uint64_t offset,
209 uint64_t num_bytes, 206 uint64_t num_bytes,
210 MojoMapBufferFlags flags, 207 MojoMapBufferFlags flags,
211 scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping) { 208 scoped_ptr<PlatformSharedBufferMapping>* mapping) {
212 mutex().AssertHeld(); 209 lock().AssertAcquired();
213 DCHECK(shared_buffer_); 210 DCHECK(shared_buffer_);
214 211
215 if (offset > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) 212 if (offset > static_cast<uint64_t>(std::numeric_limits<size_t>::max()))
216 return MOJO_RESULT_INVALID_ARGUMENT; 213 return MOJO_RESULT_INVALID_ARGUMENT;
217 if (num_bytes > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) 214 if (num_bytes > static_cast<uint64_t>(std::numeric_limits<size_t>::max()))
218 return MOJO_RESULT_INVALID_ARGUMENT; 215 return MOJO_RESULT_INVALID_ARGUMENT;
219 216
220 if (!shared_buffer_->IsValidMap(static_cast<size_t>(offset), 217 if (!shared_buffer_->IsValidMap(static_cast<size_t>(offset),
221 static_cast<size_t>(num_bytes))) 218 static_cast<size_t>(num_bytes)))
222 return MOJO_RESULT_INVALID_ARGUMENT; 219 return MOJO_RESULT_INVALID_ARGUMENT;
223 220
224 DCHECK(mapping); 221 DCHECK(mapping);
225 *mapping = shared_buffer_->MapNoCheck(static_cast<size_t>(offset), 222 *mapping = shared_buffer_->MapNoCheck(static_cast<size_t>(offset),
226 static_cast<size_t>(num_bytes)); 223 static_cast<size_t>(num_bytes));
227 if (!*mapping) 224 if (!*mapping)
228 return MOJO_RESULT_RESOURCE_EXHAUSTED; 225 return MOJO_RESULT_RESOURCE_EXHAUSTED;
229 226
230 return MOJO_RESULT_OK; 227 return MOJO_RESULT_OK;
231 } 228 }
232 229
233 void SharedBufferDispatcher::StartSerializeImplNoLock( 230 void SharedBufferDispatcher::StartSerializeImplNoLock(
234 Channel* /*channel*/,
235 size_t* max_size, 231 size_t* max_size,
236 size_t* max_platform_handles) { 232 size_t* max_platform_handles) {
237 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 233 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
238 *max_size = sizeof(SerializedSharedBufferDispatcher); 234 *max_size = sizeof(SerializedSharedBufferDispatcher);
239 *max_platform_handles = 1; 235 *max_platform_handles = 1;
240 } 236 }
241 237
242 bool SharedBufferDispatcher::EndSerializeAndCloseImplNoLock( 238 bool SharedBufferDispatcher::EndSerializeAndCloseImplNoLock(
243 Channel* /*channel*/,
244 void* destination, 239 void* destination,
245 size_t* actual_size, 240 size_t* actual_size,
246 embedder::PlatformHandleVector* platform_handles) { 241 PlatformHandleVector* platform_handles) {
247 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 242 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
248 DCHECK(shared_buffer_); 243 DCHECK(shared_buffer_);
249 244
250 SerializedSharedBufferDispatcher* serialization = 245 SerializedSharedBufferDispatcher* serialization =
251 static_cast<SerializedSharedBufferDispatcher*>(destination); 246 static_cast<SerializedSharedBufferDispatcher*>(destination);
252 // If there's only one reference to |shared_buffer_|, then it's ours (and no 247 // If there's only one reference to |shared_buffer_|, then it's ours (and no
253 // one else can make any more references to it), so we can just take its 248 // one else can make any more references to it), so we can just take its
254 // handle. 249 // handle.
255 embedder::ScopedPlatformHandle platform_handle( 250 ScopedPlatformHandle platform_handle(
256 shared_buffer_->HasOneRef() ? shared_buffer_->PassPlatformHandle() 251 shared_buffer_->HasOneRef() ? shared_buffer_->PassPlatformHandle()
257 : shared_buffer_->DuplicatePlatformHandle()); 252 : shared_buffer_->DuplicatePlatformHandle());
258 if (!platform_handle.is_valid()) { 253 if (!platform_handle.is_valid()) {
259 shared_buffer_ = nullptr; 254 shared_buffer_ = nullptr;
260 return false; 255 return false;
261 } 256 }
262 257
263 serialization->num_bytes = shared_buffer_->GetNumBytes(); 258 serialization->num_bytes = shared_buffer_->GetNumBytes();
264 serialization->platform_handle_index = platform_handles->size(); 259 serialization->platform_handle_index = platform_handles->size();
265 platform_handles->push_back(platform_handle.release()); 260 platform_handles->push_back(platform_handle.release());
266 *actual_size = sizeof(SerializedSharedBufferDispatcher); 261 *actual_size = sizeof(SerializedSharedBufferDispatcher);
267 262
268 shared_buffer_ = nullptr; 263 shared_buffer_ = nullptr;
269 264
270 return true; 265 return true;
271 } 266 }
272 267
273 } // namespace system 268
269 } // namespace edk
274 } // namespace mojo 270 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698