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 |