| 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 MojoHandleSignals signals, | 121 MojoHandleSignals signals, |
| 122 MojoDeadline deadline) { | 122 MojoDeadline deadline) { |
| 123 return WaitManyInternal(&handle, &signals, 1, deadline); | 123 uint32_t unused = static_cast<uint32_t>(-1); |
| 124 return WaitManyInternal(&handle, &signals, 1, deadline, &unused); |
| 124 } | 125 } |
| 125 | 126 |
| 126 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, | 127 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, |
| 127 UserPointer<const MojoHandleSignals> signals, | 128 UserPointer<const MojoHandleSignals> signals, |
| 128 uint32_t num_handles, | 129 uint32_t num_handles, |
| 129 MojoDeadline deadline) { | 130 MojoDeadline deadline) { |
| 130 if (num_handles < 1) | 131 if (num_handles < 1) |
| 131 return MOJO_RESULT_INVALID_ARGUMENT; | 132 return MOJO_RESULT_INVALID_ARGUMENT; |
| 132 if (num_handles > kMaxWaitManyNumHandles) | 133 if (num_handles > kMaxWaitManyNumHandles) |
| 133 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 134 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 135 |
| 134 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); | 136 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); |
| 135 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, | 137 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, |
| 136 num_handles); | 138 num_handles); |
| 137 return WaitManyInternal(handles_reader.GetPointer(), | 139 uint32_t result_index = static_cast<uint32_t>(-1); |
| 138 signals_reader.GetPointer(), num_handles, deadline); | 140 MojoResult result = WaitManyInternal(handles_reader.GetPointer(), |
| 141 signals_reader.GetPointer(), num_handles, |
| 142 deadline, &result_index); |
| 143 return (result == MOJO_RESULT_OK) ? static_cast<MojoResult>(result_index) : |
| 144 result; |
| 139 } | 145 } |
| 140 | 146 |
| 141 MojoResult Core::CreateMessagePipe( | 147 MojoResult Core::CreateMessagePipe( |
| 142 UserPointer<const MojoCreateMessagePipeOptions> options, | 148 UserPointer<const MojoCreateMessagePipeOptions> options, |
| 143 UserPointer<MojoHandle> message_pipe_handle0, | 149 UserPointer<MojoHandle> message_pipe_handle0, |
| 144 UserPointer<MojoHandle> message_pipe_handle1) { | 150 UserPointer<MojoHandle> message_pipe_handle1) { |
| 145 MojoCreateMessagePipeOptions validated_options = {}; | 151 MojoCreateMessagePipeOptions validated_options = {}; |
| 146 // This will verify the |options| pointer. | 152 // This will verify the |options| pointer. |
| 147 MojoResult result = MessagePipeDispatcher::ValidateCreateOptions( | 153 MojoResult result = MessagePipeDispatcher::ValidateCreateOptions( |
| 148 options.GetPointerUnsafe(), &validated_options); | 154 options.GetPointerUnsafe(), &validated_options); |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 return mapping_table_.RemoveMapping(buffer.GetValue()); | 516 return mapping_table_.RemoveMapping(buffer.GetValue()); |
| 511 } | 517 } |
| 512 | 518 |
| 513 // Note: We allow |handles| to repeat the same handle multiple times, since | 519 // Note: We allow |handles| to repeat the same handle multiple times, since |
| 514 // different flags may be specified. | 520 // different flags may be specified. |
| 515 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this | 521 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this |
| 516 // more carefully and address it if necessary. | 522 // more carefully and address it if necessary. |
| 517 MojoResult Core::WaitManyInternal(const MojoHandle* handles, | 523 MojoResult Core::WaitManyInternal(const MojoHandle* handles, |
| 518 const MojoHandleSignals* signals, | 524 const MojoHandleSignals* signals, |
| 519 uint32_t num_handles, | 525 uint32_t num_handles, |
| 520 MojoDeadline deadline) { | 526 MojoDeadline deadline, |
| 527 uint32_t* result_index) { |
| 521 DCHECK_GT(num_handles, 0u); | 528 DCHECK_GT(num_handles, 0u); |
| 529 DCHECK_EQ(*result_index, static_cast<uint32_t>(-1)); |
| 522 | 530 |
| 523 DispatcherVector dispatchers; | 531 DispatcherVector dispatchers; |
| 524 dispatchers.reserve(num_handles); | 532 dispatchers.reserve(num_handles); |
| 525 for (uint32_t i = 0; i < num_handles; i++) { | 533 for (uint32_t i = 0; i < num_handles; i++) { |
| 526 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]); | 534 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]); |
| 527 if (!dispatcher) | 535 if (!dispatcher) { |
| 536 *result_index = i; |
| 528 return MOJO_RESULT_INVALID_ARGUMENT; | 537 return MOJO_RESULT_INVALID_ARGUMENT; |
| 538 } |
| 529 dispatchers.push_back(dispatcher); | 539 dispatchers.push_back(dispatcher); |
| 530 } | 540 } |
| 531 | 541 |
| 532 // TODO(vtl): Should make the waiter live (permanently) in TLS. | 542 // TODO(vtl): Should make the waiter live (permanently) in TLS. |
| 533 Waiter waiter; | 543 Waiter waiter; |
| 534 waiter.Init(); | 544 waiter.Init(); |
| 535 | 545 |
| 536 uint32_t i; | 546 uint32_t i; |
| 537 MojoResult rv = MOJO_RESULT_OK; | 547 MojoResult rv = MOJO_RESULT_OK; |
| 538 for (i = 0; i < num_handles; i++) { | 548 for (i = 0; i < num_handles; i++) { |
| 539 rv = dispatchers[i]->AddWaiter(&waiter, signals[i], i); | 549 rv = dispatchers[i]->AddWaiter(&waiter, signals[i], i); |
| 540 if (rv != MOJO_RESULT_OK) | 550 if (rv != MOJO_RESULT_OK) { |
| 551 *result_index = i; |
| 541 break; | 552 break; |
| 553 } |
| 542 } | 554 } |
| 543 uint32_t num_added = i; | 555 uint32_t num_added = i; |
| 544 | 556 |
| 545 if (rv == MOJO_RESULT_ALREADY_EXISTS) { | 557 if (rv == MOJO_RESULT_ALREADY_EXISTS) |
| 546 rv = static_cast<MojoResult>(i); // The i-th one is already "triggered". | 558 rv = MOJO_RESULT_OK; // The i-th one is already "triggered". |
| 547 } else if (rv == MOJO_RESULT_OK) { | 559 else if (rv == MOJO_RESULT_OK) |
| 548 uint32_t context = static_cast<uint32_t>(-1); | 560 rv = waiter.Wait(deadline, result_index); |
| 549 rv = waiter.Wait(deadline, &context); | |
| 550 if (rv == MOJO_RESULT_OK) | |
| 551 rv = static_cast<MojoResult>(context); | |
| 552 } | |
| 553 | 561 |
| 554 // Make sure no other dispatchers try to wake |waiter| for the current | 562 // Make sure no other dispatchers try to wake |waiter| for the current |
| 555 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be | 563 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be |
| 556 // destroyed, but this would still be required if the waiter were in TLS.) | 564 // destroyed, but this would still be required if the waiter were in TLS.) |
| 557 for (i = 0; i < num_added; i++) | 565 for (i = 0; i < num_added; i++) |
| 558 dispatchers[i]->RemoveWaiter(&waiter); | 566 dispatchers[i]->RemoveWaiter(&waiter); |
| 559 | 567 |
| 560 return rv; | 568 return rv; |
| 561 } | 569 } |
| 562 | 570 |
| 563 } // namespace system | 571 } // namespace system |
| 564 } // namespace mojo | 572 } // namespace mojo |
| OLD | NEW |