| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 } | 111 } |
| 112 | 112 |
| 113 // The dispatcher doesn't have a say in being closed, but gets notified of it. | 113 // The dispatcher doesn't have a say in being closed, but gets notified of it. |
| 114 // Note: This is done outside of |handle_table_lock_|. As a result, there's a | 114 // Note: This is done outside of |handle_table_lock_|. As a result, there's a |
| 115 // race condition that the dispatcher must handle; see the comment in | 115 // race condition that the dispatcher must handle; see the comment in |
| 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 MojoWaitFlags flags, | 121 MojoHandleSignals signals, |
| 122 MojoDeadline deadline) { | 122 MojoDeadline deadline) { |
| 123 return WaitManyInternal(&handle, &flags, 1, deadline); | 123 return WaitManyInternal(&handle, &signals, 1, deadline); |
| 124 } | 124 } |
| 125 | 125 |
| 126 MojoResult Core::WaitMany(const MojoHandle* handles, | 126 MojoResult Core::WaitMany(const MojoHandle* handles, |
| 127 const MojoWaitFlags* flags, | 127 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)) | 130 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles)) |
| 131 return MOJO_RESULT_INVALID_ARGUMENT; | 131 return MOJO_RESULT_INVALID_ARGUMENT; |
| 132 if (!VerifyUserPointerWithCount<MojoWaitFlags>(flags, num_handles)) | 132 if (!VerifyUserPointerWithCount<MojoHandleSignals>(signals, num_handles)) |
| 133 return MOJO_RESULT_INVALID_ARGUMENT; | 133 return MOJO_RESULT_INVALID_ARGUMENT; |
| 134 if (num_handles < 1) | 134 if (num_handles < 1) |
| 135 return MOJO_RESULT_INVALID_ARGUMENT; | 135 return MOJO_RESULT_INVALID_ARGUMENT; |
| 136 if (num_handles > kMaxWaitManyNumHandles) | 136 if (num_handles > kMaxWaitManyNumHandles) |
| 137 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 137 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 138 return WaitManyInternal(handles, flags, num_handles, deadline); | 138 return WaitManyInternal(handles, signals, num_handles, deadline); |
| 139 } | 139 } |
| 140 | 140 |
| 141 MojoResult Core::CreateMessagePipe(const MojoCreateMessagePipeOptions* options, | 141 MojoResult Core::CreateMessagePipe(const MojoCreateMessagePipeOptions* options, |
| 142 MojoHandle* message_pipe_handle0, | 142 MojoHandle* message_pipe_handle0, |
| 143 MojoHandle* message_pipe_handle1) { | 143 MojoHandle* message_pipe_handle1) { |
| 144 MojoCreateMessagePipeOptions validated_options = {}; | 144 MojoCreateMessagePipeOptions validated_options = {}; |
| 145 // This will verify the |options| pointer. | 145 // This will verify the |options| pointer. |
| 146 MojoResult result = MessagePipeDispatcher::ValidateCreateOptions( | 146 MojoResult result = MessagePipeDispatcher::ValidateCreateOptions( |
| 147 options, &validated_options); | 147 options, &validated_options); |
| 148 if (result != MOJO_RESULT_OK) | 148 if (result != MOJO_RESULT_OK) |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 MojoResult Core::UnmapBuffer(void* buffer) { | 505 MojoResult Core::UnmapBuffer(void* buffer) { |
| 506 base::AutoLock locker(mapping_table_lock_); | 506 base::AutoLock locker(mapping_table_lock_); |
| 507 return mapping_table_.RemoveMapping(buffer); | 507 return mapping_table_.RemoveMapping(buffer); |
| 508 } | 508 } |
| 509 | 509 |
| 510 // Note: We allow |handles| to repeat the same handle multiple times, since | 510 // Note: We allow |handles| to repeat the same handle multiple times, since |
| 511 // different flags may be specified. | 511 // different flags may be specified. |
| 512 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this | 512 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this |
| 513 // more carefully and address it if necessary. | 513 // more carefully and address it if necessary. |
| 514 MojoResult Core::WaitManyInternal(const MojoHandle* handles, | 514 MojoResult Core::WaitManyInternal(const MojoHandle* handles, |
| 515 const MojoWaitFlags* flags, | 515 const MojoHandleSignals* signals, |
| 516 uint32_t num_handles, | 516 uint32_t num_handles, |
| 517 MojoDeadline deadline) { | 517 MojoDeadline deadline) { |
| 518 DCHECK_GT(num_handles, 0u); | 518 DCHECK_GT(num_handles, 0u); |
| 519 | 519 |
| 520 DispatcherVector dispatchers; | 520 DispatcherVector dispatchers; |
| 521 dispatchers.reserve(num_handles); | 521 dispatchers.reserve(num_handles); |
| 522 for (uint32_t i = 0; i < num_handles; i++) { | 522 for (uint32_t i = 0; i < num_handles; i++) { |
| 523 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]); | 523 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]); |
| 524 if (!dispatcher) | 524 if (!dispatcher) |
| 525 return MOJO_RESULT_INVALID_ARGUMENT; | 525 return MOJO_RESULT_INVALID_ARGUMENT; |
| 526 dispatchers.push_back(dispatcher); | 526 dispatchers.push_back(dispatcher); |
| 527 } | 527 } |
| 528 | 528 |
| 529 // TODO(vtl): Should make the waiter live (permanently) in TLS. | 529 // TODO(vtl): Should make the waiter live (permanently) in TLS. |
| 530 Waiter waiter; | 530 Waiter waiter; |
| 531 waiter.Init(); | 531 waiter.Init(); |
| 532 | 532 |
| 533 uint32_t i; | 533 uint32_t i; |
| 534 MojoResult rv = MOJO_RESULT_OK; | 534 MojoResult rv = MOJO_RESULT_OK; |
| 535 for (i = 0; i < num_handles; i++) { | 535 for (i = 0; i < num_handles; i++) { |
| 536 rv = dispatchers[i]->AddWaiter(&waiter, flags[i], i); | 536 rv = dispatchers[i]->AddWaiter(&waiter, signals[i], i); |
| 537 if (rv != MOJO_RESULT_OK) | 537 if (rv != MOJO_RESULT_OK) |
| 538 break; | 538 break; |
| 539 } | 539 } |
| 540 uint32_t num_added = i; | 540 uint32_t num_added = i; |
| 541 | 541 |
| 542 if (rv == MOJO_RESULT_ALREADY_EXISTS) { | 542 if (rv == MOJO_RESULT_ALREADY_EXISTS) { |
| 543 rv = static_cast<MojoResult>(i); // The i-th one is already "triggered". | 543 rv = static_cast<MojoResult>(i); // The i-th one is already "triggered". |
| 544 } else if (rv == MOJO_RESULT_OK) { | 544 } else if (rv == MOJO_RESULT_OK) { |
| 545 uint32_t context = static_cast<uint32_t>(-1); | 545 uint32_t context = static_cast<uint32_t>(-1); |
| 546 rv = waiter.Wait(deadline, &context); | 546 rv = waiter.Wait(deadline, &context); |
| 547 if (rv == MOJO_RESULT_OK) | 547 if (rv == MOJO_RESULT_OK) |
| 548 rv = static_cast<MojoResult>(context); | 548 rv = static_cast<MojoResult>(context); |
| 549 } | 549 } |
| 550 | 550 |
| 551 // Make sure no other dispatchers try to wake |waiter| for the current | 551 // Make sure no other dispatchers try to wake |waiter| for the current |
| 552 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be | 552 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be |
| 553 // destroyed, but this would still be required if the waiter were in TLS.) | 553 // destroyed, but this would still be required if the waiter were in TLS.) |
| 554 for (i = 0; i < num_added; i++) | 554 for (i = 0; i < num_added; i++) |
| 555 dispatchers[i]->RemoveWaiter(&waiter); | 555 dispatchers[i]->RemoveWaiter(&waiter); |
| 556 | 556 |
| 557 return rv; | 557 return rv; |
| 558 } | 558 } |
| 559 | 559 |
| 560 } // namespace system | 560 } // namespace system |
| 561 } // namespace mojo | 561 } // namespace mojo |
| OLD | NEW |