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" |
| 11 #include "mojo/public/c/system/macros.h" |
11 #include "mojo/system/constants.h" | 12 #include "mojo/system/constants.h" |
12 #include "mojo/system/data_pipe.h" | 13 #include "mojo/system/data_pipe.h" |
13 #include "mojo/system/data_pipe_consumer_dispatcher.h" | 14 #include "mojo/system/data_pipe_consumer_dispatcher.h" |
14 #include "mojo/system/data_pipe_producer_dispatcher.h" | 15 #include "mojo/system/data_pipe_producer_dispatcher.h" |
15 #include "mojo/system/dispatcher.h" | 16 #include "mojo/system/dispatcher.h" |
16 #include "mojo/system/local_data_pipe.h" | 17 #include "mojo/system/local_data_pipe.h" |
17 #include "mojo/system/memory.h" | 18 #include "mojo/system/memory.h" |
18 #include "mojo/system/message_pipe.h" | 19 #include "mojo/system/message_pipe.h" |
19 #include "mojo/system/message_pipe_dispatcher.h" | 20 #include "mojo/system/message_pipe_dispatcher.h" |
20 #include "mojo/system/raw_shared_buffer.h" | 21 #include "mojo/system/raw_shared_buffer.h" |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 MojoResult Core::Wait(MojoHandle handle, | 120 MojoResult Core::Wait(MojoHandle handle, |
120 MojoWaitFlags flags, | 121 MojoWaitFlags flags, |
121 MojoDeadline deadline) { | 122 MojoDeadline deadline) { |
122 return WaitManyInternal(&handle, &flags, 1, deadline); | 123 return WaitManyInternal(&handle, &flags, 1, deadline); |
123 } | 124 } |
124 | 125 |
125 MojoResult Core::WaitMany(const MojoHandle* handles, | 126 MojoResult Core::WaitMany(const MojoHandle* handles, |
126 const MojoWaitFlags* flags, | 127 const MojoWaitFlags* flags, |
127 uint32_t num_handles, | 128 uint32_t num_handles, |
128 MojoDeadline deadline) { | 129 MojoDeadline deadline) { |
129 if (!VerifyUserPointer<MojoHandle>(handles, num_handles)) | 130 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles)) |
130 return MOJO_RESULT_INVALID_ARGUMENT; | 131 return MOJO_RESULT_INVALID_ARGUMENT; |
131 if (!VerifyUserPointer<MojoWaitFlags>(flags, num_handles)) | 132 if (!VerifyUserPointerWithCount<MojoWaitFlags>(flags, num_handles)) |
132 return MOJO_RESULT_INVALID_ARGUMENT; | 133 return MOJO_RESULT_INVALID_ARGUMENT; |
133 if (num_handles < 1) | 134 if (num_handles < 1) |
134 return MOJO_RESULT_INVALID_ARGUMENT; | 135 return MOJO_RESULT_INVALID_ARGUMENT; |
135 if (num_handles > kMaxWaitManyNumHandles) | 136 if (num_handles > kMaxWaitManyNumHandles) |
136 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 137 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
137 return WaitManyInternal(handles, flags, num_handles, deadline); | 138 return WaitManyInternal(handles, flags, num_handles, deadline); |
138 } | 139 } |
139 | 140 |
140 MojoResult Core::CreateMessagePipe(MojoHandle* message_pipe_handle0, | 141 MojoResult Core::CreateMessagePipe(MojoHandle* message_pipe_handle0, |
141 MojoHandle* message_pipe_handle1) { | 142 MojoHandle* message_pipe_handle1) { |
142 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle0, 1)) | 143 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle0)) |
143 return MOJO_RESULT_INVALID_ARGUMENT; | 144 return MOJO_RESULT_INVALID_ARGUMENT; |
144 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle1, 1)) | 145 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle1)) |
145 return MOJO_RESULT_INVALID_ARGUMENT; | 146 return MOJO_RESULT_INVALID_ARGUMENT; |
146 | 147 |
147 scoped_refptr<MessagePipeDispatcher> dispatcher0(new MessagePipeDispatcher()); | 148 scoped_refptr<MessagePipeDispatcher> dispatcher0(new MessagePipeDispatcher()); |
148 scoped_refptr<MessagePipeDispatcher> dispatcher1(new MessagePipeDispatcher()); | 149 scoped_refptr<MessagePipeDispatcher> dispatcher1(new MessagePipeDispatcher()); |
149 | 150 |
150 std::pair<MojoHandle, MojoHandle> handle_pair; | 151 std::pair<MojoHandle, MojoHandle> handle_pair; |
151 { | 152 { |
152 base::AutoLock locker(handle_table_lock_); | 153 base::AutoLock locker(handle_table_lock_); |
153 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); | 154 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); |
154 } | 155 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 return dispatcher->WriteMessage(bytes, num_bytes, NULL, flags); | 192 return dispatcher->WriteMessage(bytes, num_bytes, NULL, flags); |
192 | 193 |
193 // We have to handle |handles| here, since we have to mark them busy in the | 194 // We have to handle |handles| here, since we have to mark them busy in the |
194 // global handle table. We can't delegate this to the dispatcher, since the | 195 // global handle table. We can't delegate this to the dispatcher, since the |
195 // handle table lock must be acquired before the dispatcher lock. | 196 // handle table lock must be acquired before the dispatcher lock. |
196 // | 197 // |
197 // (This leads to an oddity: |handles|/|num_handles| are always verified for | 198 // (This leads to an oddity: |handles|/|num_handles| are always verified for |
198 // validity, even for dispatchers that don't support |WriteMessage()| and will | 199 // validity, even for dispatchers that don't support |WriteMessage()| and will |
199 // simply return failure unconditionally. It also breaks the usual | 200 // simply return failure unconditionally. It also breaks the usual |
200 // left-to-right verification order of arguments.) | 201 // left-to-right verification order of arguments.) |
201 if (!VerifyUserPointer<MojoHandle>(handles, num_handles)) | 202 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles)) |
202 return MOJO_RESULT_INVALID_ARGUMENT; | 203 return MOJO_RESULT_INVALID_ARGUMENT; |
203 if (num_handles > kMaxMessageNumHandles) | 204 if (num_handles > kMaxMessageNumHandles) |
204 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 205 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
205 | 206 |
206 // We'll need to hold on to the dispatchers so that we can pass them on to | 207 // We'll need to hold on to the dispatchers so that we can pass them on to |
207 // |WriteMessage()| and also so that we can unlock their locks afterwards | 208 // |WriteMessage()| and also so that we can unlock their locks afterwards |
208 // without accessing the handle table. These can be dumb pointers, since their | 209 // without accessing the handle table. These can be dumb pointers, since their |
209 // entries in the handle table won't get removed (since they'll be marked as | 210 // entries in the handle table won't get removed (since they'll be marked as |
210 // busy). | 211 // busy). |
211 std::vector<DispatcherTransport> transports(num_handles); | 212 std::vector<DispatcherTransport> transports(num_handles); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 void* bytes, | 245 void* bytes, |
245 uint32_t* num_bytes, | 246 uint32_t* num_bytes, |
246 MojoHandle* handles, | 247 MojoHandle* handles, |
247 uint32_t* num_handles, | 248 uint32_t* num_handles, |
248 MojoReadMessageFlags flags) { | 249 MojoReadMessageFlags flags) { |
249 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); | 250 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); |
250 if (!dispatcher) | 251 if (!dispatcher) |
251 return MOJO_RESULT_INVALID_ARGUMENT; | 252 return MOJO_RESULT_INVALID_ARGUMENT; |
252 | 253 |
253 if (num_handles) { | 254 if (num_handles) { |
254 if (!VerifyUserPointer<uint32_t>(num_handles, 1)) | 255 if (!VerifyUserPointer<uint32_t>(num_handles)) |
255 return MOJO_RESULT_INVALID_ARGUMENT; | 256 return MOJO_RESULT_INVALID_ARGUMENT; |
256 if (!VerifyUserPointer<MojoHandle>(handles, *num_handles)) | 257 if (!VerifyUserPointerWithCount<MojoHandle>(handles, *num_handles)) |
257 return MOJO_RESULT_INVALID_ARGUMENT; | 258 return MOJO_RESULT_INVALID_ARGUMENT; |
258 } | 259 } |
259 | 260 |
260 // Easy case: won't receive any handles. | 261 // Easy case: won't receive any handles. |
261 if (!num_handles || *num_handles == 0) | 262 if (!num_handles || *num_handles == 0) |
262 return dispatcher->ReadMessage(bytes, num_bytes, NULL, num_handles, flags); | 263 return dispatcher->ReadMessage(bytes, num_bytes, NULL, num_handles, flags); |
263 | 264 |
264 DispatcherVector dispatchers; | 265 DispatcherVector dispatchers; |
265 MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes, | 266 MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes, |
266 &dispatchers, num_handles, | 267 &dispatchers, num_handles, |
(...skipping 20 matching lines...) Expand all Loading... |
287 } | 288 } |
288 | 289 |
289 return rv; | 290 return rv; |
290 } | 291 } |
291 | 292 |
292 MojoResult Core::CreateDataPipe(const MojoCreateDataPipeOptions* options, | 293 MojoResult Core::CreateDataPipe(const MojoCreateDataPipeOptions* options, |
293 MojoHandle* data_pipe_producer_handle, | 294 MojoHandle* data_pipe_producer_handle, |
294 MojoHandle* data_pipe_consumer_handle) { | 295 MojoHandle* data_pipe_consumer_handle) { |
295 if (options) { | 296 if (options) { |
296 // The |struct_size| field must be valid to read. | 297 // The |struct_size| field must be valid to read. |
297 if (!VerifyUserPointer<uint32_t>(&options->struct_size, 1)) | 298 if (!VerifyUserPointer<uint32_t>(&options->struct_size)) |
298 return MOJO_RESULT_INVALID_ARGUMENT; | 299 return MOJO_RESULT_INVALID_ARGUMENT; |
299 // And then |options| must point to at least |options->struct_size| bytes. | 300 // And then |options| must point to at least |options->struct_size| bytes. |
300 if (!VerifyUserPointer<void>(options, options->struct_size)) | 301 if (!VerifyUserPointerWithSize<MOJO_ALIGNOF(int64_t)>(options, |
| 302 options->struct_size)) |
301 return MOJO_RESULT_INVALID_ARGUMENT; | 303 return MOJO_RESULT_INVALID_ARGUMENT; |
302 } | 304 } |
303 if (!VerifyUserPointer<MojoHandle>(data_pipe_producer_handle, 1)) | 305 if (!VerifyUserPointer<MojoHandle>(data_pipe_producer_handle)) |
304 return MOJO_RESULT_INVALID_ARGUMENT; | 306 return MOJO_RESULT_INVALID_ARGUMENT; |
305 if (!VerifyUserPointer<MojoHandle>(data_pipe_consumer_handle, 1)) | 307 if (!VerifyUserPointer<MojoHandle>(data_pipe_consumer_handle)) |
306 return MOJO_RESULT_INVALID_ARGUMENT; | 308 return MOJO_RESULT_INVALID_ARGUMENT; |
307 | 309 |
308 MojoCreateDataPipeOptions validated_options = { 0 }; | 310 MojoCreateDataPipeOptions validated_options = { 0 }; |
309 MojoResult result = DataPipe::ValidateOptions(options, &validated_options); | 311 MojoResult result = DataPipe::ValidateOptions(options, &validated_options); |
310 if (result != MOJO_RESULT_OK) | 312 if (result != MOJO_RESULT_OK) |
311 return result; | 313 return result; |
312 | 314 |
313 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher( | 315 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher( |
314 new DataPipeProducerDispatcher()); | 316 new DataPipeProducerDispatcher()); |
315 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher( | 317 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher( |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 | 408 |
407 return dispatcher->EndReadData(num_bytes_read); | 409 return dispatcher->EndReadData(num_bytes_read); |
408 } | 410 } |
409 | 411 |
410 MojoResult Core::CreateSharedBuffer( | 412 MojoResult Core::CreateSharedBuffer( |
411 const MojoCreateSharedBufferOptions* options, | 413 const MojoCreateSharedBufferOptions* options, |
412 uint64_t num_bytes, | 414 uint64_t num_bytes, |
413 MojoHandle* shared_buffer_handle) { | 415 MojoHandle* shared_buffer_handle) { |
414 if (options) { | 416 if (options) { |
415 // The |struct_size| field must be valid to read. | 417 // The |struct_size| field must be valid to read. |
416 if (!VerifyUserPointer<uint32_t>(&options->struct_size, 1)) | 418 if (!VerifyUserPointer<uint32_t>(&options->struct_size)) |
417 return MOJO_RESULT_INVALID_ARGUMENT; | 419 return MOJO_RESULT_INVALID_ARGUMENT; |
418 // And then |options| must point to at least |options->struct_size| bytes. | 420 // And then |options| must point to at least |options->struct_size| bytes. |
419 if (!VerifyUserPointer<void>(options, options->struct_size)) | 421 if (!VerifyUserPointerWithSize<MOJO_ALIGNOF(int64_t)>(options, |
| 422 options->struct_size)) |
420 return MOJO_RESULT_INVALID_ARGUMENT; | 423 return MOJO_RESULT_INVALID_ARGUMENT; |
421 } | 424 } |
422 if (!VerifyUserPointer<MojoHandle>(shared_buffer_handle, 1)) | 425 if (!VerifyUserPointer<MojoHandle>(shared_buffer_handle)) |
423 return MOJO_RESULT_INVALID_ARGUMENT; | 426 return MOJO_RESULT_INVALID_ARGUMENT; |
424 | 427 |
425 MojoCreateSharedBufferOptions validated_options = { 0 }; | 428 MojoCreateSharedBufferOptions validated_options = { 0 }; |
426 MojoResult result = | 429 MojoResult result = |
427 SharedBufferDispatcher::ValidateOptions(options, &validated_options); | 430 SharedBufferDispatcher::ValidateOptions(options, &validated_options); |
428 if (result != MOJO_RESULT_OK) | 431 if (result != MOJO_RESULT_OK) |
429 return result; | 432 return result; |
430 | 433 |
431 scoped_refptr<SharedBufferDispatcher> dispatcher; | 434 scoped_refptr<SharedBufferDispatcher> dispatcher; |
432 result = SharedBufferDispatcher::Create(validated_options, num_bytes, | 435 result = SharedBufferDispatcher::Create(validated_options, num_bytes, |
(...skipping 16 matching lines...) Expand all Loading... |
449 | 452 |
450 MojoResult Core::DuplicateBufferHandle( | 453 MojoResult Core::DuplicateBufferHandle( |
451 MojoHandle buffer_handle, | 454 MojoHandle buffer_handle, |
452 const MojoDuplicateBufferHandleOptions* options, | 455 const MojoDuplicateBufferHandleOptions* options, |
453 MojoHandle* new_buffer_handle) { | 456 MojoHandle* new_buffer_handle) { |
454 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 457 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
455 if (!dispatcher) | 458 if (!dispatcher) |
456 return MOJO_RESULT_INVALID_ARGUMENT; | 459 return MOJO_RESULT_INVALID_ARGUMENT; |
457 | 460 |
458 // Don't verify |options| here; that's the dispatcher's job. | 461 // Don't verify |options| here; that's the dispatcher's job. |
459 if (!VerifyUserPointer<MojoHandle>(new_buffer_handle, 1)) | 462 if (!VerifyUserPointer<MojoHandle>(new_buffer_handle)) |
460 return MOJO_RESULT_INVALID_ARGUMENT; | 463 return MOJO_RESULT_INVALID_ARGUMENT; |
461 | 464 |
462 scoped_refptr<Dispatcher> new_dispatcher; | 465 scoped_refptr<Dispatcher> new_dispatcher; |
463 MojoResult result = dispatcher->DuplicateBufferHandle(options, | 466 MojoResult result = dispatcher->DuplicateBufferHandle(options, |
464 &new_dispatcher); | 467 &new_dispatcher); |
465 if (result != MOJO_RESULT_OK) | 468 if (result != MOJO_RESULT_OK) |
466 return result; | 469 return result; |
467 | 470 |
468 MojoHandle new_handle = AddDispatcher(new_dispatcher); | 471 MojoHandle new_handle = AddDispatcher(new_dispatcher); |
469 if (new_handle == MOJO_HANDLE_INVALID) { | 472 if (new_handle == MOJO_HANDLE_INVALID) { |
470 LOG(ERROR) << "Handle table full"; | 473 LOG(ERROR) << "Handle table full"; |
471 dispatcher->Close(); | 474 dispatcher->Close(); |
472 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 475 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
473 } | 476 } |
474 | 477 |
475 *new_buffer_handle = new_handle; | 478 *new_buffer_handle = new_handle; |
476 return MOJO_RESULT_OK; | 479 return MOJO_RESULT_OK; |
477 } | 480 } |
478 | 481 |
479 MojoResult Core::MapBuffer(MojoHandle buffer_handle, | 482 MojoResult Core::MapBuffer(MojoHandle buffer_handle, |
480 uint64_t offset, | 483 uint64_t offset, |
481 uint64_t num_bytes, | 484 uint64_t num_bytes, |
482 void** buffer, | 485 void** buffer, |
483 MojoMapBufferFlags flags) { | 486 MojoMapBufferFlags flags) { |
484 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 487 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
485 if (!dispatcher) | 488 if (!dispatcher) |
486 return MOJO_RESULT_INVALID_ARGUMENT; | 489 return MOJO_RESULT_INVALID_ARGUMENT; |
487 | 490 |
488 if (!VerifyUserPointer<void*>(buffer, 1)) | 491 if (!VerifyUserPointerWithCount<void*>(buffer, 1)) |
489 return MOJO_RESULT_INVALID_ARGUMENT; | 492 return MOJO_RESULT_INVALID_ARGUMENT; |
490 | 493 |
491 scoped_ptr<RawSharedBufferMapping> mapping; | 494 scoped_ptr<RawSharedBufferMapping> mapping; |
492 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); | 495 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); |
493 if (result != MOJO_RESULT_OK) | 496 if (result != MOJO_RESULT_OK) |
494 return result; | 497 return result; |
495 | 498 |
496 DCHECK(mapping); | 499 DCHECK(mapping); |
497 void* address = mapping->base(); | 500 void* address = mapping->base(); |
498 { | 501 { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be | 557 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be |
555 // destroyed, but this would still be required if the waiter were in TLS.) | 558 // destroyed, but this would still be required if the waiter were in TLS.) |
556 for (i = 0; i < num_added; i++) | 559 for (i = 0; i < num_added; i++) |
557 dispatchers[i]->RemoveWaiter(&waiter); | 560 dispatchers[i]->RemoveWaiter(&waiter); |
558 | 561 |
559 return rv; | 562 return rv; |
560 } | 563 } |
561 | 564 |
562 } // namespace system | 565 } // namespace system |
563 } // namespace mojo | 566 } // namespace mojo |
OLD | NEW |