OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "mojo/system/core.h" | 5 #include "mojo/system/core.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 // |Dispatcher| in dispatcher.h. | 116 // |Dispatcher| in dispatcher.h. |
117 return dispatcher->Close(); | 117 return dispatcher->Close(); |
118 } | 118 } |
119 | 119 |
120 MojoResult Core::Wait(MojoHandle handle, | 120 MojoResult Core::Wait(MojoHandle handle, |
121 MojoHandleSignals signals, | 121 MojoHandleSignals signals, |
122 MojoDeadline deadline) { | 122 MojoDeadline deadline) { |
123 return WaitManyInternal(&handle, &signals, 1, deadline); | 123 return WaitManyInternal(&handle, &signals, 1, deadline); |
124 } | 124 } |
125 | 125 |
126 MojoResult Core::WaitMany(const MojoHandle* handles, | 126 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, |
127 const MojoHandleSignals* signals, | 127 UserPointer<const MojoHandleSignals> signals, |
128 uint32_t num_handles, | 128 uint32_t num_handles, |
129 MojoDeadline deadline) { | 129 MojoDeadline deadline) { |
130 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles)) | |
131 return MOJO_RESULT_INVALID_ARGUMENT; | |
132 if (!VerifyUserPointerWithCount<MojoHandleSignals>(signals, num_handles)) | |
133 return MOJO_RESULT_INVALID_ARGUMENT; | |
134 if (num_handles < 1) | 130 if (num_handles < 1) |
135 return MOJO_RESULT_INVALID_ARGUMENT; | 131 return MOJO_RESULT_INVALID_ARGUMENT; |
136 if (num_handles > kMaxWaitManyNumHandles) | 132 if (num_handles > kMaxWaitManyNumHandles) |
137 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 133 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
138 return WaitManyInternal(handles, signals, num_handles, deadline); | 134 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); |
| 135 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, |
| 136 num_handles); |
| 137 return WaitManyInternal(handles_reader.GetPointer(), |
| 138 signals_reader.GetPointer(), num_handles, deadline); |
139 } | 139 } |
140 | 140 |
141 MojoResult Core::CreateMessagePipe(const MojoCreateMessagePipeOptions* options, | 141 MojoResult Core::CreateMessagePipe( |
142 MojoHandle* message_pipe_handle0, | 142 UserPointer<const MojoCreateMessagePipeOptions> options, |
143 MojoHandle* message_pipe_handle1) { | 143 UserPointer<MojoHandle> message_pipe_handle0, |
| 144 UserPointer<MojoHandle> message_pipe_handle1) { |
144 MojoCreateMessagePipeOptions validated_options = {}; | 145 MojoCreateMessagePipeOptions validated_options = {}; |
145 // This will verify the |options| pointer. | 146 // This will verify the |options| pointer. |
146 MojoResult result = MessagePipeDispatcher::ValidateCreateOptions( | 147 MojoResult result = MessagePipeDispatcher::ValidateCreateOptions( |
147 options, &validated_options); | 148 options.GetPointerUnsafe(), &validated_options); |
148 if (result != MOJO_RESULT_OK) | 149 if (result != MOJO_RESULT_OK) |
149 return result; | 150 return result; |
150 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle0)) | |
151 return MOJO_RESULT_INVALID_ARGUMENT; | |
152 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle1)) | |
153 return MOJO_RESULT_INVALID_ARGUMENT; | |
154 | 151 |
155 scoped_refptr<MessagePipeDispatcher> dispatcher0( | 152 scoped_refptr<MessagePipeDispatcher> dispatcher0( |
156 new MessagePipeDispatcher(validated_options)); | 153 new MessagePipeDispatcher(validated_options)); |
157 scoped_refptr<MessagePipeDispatcher> dispatcher1( | 154 scoped_refptr<MessagePipeDispatcher> dispatcher1( |
158 new MessagePipeDispatcher(validated_options)); | 155 new MessagePipeDispatcher(validated_options)); |
159 | 156 |
160 std::pair<MojoHandle, MojoHandle> handle_pair; | 157 std::pair<MojoHandle, MojoHandle> handle_pair; |
161 { | 158 { |
162 base::AutoLock locker(handle_table_lock_); | 159 base::AutoLock locker(handle_table_lock_); |
163 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); | 160 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); |
164 } | 161 } |
165 if (handle_pair.first == MOJO_HANDLE_INVALID) { | 162 if (handle_pair.first == MOJO_HANDLE_INVALID) { |
166 DCHECK_EQ(handle_pair.second, MOJO_HANDLE_INVALID); | 163 DCHECK_EQ(handle_pair.second, MOJO_HANDLE_INVALID); |
167 LOG(ERROR) << "Handle table full"; | 164 LOG(ERROR) << "Handle table full"; |
168 dispatcher0->Close(); | 165 dispatcher0->Close(); |
169 dispatcher1->Close(); | 166 dispatcher1->Close(); |
170 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 167 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
171 } | 168 } |
172 | 169 |
173 scoped_refptr<MessagePipe> message_pipe(new MessagePipe()); | 170 scoped_refptr<MessagePipe> message_pipe(new MessagePipe()); |
174 dispatcher0->Init(message_pipe, 0); | 171 dispatcher0->Init(message_pipe, 0); |
175 dispatcher1->Init(message_pipe, 1); | 172 dispatcher1->Init(message_pipe, 1); |
176 | 173 |
177 *message_pipe_handle0 = handle_pair.first; | 174 message_pipe_handle0.Put(handle_pair.first); |
178 *message_pipe_handle1 = handle_pair.second; | 175 message_pipe_handle1.Put(handle_pair.second); |
179 return MOJO_RESULT_OK; | 176 return MOJO_RESULT_OK; |
180 } | 177 } |
181 | 178 |
182 // Implementation note: To properly cancel waiters and avoid other races, this | 179 // Implementation note: To properly cancel waiters and avoid other races, this |
183 // does not transfer dispatchers from one handle to another, even when sending a | 180 // does not transfer dispatchers from one handle to another, even when sending a |
184 // message in-process. Instead, it must transfer the "contents" of the | 181 // message in-process. Instead, it must transfer the "contents" of the |
185 // dispatcher to a new dispatcher, and then close the old dispatcher. If this | 182 // dispatcher to a new dispatcher, and then close the old dispatcher. If this |
186 // isn't done, in the in-process case, calls on the old handle may complete | 183 // isn't done, in the in-process case, calls on the old handle may complete |
187 // after the the message has been received and a new handle created (and | 184 // after the the message has been received and a new handle created (and |
188 // possibly even after calls have been made on the new handle). | 185 // possibly even after calls have been made on the new handle). |
189 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, | 186 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, |
190 const void* bytes, | 187 UserPointer<const void> bytes, |
191 uint32_t num_bytes, | 188 uint32_t num_bytes, |
192 const MojoHandle* handles, | 189 UserPointer<const MojoHandle> handles, |
193 uint32_t num_handles, | 190 uint32_t num_handles, |
194 MojoWriteMessageFlags flags) { | 191 MojoWriteMessageFlags flags) { |
195 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); | 192 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); |
196 if (!dispatcher) | 193 if (!dispatcher) |
197 return MOJO_RESULT_INVALID_ARGUMENT; | 194 return MOJO_RESULT_INVALID_ARGUMENT; |
198 | 195 |
199 // Easy case: not sending any handles. | 196 // Easy case: not sending any handles. |
200 if (num_handles == 0) | 197 if (num_handles == 0) { |
201 return dispatcher->WriteMessage(bytes, num_bytes, NULL, flags); | 198 return dispatcher->WriteMessage(bytes.GetPointerUnsafe(), num_bytes, NULL, |
| 199 flags); |
| 200 } |
202 | 201 |
203 // We have to handle |handles| here, since we have to mark them busy in the | 202 // We have to handle |handles| here, since we have to mark them busy in the |
204 // global handle table. We can't delegate this to the dispatcher, since the | 203 // global handle table. We can't delegate this to the dispatcher, since the |
205 // handle table lock must be acquired before the dispatcher lock. | 204 // handle table lock must be acquired before the dispatcher lock. |
206 // | 205 // |
207 // (This leads to an oddity: |handles|/|num_handles| are always verified for | 206 // (This leads to an oddity: |handles|/|num_handles| are always verified for |
208 // validity, even for dispatchers that don't support |WriteMessage()| and will | 207 // validity, even for dispatchers that don't support |WriteMessage()| and will |
209 // simply return failure unconditionally. It also breaks the usual | 208 // simply return failure unconditionally. It also breaks the usual |
210 // left-to-right verification order of arguments.) | 209 // left-to-right verification order of arguments.) |
211 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles)) | |
212 return MOJO_RESULT_INVALID_ARGUMENT; | |
213 if (num_handles > kMaxMessageNumHandles) | 210 if (num_handles > kMaxMessageNumHandles) |
214 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 211 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
215 | 212 |
| 213 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); |
| 214 |
216 // We'll need to hold on to the dispatchers so that we can pass them on to | 215 // We'll need to hold on to the dispatchers so that we can pass them on to |
217 // |WriteMessage()| and also so that we can unlock their locks afterwards | 216 // |WriteMessage()| and also so that we can unlock their locks afterwards |
218 // without accessing the handle table. These can be dumb pointers, since their | 217 // without accessing the handle table. These can be dumb pointers, since their |
219 // entries in the handle table won't get removed (since they'll be marked as | 218 // entries in the handle table won't get removed (since they'll be marked as |
220 // busy). | 219 // busy). |
221 std::vector<DispatcherTransport> transports(num_handles); | 220 std::vector<DispatcherTransport> transports(num_handles); |
222 | 221 |
223 // When we pass handles, we have to try to take all their dispatchers' locks | 222 // When we pass handles, we have to try to take all their dispatchers' locks |
224 // and mark the handles as busy. If the call succeeds, we then remove the | 223 // and mark the handles as busy. If the call succeeds, we then remove the |
225 // handles from the handle table. | 224 // handles from the handle table. |
226 { | 225 { |
227 base::AutoLock locker(handle_table_lock_); | 226 base::AutoLock locker(handle_table_lock_); |
228 MojoResult result = handle_table_.MarkBusyAndStartTransport( | 227 MojoResult result = handle_table_.MarkBusyAndStartTransport( |
229 message_pipe_handle, handles, num_handles, &transports); | 228 message_pipe_handle, handles_reader.GetPointer(), num_handles, |
| 229 &transports); |
230 if (result != MOJO_RESULT_OK) | 230 if (result != MOJO_RESULT_OK) |
231 return result; | 231 return result; |
232 } | 232 } |
233 | 233 |
234 MojoResult rv = dispatcher->WriteMessage(bytes, num_bytes, &transports, | 234 MojoResult rv = dispatcher->WriteMessage(bytes.GetPointerUnsafe(), num_bytes, |
235 flags); | 235 &transports, flags); |
236 | 236 |
237 // We need to release the dispatcher locks before we take the handle table | 237 // We need to release the dispatcher locks before we take the handle table |
238 // lock. | 238 // lock. |
239 for (uint32_t i = 0; i < num_handles; i++) | 239 for (uint32_t i = 0; i < num_handles; i++) |
240 transports[i].End(); | 240 transports[i].End(); |
241 | 241 |
242 { | 242 { |
243 base::AutoLock locker(handle_table_lock_); | 243 base::AutoLock locker(handle_table_lock_); |
244 if (rv == MOJO_RESULT_OK) | 244 if (rv == MOJO_RESULT_OK) { |
245 handle_table_.RemoveBusyHandles(handles, num_handles); | 245 handle_table_.RemoveBusyHandles(handles_reader.GetPointer(), num_handles); |
246 else | 246 } else { |
247 handle_table_.RestoreBusyHandles(handles, num_handles); | 247 handle_table_.RestoreBusyHandles(handles_reader.GetPointer(), |
| 248 num_handles); |
| 249 } |
248 } | 250 } |
249 | 251 |
250 return rv; | 252 return rv; |
251 } | 253 } |
252 | 254 |
253 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, | 255 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, |
254 void* bytes, | 256 UserPointer<void> bytes, |
255 uint32_t* num_bytes, | 257 UserPointer<uint32_t> num_bytes, |
256 MojoHandle* handles, | 258 UserPointer<MojoHandle> handles, |
257 uint32_t* num_handles, | 259 UserPointer<uint32_t> num_handles, |
258 MojoReadMessageFlags flags) { | 260 MojoReadMessageFlags flags) { |
259 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); | 261 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); |
260 if (!dispatcher) | 262 if (!dispatcher) |
261 return MOJO_RESULT_INVALID_ARGUMENT; | 263 return MOJO_RESULT_INVALID_ARGUMENT; |
262 | 264 |
263 if (num_handles) { | 265 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get(); |
264 if (!VerifyUserPointer<uint32_t>(num_handles)) | |
265 return MOJO_RESULT_INVALID_ARGUMENT; | |
266 if (!VerifyUserPointerWithCount<MojoHandle>(handles, *num_handles)) | |
267 return MOJO_RESULT_INVALID_ARGUMENT; | |
268 } | |
269 | 266 |
270 // Easy case: won't receive any handles. | 267 MojoResult rv; |
271 if (!num_handles || *num_handles == 0) | 268 if (num_handles_value == 0) { |
272 return dispatcher->ReadMessage(bytes, num_bytes, NULL, num_handles, flags); | 269 // Easy case: won't receive any handles. |
| 270 rv = dispatcher->ReadMessage(bytes.GetPointerUnsafe(), |
| 271 num_bytes.GetPointerUnsafe(), NULL, |
| 272 &num_handles_value, flags); |
| 273 } else { |
| 274 DispatcherVector dispatchers; |
| 275 rv = dispatcher->ReadMessage(bytes.GetPointerUnsafe(), |
| 276 num_bytes.GetPointerUnsafe(), &dispatchers, |
| 277 &num_handles_value, flags); |
| 278 if (!dispatchers.empty()) { |
| 279 DCHECK_EQ(rv, MOJO_RESULT_OK); |
| 280 DCHECK(!num_handles.IsNull()); |
| 281 DCHECK_LE(dispatchers.size(), static_cast<size_t>(num_handles_value)); |
273 | 282 |
274 DispatcherVector dispatchers; | 283 bool success; |
275 MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes, | 284 UserPointer<MojoHandle>::Writer handles_writer(handles, |
276 &dispatchers, num_handles, | 285 dispatchers.size()); |
277 flags); | 286 { |
278 if (!dispatchers.empty()) { | 287 base::AutoLock locker(handle_table_lock_); |
279 DCHECK_EQ(rv, MOJO_RESULT_OK); | 288 success = handle_table_.AddDispatcherVector( |
280 DCHECK(num_handles); | 289 dispatchers, handles_writer.GetPointer()); |
281 DCHECK_LE(dispatchers.size(), static_cast<size_t>(*num_handles)); | 290 } |
282 | 291 if (success) { |
283 bool success; | 292 handles_writer.Commit(); |
284 { | 293 } else { |
285 base::AutoLock locker(handle_table_lock_); | 294 LOG(ERROR) << "Received message with " << dispatchers.size() |
286 success = handle_table_.AddDispatcherVector(dispatchers, handles); | 295 << " handles, but handle table full"; |
287 } | 296 // Close dispatchers (outside the lock). |
288 if (!success) { | 297 for (size_t i = 0; i < dispatchers.size(); i++) { |
289 LOG(ERROR) << "Received message with " << dispatchers.size() | 298 if (dispatchers[i]) |
290 << " handles, but handle table full"; | 299 dispatchers[i]->Close(); |
291 // Close dispatchers (outside the lock). | 300 } |
292 for (size_t i = 0; i < dispatchers.size(); i++) { | 301 if (rv == MOJO_RESULT_OK) |
293 if (dispatchers[i]) | 302 rv = MOJO_RESULT_RESOURCE_EXHAUSTED; |
294 dispatchers[i]->Close(); | |
295 } | 303 } |
296 } | 304 } |
297 } | 305 } |
298 | 306 |
| 307 if (!num_handles.IsNull()) |
| 308 num_handles.Put(num_handles_value); |
299 return rv; | 309 return rv; |
300 } | 310 } |
301 | 311 |
302 MojoResult Core::CreateDataPipe(const MojoCreateDataPipeOptions* options, | 312 MojoResult Core::CreateDataPipe( |
303 MojoHandle* data_pipe_producer_handle, | 313 UserPointer<const MojoCreateDataPipeOptions> options, |
304 MojoHandle* data_pipe_consumer_handle) { | 314 UserPointer<MojoHandle> data_pipe_producer_handle, |
| 315 UserPointer<MojoHandle> data_pipe_consumer_handle) { |
305 MojoCreateDataPipeOptions validated_options = {}; | 316 MojoCreateDataPipeOptions validated_options = {}; |
306 // This will verify the |options| pointer. | 317 // This will verify the |options| pointer. |
307 MojoResult result = DataPipe::ValidateCreateOptions(options, | 318 MojoResult result = DataPipe::ValidateCreateOptions( |
308 &validated_options); | 319 options.GetPointerUnsafe(), &validated_options); |
309 if (result != MOJO_RESULT_OK) | 320 if (result != MOJO_RESULT_OK) |
310 return result; | 321 return result; |
311 if (!VerifyUserPointer<MojoHandle>(data_pipe_producer_handle)) | |
312 return MOJO_RESULT_INVALID_ARGUMENT; | |
313 if (!VerifyUserPointer<MojoHandle>(data_pipe_consumer_handle)) | |
314 return MOJO_RESULT_INVALID_ARGUMENT; | |
315 | 322 |
316 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher( | 323 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher( |
317 new DataPipeProducerDispatcher()); | 324 new DataPipeProducerDispatcher()); |
318 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher( | 325 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher( |
319 new DataPipeConsumerDispatcher()); | 326 new DataPipeConsumerDispatcher()); |
320 | 327 |
321 std::pair<MojoHandle, MojoHandle> handle_pair; | 328 std::pair<MojoHandle, MojoHandle> handle_pair; |
322 { | 329 { |
323 base::AutoLock locker(handle_table_lock_); | 330 base::AutoLock locker(handle_table_lock_); |
324 handle_pair = handle_table_.AddDispatcherPair(producer_dispatcher, | 331 handle_pair = handle_table_.AddDispatcherPair(producer_dispatcher, |
325 consumer_dispatcher); | 332 consumer_dispatcher); |
326 } | 333 } |
327 if (handle_pair.first == MOJO_HANDLE_INVALID) { | 334 if (handle_pair.first == MOJO_HANDLE_INVALID) { |
328 DCHECK_EQ(handle_pair.second, MOJO_HANDLE_INVALID); | 335 DCHECK_EQ(handle_pair.second, MOJO_HANDLE_INVALID); |
329 LOG(ERROR) << "Handle table full"; | 336 LOG(ERROR) << "Handle table full"; |
330 producer_dispatcher->Close(); | 337 producer_dispatcher->Close(); |
331 consumer_dispatcher->Close(); | 338 consumer_dispatcher->Close(); |
332 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 339 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
333 } | 340 } |
334 DCHECK_NE(handle_pair.second, MOJO_HANDLE_INVALID); | 341 DCHECK_NE(handle_pair.second, MOJO_HANDLE_INVALID); |
335 | 342 |
336 scoped_refptr<DataPipe> data_pipe(new LocalDataPipe(validated_options)); | 343 scoped_refptr<DataPipe> data_pipe(new LocalDataPipe(validated_options)); |
337 producer_dispatcher->Init(data_pipe); | 344 producer_dispatcher->Init(data_pipe); |
338 consumer_dispatcher->Init(data_pipe); | 345 consumer_dispatcher->Init(data_pipe); |
339 | 346 |
340 *data_pipe_producer_handle = handle_pair.first; | 347 data_pipe_producer_handle.Put(handle_pair.first); |
341 *data_pipe_consumer_handle = handle_pair.second; | 348 data_pipe_consumer_handle.Put(handle_pair.second); |
342 return MOJO_RESULT_OK; | 349 return MOJO_RESULT_OK; |
343 } | 350 } |
344 | 351 |
345 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, | 352 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, |
346 const void* elements, | 353 UserPointer<const void> elements, |
347 uint32_t* num_bytes, | 354 UserPointer<uint32_t> num_bytes, |
348 MojoWriteDataFlags flags) { | 355 MojoWriteDataFlags flags) { |
349 scoped_refptr<Dispatcher> dispatcher( | 356 scoped_refptr<Dispatcher> dispatcher( |
350 GetDispatcher(data_pipe_producer_handle)); | 357 GetDispatcher(data_pipe_producer_handle)); |
351 if (!dispatcher) | 358 if (!dispatcher) |
352 return MOJO_RESULT_INVALID_ARGUMENT; | 359 return MOJO_RESULT_INVALID_ARGUMENT; |
353 | 360 |
354 return dispatcher->WriteData(elements, num_bytes, flags); | 361 return dispatcher->WriteData(elements.GetPointerUnsafe(), |
| 362 num_bytes.GetPointerUnsafe(), flags); |
355 } | 363 } |
356 | 364 |
357 MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle, | 365 MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle, |
358 void** buffer, | 366 UserPointer<void*> buffer, |
359 uint32_t* buffer_num_bytes, | 367 UserPointer<uint32_t> buffer_num_bytes, |
360 MojoWriteDataFlags flags) { | 368 MojoWriteDataFlags flags) { |
361 scoped_refptr<Dispatcher> dispatcher( | 369 scoped_refptr<Dispatcher> dispatcher( |
362 GetDispatcher(data_pipe_producer_handle)); | 370 GetDispatcher(data_pipe_producer_handle)); |
363 if (!dispatcher) | 371 if (!dispatcher) |
364 return MOJO_RESULT_INVALID_ARGUMENT; | 372 return MOJO_RESULT_INVALID_ARGUMENT; |
365 | 373 |
366 return dispatcher->BeginWriteData(buffer, buffer_num_bytes, flags); | 374 return dispatcher->BeginWriteData(buffer.GetPointerUnsafe(), |
| 375 buffer_num_bytes.GetPointerUnsafe(), flags); |
367 } | 376 } |
368 | 377 |
369 MojoResult Core::EndWriteData(MojoHandle data_pipe_producer_handle, | 378 MojoResult Core::EndWriteData(MojoHandle data_pipe_producer_handle, |
370 uint32_t num_bytes_written) { | 379 uint32_t num_bytes_written) { |
371 scoped_refptr<Dispatcher> dispatcher( | 380 scoped_refptr<Dispatcher> dispatcher( |
372 GetDispatcher(data_pipe_producer_handle)); | 381 GetDispatcher(data_pipe_producer_handle)); |
373 if (!dispatcher) | 382 if (!dispatcher) |
374 return MOJO_RESULT_INVALID_ARGUMENT; | 383 return MOJO_RESULT_INVALID_ARGUMENT; |
375 | 384 |
376 return dispatcher->EndWriteData(num_bytes_written); | 385 return dispatcher->EndWriteData(num_bytes_written); |
377 } | 386 } |
378 | 387 |
379 MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle, | 388 MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle, |
380 void* elements, | 389 UserPointer<void> elements, |
381 uint32_t* num_bytes, | 390 UserPointer<uint32_t> num_bytes, |
382 MojoReadDataFlags flags) { | 391 MojoReadDataFlags flags) { |
383 scoped_refptr<Dispatcher> dispatcher( | 392 scoped_refptr<Dispatcher> dispatcher( |
384 GetDispatcher(data_pipe_consumer_handle)); | 393 GetDispatcher(data_pipe_consumer_handle)); |
385 if (!dispatcher) | 394 if (!dispatcher) |
386 return MOJO_RESULT_INVALID_ARGUMENT; | 395 return MOJO_RESULT_INVALID_ARGUMENT; |
387 | 396 |
388 return dispatcher->ReadData(elements, num_bytes, flags); | 397 return dispatcher->ReadData(elements.GetPointerUnsafe(), |
| 398 num_bytes.GetPointerUnsafe(), flags); |
389 } | 399 } |
390 | 400 |
391 MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle, | 401 MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle, |
392 const void** buffer, | 402 UserPointer<const void*> buffer, |
393 uint32_t* buffer_num_bytes, | 403 UserPointer<uint32_t> buffer_num_bytes, |
394 MojoReadDataFlags flags) { | 404 MojoReadDataFlags flags) { |
395 scoped_refptr<Dispatcher> dispatcher( | 405 scoped_refptr<Dispatcher> dispatcher( |
396 GetDispatcher(data_pipe_consumer_handle)); | 406 GetDispatcher(data_pipe_consumer_handle)); |
397 if (!dispatcher) | 407 if (!dispatcher) |
398 return MOJO_RESULT_INVALID_ARGUMENT; | 408 return MOJO_RESULT_INVALID_ARGUMENT; |
399 | 409 |
400 return dispatcher->BeginReadData(buffer, buffer_num_bytes, flags); | 410 return dispatcher->BeginReadData(buffer.GetPointerUnsafe(), |
| 411 buffer_num_bytes.GetPointerUnsafe(), flags); |
401 } | 412 } |
402 | 413 |
403 MojoResult Core::EndReadData(MojoHandle data_pipe_consumer_handle, | 414 MojoResult Core::EndReadData(MojoHandle data_pipe_consumer_handle, |
404 uint32_t num_bytes_read) { | 415 uint32_t num_bytes_read) { |
405 scoped_refptr<Dispatcher> dispatcher( | 416 scoped_refptr<Dispatcher> dispatcher( |
406 GetDispatcher(data_pipe_consumer_handle)); | 417 GetDispatcher(data_pipe_consumer_handle)); |
407 if (!dispatcher) | 418 if (!dispatcher) |
408 return MOJO_RESULT_INVALID_ARGUMENT; | 419 return MOJO_RESULT_INVALID_ARGUMENT; |
409 | 420 |
410 return dispatcher->EndReadData(num_bytes_read); | 421 return dispatcher->EndReadData(num_bytes_read); |
411 } | 422 } |
412 | 423 |
413 MojoResult Core::CreateSharedBuffer( | 424 MojoResult Core::CreateSharedBuffer( |
414 const MojoCreateSharedBufferOptions* options, | 425 UserPointer<const MojoCreateSharedBufferOptions> options, |
415 uint64_t num_bytes, | 426 uint64_t num_bytes, |
416 MojoHandle* shared_buffer_handle) { | 427 UserPointer<MojoHandle> shared_buffer_handle) { |
417 MojoCreateSharedBufferOptions validated_options = {}; | 428 MojoCreateSharedBufferOptions validated_options = {}; |
418 // This will verify the |options| pointer. | 429 // This will verify the |options| pointer. |
419 MojoResult result = | 430 MojoResult result = |
420 SharedBufferDispatcher::ValidateCreateOptions(options, | 431 SharedBufferDispatcher::ValidateCreateOptions(options.GetPointerUnsafe(), |
421 &validated_options); | 432 &validated_options); |
422 if (result != MOJO_RESULT_OK) | 433 if (result != MOJO_RESULT_OK) |
423 return result; | 434 return result; |
424 if (!VerifyUserPointer<MojoHandle>(shared_buffer_handle)) | |
425 return MOJO_RESULT_INVALID_ARGUMENT; | |
426 | 435 |
427 scoped_refptr<SharedBufferDispatcher> dispatcher; | 436 scoped_refptr<SharedBufferDispatcher> dispatcher; |
428 result = SharedBufferDispatcher::Create(validated_options, num_bytes, | 437 result = SharedBufferDispatcher::Create(validated_options, num_bytes, |
429 &dispatcher); | 438 &dispatcher); |
430 if (result != MOJO_RESULT_OK) { | 439 if (result != MOJO_RESULT_OK) { |
431 DCHECK(!dispatcher); | 440 DCHECK(!dispatcher); |
432 return result; | 441 return result; |
433 } | 442 } |
434 | 443 |
435 MojoHandle h = AddDispatcher(dispatcher); | 444 MojoHandle h = AddDispatcher(dispatcher); |
436 if (h == MOJO_HANDLE_INVALID) { | 445 if (h == MOJO_HANDLE_INVALID) { |
437 LOG(ERROR) << "Handle table full"; | 446 LOG(ERROR) << "Handle table full"; |
438 dispatcher->Close(); | 447 dispatcher->Close(); |
439 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 448 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
440 } | 449 } |
441 | 450 |
442 *shared_buffer_handle = h; | 451 shared_buffer_handle.Put(h); |
443 return MOJO_RESULT_OK; | 452 return MOJO_RESULT_OK; |
444 } | 453 } |
445 | 454 |
446 MojoResult Core::DuplicateBufferHandle( | 455 MojoResult Core::DuplicateBufferHandle( |
447 MojoHandle buffer_handle, | 456 MojoHandle buffer_handle, |
448 const MojoDuplicateBufferHandleOptions* options, | 457 UserPointer<const MojoDuplicateBufferHandleOptions> options, |
449 MojoHandle* new_buffer_handle) { | 458 UserPointer<MojoHandle> new_buffer_handle) { |
450 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 459 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
451 if (!dispatcher) | 460 if (!dispatcher) |
452 return MOJO_RESULT_INVALID_ARGUMENT; | 461 return MOJO_RESULT_INVALID_ARGUMENT; |
453 | 462 |
454 // Don't verify |options| here; that's the dispatcher's job. | 463 // Don't verify |options| here; that's the dispatcher's job. |
455 if (!VerifyUserPointer<MojoHandle>(new_buffer_handle)) | |
456 return MOJO_RESULT_INVALID_ARGUMENT; | |
457 | |
458 scoped_refptr<Dispatcher> new_dispatcher; | 464 scoped_refptr<Dispatcher> new_dispatcher; |
459 MojoResult result = dispatcher->DuplicateBufferHandle(options, | 465 MojoResult result = dispatcher->DuplicateBufferHandle( |
460 &new_dispatcher); | 466 options.GetPointerUnsafe(), &new_dispatcher); |
461 if (result != MOJO_RESULT_OK) | 467 if (result != MOJO_RESULT_OK) |
462 return result; | 468 return result; |
463 | 469 |
464 MojoHandle new_handle = AddDispatcher(new_dispatcher); | 470 MojoHandle new_handle = AddDispatcher(new_dispatcher); |
465 if (new_handle == MOJO_HANDLE_INVALID) { | 471 if (new_handle == MOJO_HANDLE_INVALID) { |
466 LOG(ERROR) << "Handle table full"; | 472 LOG(ERROR) << "Handle table full"; |
467 dispatcher->Close(); | 473 dispatcher->Close(); |
468 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 474 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
469 } | 475 } |
470 | 476 |
471 *new_buffer_handle = new_handle; | 477 new_buffer_handle.Put(new_handle); |
472 return MOJO_RESULT_OK; | 478 return MOJO_RESULT_OK; |
473 } | 479 } |
474 | 480 |
475 MojoResult Core::MapBuffer(MojoHandle buffer_handle, | 481 MojoResult Core::MapBuffer(MojoHandle buffer_handle, |
476 uint64_t offset, | 482 uint64_t offset, |
477 uint64_t num_bytes, | 483 uint64_t num_bytes, |
478 void** buffer, | 484 UserPointer<void*> buffer, |
479 MojoMapBufferFlags flags) { | 485 MojoMapBufferFlags flags) { |
480 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 486 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
481 if (!dispatcher) | 487 if (!dispatcher) |
482 return MOJO_RESULT_INVALID_ARGUMENT; | 488 return MOJO_RESULT_INVALID_ARGUMENT; |
483 | 489 |
484 if (!VerifyUserPointerWithCount<void*>(buffer, 1)) | |
485 return MOJO_RESULT_INVALID_ARGUMENT; | |
486 | |
487 scoped_ptr<RawSharedBufferMapping> mapping; | 490 scoped_ptr<RawSharedBufferMapping> mapping; |
488 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); | 491 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); |
489 if (result != MOJO_RESULT_OK) | 492 if (result != MOJO_RESULT_OK) |
490 return result; | 493 return result; |
491 | 494 |
492 DCHECK(mapping); | 495 DCHECK(mapping); |
493 void* address = mapping->base(); | 496 void* address = mapping->base(); |
494 { | 497 { |
495 base::AutoLock locker(mapping_table_lock_); | 498 base::AutoLock locker(mapping_table_lock_); |
496 result = mapping_table_.AddMapping(mapping.Pass()); | 499 result = mapping_table_.AddMapping(mapping.Pass()); |
497 } | 500 } |
498 if (result != MOJO_RESULT_OK) | 501 if (result != MOJO_RESULT_OK) |
499 return result; | 502 return result; |
500 | 503 |
501 *buffer = address; | 504 buffer.Put(address); |
502 return MOJO_RESULT_OK; | 505 return MOJO_RESULT_OK; |
503 } | 506 } |
504 | 507 |
505 MojoResult Core::UnmapBuffer(void* buffer) { | 508 MojoResult Core::UnmapBuffer(UserPointerValue<void> buffer) { |
506 base::AutoLock locker(mapping_table_lock_); | 509 base::AutoLock locker(mapping_table_lock_); |
507 return mapping_table_.RemoveMapping(buffer); | 510 return mapping_table_.RemoveMapping(buffer.GetValue()); |
508 } | 511 } |
509 | 512 |
510 // Note: We allow |handles| to repeat the same handle multiple times, since | 513 // Note: We allow |handles| to repeat the same handle multiple times, since |
511 // different flags may be specified. | 514 // different flags may be specified. |
512 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this | 515 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this |
513 // more carefully and address it if necessary. | 516 // more carefully and address it if necessary. |
514 MojoResult Core::WaitManyInternal(const MojoHandle* handles, | 517 MojoResult Core::WaitManyInternal(const MojoHandle* handles, |
515 const MojoHandleSignals* signals, | 518 const MojoHandleSignals* signals, |
516 uint32_t num_handles, | 519 uint32_t num_handles, |
517 MojoDeadline deadline) { | 520 MojoDeadline deadline) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be | 555 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be |
553 // destroyed, but this would still be required if the waiter were in TLS.) | 556 // destroyed, but this would still be required if the waiter were in TLS.) |
554 for (i = 0; i < num_added; i++) | 557 for (i = 0; i < num_added; i++) |
555 dispatchers[i]->RemoveWaiter(&waiter); | 558 dispatchers[i]->RemoveWaiter(&waiter); |
556 | 559 |
557 return rv; | 560 return rv; |
558 } | 561 } |
559 | 562 |
560 } // namespace system | 563 } // namespace system |
561 } // namespace mojo | 564 } // namespace mojo |
OLD | NEW |