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

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

Powered by Google App Engine
This is Rietveld 408576698