| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 Core::~Core() { | 83 Core::~Core() { |
| 84 } | 84 } |
| 85 | 85 |
| 86 MojoHandle Core::AddDispatcher(const scoped_refptr<Dispatcher>& dispatcher) { | 86 MojoHandle Core::AddDispatcher(const scoped_refptr<Dispatcher>& dispatcher) { |
| 87 base::AutoLock locker(handle_table_lock_); | 87 base::AutoLock locker(handle_table_lock_); |
| 88 return handle_table_.AddDispatcher(dispatcher); | 88 return handle_table_.AddDispatcher(dispatcher); |
| 89 } | 89 } |
| 90 | 90 |
| 91 scoped_refptr<Dispatcher> Core::GetDispatcher(MojoHandle handle) { | 91 scoped_refptr<Dispatcher> Core::GetDispatcher(MojoHandle handle) { |
| 92 if (handle == MOJO_HANDLE_INVALID) | 92 if (handle == MOJO_HANDLE_INVALID) |
| 93 return NULL; | 93 return nullptr; |
| 94 | 94 |
| 95 base::AutoLock locker(handle_table_lock_); | 95 base::AutoLock locker(handle_table_lock_); |
| 96 return handle_table_.GetDispatcher(handle); | 96 return handle_table_.GetDispatcher(handle); |
| 97 } | 97 } |
| 98 | 98 |
| 99 MojoTimeTicks Core::GetTimeTicksNow() { | 99 MojoTimeTicks Core::GetTimeTicksNow() { |
| 100 return base::TimeTicks::Now().ToInternalValue(); | 100 return base::TimeTicks::Now().ToInternalValue(); |
| 101 } | 101 } |
| 102 | 102 |
| 103 MojoResult Core::Close(MojoHandle handle) { | 103 MojoResult Core::Close(MojoHandle handle) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 124 MojoHandleSignals signals, | 124 MojoHandleSignals signals, |
| 125 MojoDeadline deadline, | 125 MojoDeadline deadline, |
| 126 UserPointer<MojoHandleSignalsState> signals_state) { | 126 UserPointer<MojoHandleSignalsState> signals_state) { |
| 127 uint32_t unused = static_cast<uint32_t>(-1); | 127 uint32_t unused = static_cast<uint32_t>(-1); |
| 128 HandleSignalsState hss; | 128 HandleSignalsState hss; |
| 129 MojoResult rv = WaitManyInternal(&handle, | 129 MojoResult rv = WaitManyInternal(&handle, |
| 130 &signals, | 130 &signals, |
| 131 1, | 131 1, |
| 132 deadline, | 132 deadline, |
| 133 &unused, | 133 &unused, |
| 134 signals_state.IsNull() ? NULL : &hss); | 134 signals_state.IsNull() ? nullptr : &hss); |
| 135 if (rv != MOJO_RESULT_INVALID_ARGUMENT && !signals_state.IsNull()) | 135 if (rv != MOJO_RESULT_INVALID_ARGUMENT && !signals_state.IsNull()) |
| 136 signals_state.Put(hss); | 136 signals_state.Put(hss); |
| 137 return rv; | 137 return rv; |
| 138 } | 138 } |
| 139 | 139 |
| 140 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, | 140 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, |
| 141 UserPointer<const MojoHandleSignals> signals, | 141 UserPointer<const MojoHandleSignals> signals, |
| 142 uint32_t num_handles, | 142 uint32_t num_handles, |
| 143 MojoDeadline deadline, | 143 MojoDeadline deadline, |
| 144 UserPointer<uint32_t> result_index, | 144 UserPointer<uint32_t> result_index, |
| 145 UserPointer<MojoHandleSignalsState> signals_states) { | 145 UserPointer<MojoHandleSignalsState> signals_states) { |
| 146 if (num_handles < 1) | 146 if (num_handles < 1) |
| 147 return MOJO_RESULT_INVALID_ARGUMENT; | 147 return MOJO_RESULT_INVALID_ARGUMENT; |
| 148 if (num_handles > kMaxWaitManyNumHandles) | 148 if (num_handles > kMaxWaitManyNumHandles) |
| 149 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 149 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 150 | 150 |
| 151 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); | 151 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); |
| 152 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, | 152 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, |
| 153 num_handles); | 153 num_handles); |
| 154 uint32_t index = static_cast<uint32_t>(-1); | 154 uint32_t index = static_cast<uint32_t>(-1); |
| 155 MojoResult rv; | 155 MojoResult rv; |
| 156 if (signals_states.IsNull()) { | 156 if (signals_states.IsNull()) { |
| 157 rv = WaitManyInternal(handles_reader.GetPointer(), | 157 rv = WaitManyInternal(handles_reader.GetPointer(), |
| 158 signals_reader.GetPointer(), | 158 signals_reader.GetPointer(), |
| 159 num_handles, | 159 num_handles, |
| 160 deadline, | 160 deadline, |
| 161 &index, | 161 &index, |
| 162 NULL); | 162 nullptr); |
| 163 } else { | 163 } else { |
| 164 UserPointer<MojoHandleSignalsState>::Writer signals_states_writer( | 164 UserPointer<MojoHandleSignalsState>::Writer signals_states_writer( |
| 165 signals_states, num_handles); | 165 signals_states, num_handles); |
| 166 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a | 166 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a |
| 167 // subclass of |MojoHandleSignalsState| that doesn't add any data members. | 167 // subclass of |MojoHandleSignalsState| that doesn't add any data members. |
| 168 rv = WaitManyInternal(handles_reader.GetPointer(), | 168 rv = WaitManyInternal(handles_reader.GetPointer(), |
| 169 signals_reader.GetPointer(), | 169 signals_reader.GetPointer(), |
| 170 num_handles, | 170 num_handles, |
| 171 deadline, | 171 deadline, |
| 172 &index, | 172 &index, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 uint32_t num_bytes, | 229 uint32_t num_bytes, |
| 230 UserPointer<const MojoHandle> handles, | 230 UserPointer<const MojoHandle> handles, |
| 231 uint32_t num_handles, | 231 uint32_t num_handles, |
| 232 MojoWriteMessageFlags flags) { | 232 MojoWriteMessageFlags flags) { |
| 233 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); | 233 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); |
| 234 if (!dispatcher.get()) | 234 if (!dispatcher.get()) |
| 235 return MOJO_RESULT_INVALID_ARGUMENT; | 235 return MOJO_RESULT_INVALID_ARGUMENT; |
| 236 | 236 |
| 237 // Easy case: not sending any handles. | 237 // Easy case: not sending any handles. |
| 238 if (num_handles == 0) | 238 if (num_handles == 0) |
| 239 return dispatcher->WriteMessage(bytes, num_bytes, NULL, flags); | 239 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, flags); |
| 240 | 240 |
| 241 // We have to handle |handles| here, since we have to mark them busy in the | 241 // We have to handle |handles| here, since we have to mark them busy in the |
| 242 // global handle table. We can't delegate this to the dispatcher, since the | 242 // global handle table. We can't delegate this to the dispatcher, since the |
| 243 // handle table lock must be acquired before the dispatcher lock. | 243 // handle table lock must be acquired before the dispatcher lock. |
| 244 // | 244 // |
| 245 // (This leads to an oddity: |handles|/|num_handles| are always verified for | 245 // (This leads to an oddity: |handles|/|num_handles| are always verified for |
| 246 // validity, even for dispatchers that don't support |WriteMessage()| and will | 246 // validity, even for dispatchers that don't support |WriteMessage()| and will |
| 247 // simply return failure unconditionally. It also breaks the usual | 247 // simply return failure unconditionally. It also breaks the usual |
| 248 // left-to-right verification order of arguments.) | 248 // left-to-right verification order of arguments.) |
| 249 if (num_handles > kMaxMessageNumHandles) | 249 if (num_handles > kMaxMessageNumHandles) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); | 302 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); |
| 303 if (!dispatcher.get()) | 303 if (!dispatcher.get()) |
| 304 return MOJO_RESULT_INVALID_ARGUMENT; | 304 return MOJO_RESULT_INVALID_ARGUMENT; |
| 305 | 305 |
| 306 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get(); | 306 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get(); |
| 307 | 307 |
| 308 MojoResult rv; | 308 MojoResult rv; |
| 309 if (num_handles_value == 0) { | 309 if (num_handles_value == 0) { |
| 310 // Easy case: won't receive any handles. | 310 // Easy case: won't receive any handles. |
| 311 rv = dispatcher->ReadMessage( | 311 rv = dispatcher->ReadMessage( |
| 312 bytes, num_bytes, NULL, &num_handles_value, flags); | 312 bytes, num_bytes, nullptr, &num_handles_value, flags); |
| 313 } else { | 313 } else { |
| 314 DispatcherVector dispatchers; | 314 DispatcherVector dispatchers; |
| 315 rv = dispatcher->ReadMessage( | 315 rv = dispatcher->ReadMessage( |
| 316 bytes, num_bytes, &dispatchers, &num_handles_value, flags); | 316 bytes, num_bytes, &dispatchers, &num_handles_value, flags); |
| 317 if (!dispatchers.empty()) { | 317 if (!dispatchers.empty()) { |
| 318 DCHECK_EQ(rv, MOJO_RESULT_OK); | 318 DCHECK_EQ(rv, MOJO_RESULT_OK); |
| 319 DCHECK(!num_handles.IsNull()); | 319 DCHECK(!num_handles.IsNull()); |
| 320 DCHECK_LE(dispatchers.size(), static_cast<size_t>(num_handles_value)); | 320 DCHECK_LE(dispatchers.size(), static_cast<size_t>(num_handles_value)); |
| 321 | 321 |
| 322 bool success; | 322 bool success; |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 } | 567 } |
| 568 | 568 |
| 569 // TODO(vtl): Should make the waiter live (permanently) in TLS. | 569 // TODO(vtl): Should make the waiter live (permanently) in TLS. |
| 570 Waiter waiter; | 570 Waiter waiter; |
| 571 waiter.Init(); | 571 waiter.Init(); |
| 572 | 572 |
| 573 uint32_t i; | 573 uint32_t i; |
| 574 MojoResult rv = MOJO_RESULT_OK; | 574 MojoResult rv = MOJO_RESULT_OK; |
| 575 for (i = 0; i < num_handles; i++) { | 575 for (i = 0; i < num_handles; i++) { |
| 576 rv = dispatchers[i]->AddWaiter( | 576 rv = dispatchers[i]->AddWaiter( |
| 577 &waiter, signals[i], i, signals_states ? &signals_states[i] : NULL); | 577 &waiter, signals[i], i, signals_states ? &signals_states[i] : nullptr); |
| 578 if (rv != MOJO_RESULT_OK) { | 578 if (rv != MOJO_RESULT_OK) { |
| 579 *result_index = i; | 579 *result_index = i; |
| 580 break; | 580 break; |
| 581 } | 581 } |
| 582 } | 582 } |
| 583 uint32_t num_added = i; | 583 uint32_t num_added = i; |
| 584 | 584 |
| 585 if (rv == MOJO_RESULT_ALREADY_EXISTS) | 585 if (rv == MOJO_RESULT_ALREADY_EXISTS) |
| 586 rv = MOJO_RESULT_OK; // The i-th one is already "triggered". | 586 rv = MOJO_RESULT_OK; // The i-th one is already "triggered". |
| 587 else if (rv == MOJO_RESULT_OK) | 587 else if (rv == MOJO_RESULT_OK) |
| 588 rv = waiter.Wait(deadline, result_index); | 588 rv = waiter.Wait(deadline, result_index); |
| 589 | 589 |
| 590 // Make sure no other dispatchers try to wake |waiter| for the current | 590 // Make sure no other dispatchers try to wake |waiter| for the current |
| 591 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be | 591 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be |
| 592 // destroyed, but this would still be required if the waiter were in TLS.) | 592 // destroyed, but this would still be required if the waiter were in TLS.) |
| 593 for (i = 0; i < num_added; i++) { | 593 for (i = 0; i < num_added; i++) { |
| 594 dispatchers[i]->RemoveWaiter(&waiter, | 594 dispatchers[i]->RemoveWaiter(&waiter, |
| 595 signals_states ? &signals_states[i] : NULL); | 595 signals_states ? &signals_states[i] : nullptr); |
| 596 } | 596 } |
| 597 if (signals_states) { | 597 if (signals_states) { |
| 598 for (; i < num_handles; i++) | 598 for (; i < num_handles; i++) |
| 599 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); | 599 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); |
| 600 } | 600 } |
| 601 | 601 |
| 602 return rv; | 602 return rv; |
| 603 } | 603 } |
| 604 | 604 |
| 605 } // namespace system | 605 } // namespace system |
| 606 } // namespace mojo | 606 } // namespace mojo |
| OLD | NEW |