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