| 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/edk/system/core.h" | 5 #include "mojo/edk/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/edk/embedder/platform_shared_buffer.h" | 11 #include "mojo/edk/embedder/platform_shared_buffer.h" |
| 12 #include "mojo/edk/embedder/platform_support.h" | 12 #include "mojo/edk/embedder/platform_support.h" |
| 13 #include "mojo/edk/system/constants.h" | 13 #include "mojo/edk/system/configuration.h" |
| 14 #include "mojo/edk/system/data_pipe.h" | 14 #include "mojo/edk/system/data_pipe.h" |
| 15 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 15 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" |
| 16 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" | 16 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" |
| 17 #include "mojo/edk/system/dispatcher.h" | 17 #include "mojo/edk/system/dispatcher.h" |
| 18 #include "mojo/edk/system/handle_signals_state.h" | 18 #include "mojo/edk/system/handle_signals_state.h" |
| 19 #include "mojo/edk/system/local_data_pipe.h" | 19 #include "mojo/edk/system/local_data_pipe.h" |
| 20 #include "mojo/edk/system/memory.h" | 20 #include "mojo/edk/system/memory.h" |
| 21 #include "mojo/edk/system/message_pipe.h" | 21 #include "mojo/edk/system/message_pipe.h" |
| 22 #include "mojo/edk/system/message_pipe_dispatcher.h" | 22 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 23 #include "mojo/edk/system/shared_buffer_dispatcher.h" | 23 #include "mojo/edk/system/shared_buffer_dispatcher.h" |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 // |Dispatcher| in dispatcher.h. | 119 // |Dispatcher| in dispatcher.h. |
| 120 return dispatcher->Close(); | 120 return dispatcher->Close(); |
| 121 } | 121 } |
| 122 | 122 |
| 123 MojoResult Core::Wait(MojoHandle handle, | 123 MojoResult Core::Wait(MojoHandle handle, |
| 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, &signals, 1, deadline, &unused, |
| 130 &signals, | |
| 131 1, | |
| 132 deadline, | |
| 133 &unused, | |
| 134 signals_state.IsNull() ? nullptr : &hss); | 130 signals_state.IsNull() ? nullptr : &hss); |
| 135 if (rv != MOJO_RESULT_INVALID_ARGUMENT && !signals_state.IsNull()) | 131 if (rv != MOJO_RESULT_INVALID_ARGUMENT && !signals_state.IsNull()) |
| 136 signals_state.Put(hss); | 132 signals_state.Put(hss); |
| 137 return rv; | 133 return rv; |
| 138 } | 134 } |
| 139 | 135 |
| 140 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, | 136 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, |
| 141 UserPointer<const MojoHandleSignals> signals, | 137 UserPointer<const MojoHandleSignals> signals, |
| 142 uint32_t num_handles, | 138 uint32_t num_handles, |
| 143 MojoDeadline deadline, | 139 MojoDeadline deadline, |
| 144 UserPointer<uint32_t> result_index, | 140 UserPointer<uint32_t> result_index, |
| 145 UserPointer<MojoHandleSignalsState> signals_states) { | 141 UserPointer<MojoHandleSignalsState> signals_states) { |
| 146 if (num_handles < 1) | 142 if (num_handles < 1) |
| 147 return MOJO_RESULT_INVALID_ARGUMENT; | 143 return MOJO_RESULT_INVALID_ARGUMENT; |
| 148 if (num_handles > kMaxWaitManyNumHandles) | 144 if (num_handles > GetConfiguration().max_wait_many_num_handles) |
| 149 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 145 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 150 | 146 |
| 151 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); | 147 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); |
| 152 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, | 148 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, |
| 153 num_handles); | 149 num_handles); |
| 154 uint32_t index = static_cast<uint32_t>(-1); | 150 uint32_t index = static_cast<uint32_t>(-1); |
| 155 MojoResult rv; | 151 MojoResult rv; |
| 156 if (signals_states.IsNull()) { | 152 if (signals_states.IsNull()) { |
| 157 rv = WaitManyInternal(handles_reader.GetPointer(), | 153 rv = WaitManyInternal(handles_reader.GetPointer(), |
| 158 signals_reader.GetPointer(), | 154 signals_reader.GetPointer(), num_handles, deadline, |
| 159 num_handles, | 155 &index, nullptr); |
| 160 deadline, | |
| 161 &index, | |
| 162 nullptr); | |
| 163 } else { | 156 } else { |
| 164 UserPointer<MojoHandleSignalsState>::Writer signals_states_writer( | 157 UserPointer<MojoHandleSignalsState>::Writer signals_states_writer( |
| 165 signals_states, num_handles); | 158 signals_states, num_handles); |
| 166 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a | 159 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a |
| 167 // subclass of |MojoHandleSignalsState| that doesn't add any data members. | 160 // subclass of |MojoHandleSignalsState| that doesn't add any data members. |
| 168 rv = WaitManyInternal(handles_reader.GetPointer(), | 161 rv = WaitManyInternal(handles_reader.GetPointer(), |
| 169 signals_reader.GetPointer(), | 162 signals_reader.GetPointer(), num_handles, deadline, |
| 170 num_handles, | 163 &index, reinterpret_cast<HandleSignalsState*>( |
| 171 deadline, | 164 signals_states_writer.GetPointer())); |
| 172 &index, | |
| 173 reinterpret_cast<HandleSignalsState*>( | |
| 174 signals_states_writer.GetPointer())); | |
| 175 if (rv != MOJO_RESULT_INVALID_ARGUMENT) | 165 if (rv != MOJO_RESULT_INVALID_ARGUMENT) |
| 176 signals_states_writer.Commit(); | 166 signals_states_writer.Commit(); |
| 177 } | 167 } |
| 178 if (index != static_cast<uint32_t>(-1) && !result_index.IsNull()) | 168 if (index != static_cast<uint32_t>(-1) && !result_index.IsNull()) |
| 179 result_index.Put(index); | 169 result_index.Put(index); |
| 180 return rv; | 170 return rv; |
| 181 } | 171 } |
| 182 | 172 |
| 183 MojoResult Core::CreateMessagePipe( | 173 MojoResult Core::CreateMessagePipe( |
| 184 UserPointer<const MojoCreateMessagePipeOptions> options, | 174 UserPointer<const MojoCreateMessagePipeOptions> options, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, flags); | 229 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, flags); |
| 240 | 230 |
| 241 // We have to handle |handles| here, since we have to mark them busy in the | 231 // 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 | 232 // global handle table. We can't delegate this to the dispatcher, since the |
| 243 // handle table lock must be acquired before the dispatcher lock. | 233 // handle table lock must be acquired before the dispatcher lock. |
| 244 // | 234 // |
| 245 // (This leads to an oddity: |handles|/|num_handles| are always verified for | 235 // (This leads to an oddity: |handles|/|num_handles| are always verified for |
| 246 // validity, even for dispatchers that don't support |WriteMessage()| and will | 236 // validity, even for dispatchers that don't support |WriteMessage()| and will |
| 247 // simply return failure unconditionally. It also breaks the usual | 237 // simply return failure unconditionally. It also breaks the usual |
| 248 // left-to-right verification order of arguments.) | 238 // left-to-right verification order of arguments.) |
| 249 if (num_handles > kMaxMessageNumHandles) | 239 if (num_handles > GetConfiguration().max_message_num_handles) |
| 250 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 240 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 251 | 241 |
| 252 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); | 242 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); |
| 253 | 243 |
| 254 // We'll need to hold on to the dispatchers so that we can pass them on to | 244 // We'll need to hold on to the dispatchers so that we can pass them on to |
| 255 // |WriteMessage()| and also so that we can unlock their locks afterwards | 245 // |WriteMessage()| and also so that we can unlock their locks afterwards |
| 256 // without accessing the handle table. These can be dumb pointers, since their | 246 // without accessing the handle table. These can be dumb pointers, since their |
| 257 // entries in the handle table won't get removed (since they'll be marked as | 247 // entries in the handle table won't get removed (since they'll be marked as |
| 258 // busy). | 248 // busy). |
| 259 std::vector<DispatcherTransport> transports(num_handles); | 249 std::vector<DispatcherTransport> transports(num_handles); |
| 260 | 250 |
| 261 // When we pass handles, we have to try to take all their dispatchers' locks | 251 // When we pass handles, we have to try to take all their dispatchers' locks |
| 262 // and mark the handles as busy. If the call succeeds, we then remove the | 252 // and mark the handles as busy. If the call succeeds, we then remove the |
| 263 // handles from the handle table. | 253 // handles from the handle table. |
| 264 { | 254 { |
| 265 base::AutoLock locker(handle_table_lock_); | 255 base::AutoLock locker(handle_table_lock_); |
| 266 MojoResult result = | 256 MojoResult result = handle_table_.MarkBusyAndStartTransport( |
| 267 handle_table_.MarkBusyAndStartTransport(message_pipe_handle, | 257 message_pipe_handle, handles_reader.GetPointer(), num_handles, |
| 268 handles_reader.GetPointer(), | 258 &transports); |
| 269 num_handles, | |
| 270 &transports); | |
| 271 if (result != MOJO_RESULT_OK) | 259 if (result != MOJO_RESULT_OK) |
| 272 return result; | 260 return result; |
| 273 } | 261 } |
| 274 | 262 |
| 275 MojoResult rv = | 263 MojoResult rv = |
| 276 dispatcher->WriteMessage(bytes, num_bytes, &transports, flags); | 264 dispatcher->WriteMessage(bytes, num_bytes, &transports, flags); |
| 277 | 265 |
| 278 // We need to release the dispatcher locks before we take the handle table | 266 // We need to release the dispatcher locks before we take the handle table |
| 279 // lock. | 267 // lock. |
| 280 for (uint32_t i = 0; i < num_handles; i++) | 268 for (uint32_t i = 0; i < num_handles; i++) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 301 MojoReadMessageFlags flags) { | 289 MojoReadMessageFlags flags) { |
| 302 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); | 290 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); |
| 303 if (!dispatcher.get()) | 291 if (!dispatcher.get()) |
| 304 return MOJO_RESULT_INVALID_ARGUMENT; | 292 return MOJO_RESULT_INVALID_ARGUMENT; |
| 305 | 293 |
| 306 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get(); | 294 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get(); |
| 307 | 295 |
| 308 MojoResult rv; | 296 MojoResult rv; |
| 309 if (num_handles_value == 0) { | 297 if (num_handles_value == 0) { |
| 310 // Easy case: won't receive any handles. | 298 // Easy case: won't receive any handles. |
| 311 rv = dispatcher->ReadMessage( | 299 rv = dispatcher->ReadMessage(bytes, num_bytes, nullptr, &num_handles_value, |
| 312 bytes, num_bytes, nullptr, &num_handles_value, flags); | 300 flags); |
| 313 } else { | 301 } else { |
| 314 DispatcherVector dispatchers; | 302 DispatcherVector dispatchers; |
| 315 rv = dispatcher->ReadMessage( | 303 rv = dispatcher->ReadMessage(bytes, num_bytes, &dispatchers, |
| 316 bytes, num_bytes, &dispatchers, &num_handles_value, flags); | 304 &num_handles_value, flags); |
| 317 if (!dispatchers.empty()) { | 305 if (!dispatchers.empty()) { |
| 318 DCHECK_EQ(rv, MOJO_RESULT_OK); | 306 DCHECK_EQ(rv, MOJO_RESULT_OK); |
| 319 DCHECK(!num_handles.IsNull()); | 307 DCHECK(!num_handles.IsNull()); |
| 320 DCHECK_LE(dispatchers.size(), static_cast<size_t>(num_handles_value)); | 308 DCHECK_LE(dispatchers.size(), static_cast<size_t>(num_handles_value)); |
| 321 | 309 |
| 322 bool success; | 310 bool success; |
| 323 UserPointer<MojoHandle>::Writer handles_writer(handles, | 311 UserPointer<MojoHandle>::Writer handles_writer(handles, |
| 324 dispatchers.size()); | 312 dispatchers.size()); |
| 325 { | 313 { |
| 326 base::AutoLock locker(handle_table_lock_); | 314 base::AutoLock locker(handle_table_lock_); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 UserPointer<const MojoCreateSharedBufferOptions> options, | 447 UserPointer<const MojoCreateSharedBufferOptions> options, |
| 460 uint64_t num_bytes, | 448 uint64_t num_bytes, |
| 461 UserPointer<MojoHandle> shared_buffer_handle) { | 449 UserPointer<MojoHandle> shared_buffer_handle) { |
| 462 MojoCreateSharedBufferOptions validated_options = {}; | 450 MojoCreateSharedBufferOptions validated_options = {}; |
| 463 MojoResult result = SharedBufferDispatcher::ValidateCreateOptions( | 451 MojoResult result = SharedBufferDispatcher::ValidateCreateOptions( |
| 464 options, &validated_options); | 452 options, &validated_options); |
| 465 if (result != MOJO_RESULT_OK) | 453 if (result != MOJO_RESULT_OK) |
| 466 return result; | 454 return result; |
| 467 | 455 |
| 468 scoped_refptr<SharedBufferDispatcher> dispatcher; | 456 scoped_refptr<SharedBufferDispatcher> dispatcher; |
| 469 result = SharedBufferDispatcher::Create( | 457 result = SharedBufferDispatcher::Create(platform_support(), validated_options, |
| 470 platform_support(), validated_options, num_bytes, &dispatcher); | 458 num_bytes, &dispatcher); |
| 471 if (result != MOJO_RESULT_OK) { | 459 if (result != MOJO_RESULT_OK) { |
| 472 DCHECK(!dispatcher.get()); | 460 DCHECK(!dispatcher.get()); |
| 473 return result; | 461 return result; |
| 474 } | 462 } |
| 475 | 463 |
| 476 MojoHandle h = AddDispatcher(dispatcher); | 464 MojoHandle h = AddDispatcher(dispatcher); |
| 477 if (h == MOJO_HANDLE_INVALID) { | 465 if (h == MOJO_HANDLE_INVALID) { |
| 478 LOG(ERROR) << "Handle table full"; | 466 LOG(ERROR) << "Handle table full"; |
| 479 dispatcher->Close(); | 467 dispatcher->Close(); |
| 480 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 468 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 if (signals_states) { | 585 if (signals_states) { |
| 598 for (; i < num_handles; i++) | 586 for (; i < num_handles; i++) |
| 599 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); | 587 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); |
| 600 } | 588 } |
| 601 | 589 |
| 602 return rv; | 590 return rv; |
| 603 } | 591 } |
| 604 | 592 |
| 605 } // namespace system | 593 } // namespace system |
| 606 } // namespace mojo | 594 } // namespace mojo |
| OLD | NEW |