| 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_channel_pair.h" |
| 11 #include "mojo/edk/embedder/platform_shared_buffer.h" | 12 #include "mojo/edk/embedder/platform_shared_buffer.h" |
| 12 #include "mojo/edk/embedder/platform_support.h" | 13 #include "mojo/edk/embedder/platform_support.h" |
| 13 #include "mojo/edk/system/async_waiter.h" | 14 #include "mojo/edk/system/async_waiter.h" |
| 14 #include "mojo/edk/system/configuration.h" | 15 #include "mojo/edk/system/configuration.h" |
| 15 #include "mojo/edk/system/data_pipe.h" | 16 #include "mojo/edk/system/data_pipe.h" |
| 16 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 17 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" |
| 17 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" | 18 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" |
| 18 #include "mojo/edk/system/dispatcher.h" | 19 #include "mojo/edk/system/dispatcher.h" |
| 19 #include "mojo/edk/system/handle_signals_state.h" | 20 #include "mojo/edk/system/handle_signals_state.h" |
| 20 #include "mojo/edk/system/memory.h" | 21 #include "mojo/edk/system/memory.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" |
| 24 #include "mojo/edk/system/waiter.h" | 24 #include "mojo/edk/system/waiter.h" |
| 25 #include "mojo/public/c/system/macros.h" | 25 #include "mojo/public/c/system/macros.h" |
| 26 #include "mojo/public/cpp/system/macros.h" | 26 #include "mojo/public/cpp/system/macros.h" |
| 27 | 27 |
| 28 namespace mojo { | 28 namespace mojo { |
| 29 namespace system { | 29 namespace edk { |
| 30 | 30 |
| 31 // Implementation notes | 31 // Implementation notes |
| 32 // | 32 // |
| 33 // Mojo primitives are implemented by the singleton |Core| object. Most calls | 33 // Mojo primitives are implemented by the singleton |Core| object. Most calls |
| 34 // are for a "primary" handle (the first argument). |Core::GetDispatcher()| is | 34 // are for a "primary" handle (the first argument). |Core::GetDispatcher()| is |
| 35 // used to look up a |Dispatcher| object for a given handle. That object | 35 // used to look up a |Dispatcher| object for a given handle. That object |
| 36 // implements most primitives for that object. The wait primitives are not | 36 // implements most primitives for that object. The wait primitives are not |
| 37 // attached to objects and are implemented by |Core| itself. | 37 // attached to objects and are implemented by |Core| itself. |
| 38 // | 38 // |
| 39 // Some objects have multiple handles associated to them, e.g., message pipes | 39 // Some objects have multiple handles associated to them, e.g., message pipes |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 // | 71 // |
| 72 // Notes: | 72 // Notes: |
| 73 // - While holding a |Dispatcher| lock, you may not unconditionally attempt | 73 // - While holding a |Dispatcher| lock, you may not unconditionally attempt |
| 74 // to take another |Dispatcher| lock. (This has consequences on the | 74 // to take another |Dispatcher| lock. (This has consequences on the |
| 75 // concurrency semantics of |MojoWriteMessage()| when passing handles.) | 75 // concurrency semantics of |MojoWriteMessage()| when passing handles.) |
| 76 // Doing so would lead to deadlock. | 76 // Doing so would lead to deadlock. |
| 77 // - Locks at the "INF" level may not have any locks taken while they are | 77 // - Locks at the "INF" level may not have any locks taken while they are |
| 78 // held. | 78 // held. |
| 79 | 79 |
| 80 // TODO(vtl): This should take a |scoped_ptr<PlatformSupport>| as a parameter. | 80 // TODO(vtl): This should take a |scoped_ptr<PlatformSupport>| as a parameter. |
| 81 Core::Core(embedder::PlatformSupport* platform_support) | 81 Core::Core(PlatformSupport* platform_support) |
| 82 : platform_support_(platform_support) { | 82 : platform_support_(platform_support) { |
| 83 } | 83 } |
| 84 | 84 |
| 85 Core::~Core() { | 85 Core::~Core() { |
| 86 } | 86 } |
| 87 | 87 |
| 88 MojoHandle Core::AddDispatcher(const scoped_refptr<Dispatcher>& dispatcher) { | 88 MojoHandle Core::AddDispatcher(const scoped_refptr<Dispatcher>& dispatcher) { |
| 89 MutexLocker locker(&handle_table_mutex_); | 89 base::AutoLock locker(handle_table_lock_); |
| 90 return handle_table_.AddDispatcher(dispatcher); | 90 return handle_table_.AddDispatcher(dispatcher); |
| 91 } | 91 } |
| 92 | 92 |
| 93 scoped_refptr<Dispatcher> Core::GetDispatcher(MojoHandle handle) { | 93 scoped_refptr<Dispatcher> Core::GetDispatcher(MojoHandle handle) { |
| 94 if (handle == MOJO_HANDLE_INVALID) | 94 if (handle == MOJO_HANDLE_INVALID) |
| 95 return nullptr; | 95 return nullptr; |
| 96 | 96 |
| 97 MutexLocker locker(&handle_table_mutex_); | 97 base::AutoLock locker(handle_table_lock_); |
| 98 return handle_table_.GetDispatcher(handle); | 98 return handle_table_.GetDispatcher(handle); |
| 99 } | 99 } |
| 100 | 100 |
| 101 MojoResult Core::GetAndRemoveDispatcher(MojoHandle handle, | 101 MojoResult Core::GetAndRemoveDispatcher(MojoHandle handle, |
| 102 scoped_refptr<Dispatcher>* dispatcher) { | 102 scoped_refptr<Dispatcher>* dispatcher) { |
| 103 if (handle == MOJO_HANDLE_INVALID) | 103 if (handle == MOJO_HANDLE_INVALID) |
| 104 return MOJO_RESULT_INVALID_ARGUMENT; | 104 return MOJO_RESULT_INVALID_ARGUMENT; |
| 105 | 105 |
| 106 MutexLocker locker(&handle_table_mutex_); | 106 base::AutoLock locker(handle_table_lock_); |
| 107 return handle_table_.GetAndRemoveDispatcher(handle, dispatcher); | 107 return handle_table_.GetAndRemoveDispatcher(handle, dispatcher); |
| 108 } | 108 } |
| 109 | 109 |
| 110 MojoResult Core::AsyncWait(MojoHandle handle, | 110 MojoResult Core::AsyncWait(MojoHandle handle, |
| 111 MojoHandleSignals signals, | 111 MojoHandleSignals signals, |
| 112 const base::Callback<void(MojoResult)>& callback) { | 112 const base::Callback<void(MojoResult)>& callback) { |
| 113 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); | 113 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); |
| 114 DCHECK(dispatcher); | 114 DCHECK(dispatcher); |
| 115 | 115 |
| 116 scoped_ptr<AsyncWaiter> waiter = make_scoped_ptr(new AsyncWaiter(callback)); | 116 scoped_ptr<AsyncWaiter> waiter = make_scoped_ptr(new AsyncWaiter(callback)); |
| 117 MojoResult rv = dispatcher->AddAwakable(waiter.get(), signals, 0, nullptr); | 117 MojoResult rv = dispatcher->AddAwakable(waiter.get(), signals, 0, nullptr); |
| 118 if (rv == MOJO_RESULT_OK) | 118 if (rv == MOJO_RESULT_OK) |
| 119 ignore_result(waiter.release()); | 119 ignore_result(waiter.release()); |
| 120 return rv; | 120 return rv; |
| 121 } | 121 } |
| 122 | 122 |
| 123 MojoTimeTicks Core::GetTimeTicksNow() { | 123 MojoTimeTicks Core::GetTimeTicksNow() { |
| 124 return base::TimeTicks::Now().ToInternalValue(); | 124 return base::TimeTicks::Now().ToInternalValue(); |
| 125 } | 125 } |
| 126 | 126 |
| 127 MojoResult Core::Close(MojoHandle handle) { | 127 MojoResult Core::Close(MojoHandle handle) { |
| 128 if (handle == MOJO_HANDLE_INVALID) | 128 if (handle == MOJO_HANDLE_INVALID) |
| 129 return MOJO_RESULT_INVALID_ARGUMENT; | 129 return MOJO_RESULT_INVALID_ARGUMENT; |
| 130 | 130 |
| 131 scoped_refptr<Dispatcher> dispatcher; | 131 scoped_refptr<Dispatcher> dispatcher; |
| 132 { | 132 { |
| 133 MutexLocker locker(&handle_table_mutex_); | 133 base::AutoLock locker(handle_table_lock_); |
| 134 MojoResult result = | 134 MojoResult result = |
| 135 handle_table_.GetAndRemoveDispatcher(handle, &dispatcher); | 135 handle_table_.GetAndRemoveDispatcher(handle, &dispatcher); |
| 136 if (result != MOJO_RESULT_OK) | 136 if (result != MOJO_RESULT_OK) |
| 137 return result; | 137 return result; |
| 138 } | 138 } |
| 139 | 139 |
| 140 // The dispatcher doesn't have a say in being closed, but gets notified of it. | 140 // The dispatcher doesn't have a say in being closed, but gets notified of it. |
| 141 // Note: This is done outside of |handle_table_mutex_|. As a result, there's a | 141 // Note: This is done outside of |handle_table_lock_|. As a result, there's a |
| 142 // race condition that the dispatcher must handle; see the comment in | 142 // race condition that the dispatcher must handle; see the comment in |
| 143 // |Dispatcher| in dispatcher.h. | 143 // |Dispatcher| in dispatcher.h. |
| 144 return dispatcher->Close(); | 144 return dispatcher->Close(); |
| 145 } | 145 } |
| 146 | 146 |
| 147 MojoResult Core::Wait(MojoHandle handle, | 147 MojoResult Core::Wait(MojoHandle handle, |
| 148 MojoHandleSignals signals, | 148 MojoHandleSignals signals, |
| 149 MojoDeadline deadline, | 149 MojoDeadline deadline, |
| 150 UserPointer<MojoHandleSignalsState> signals_state) { | 150 UserPointer<MojoHandleSignalsState> signals_state) { |
| 151 uint32_t unused = static_cast<uint32_t>(-1); | 151 uint32_t unused = static_cast<uint32_t>(-1); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 if (result != MOJO_RESULT_OK) | 204 if (result != MOJO_RESULT_OK) |
| 205 return result; | 205 return result; |
| 206 | 206 |
| 207 scoped_refptr<MessagePipeDispatcher> dispatcher0 = | 207 scoped_refptr<MessagePipeDispatcher> dispatcher0 = |
| 208 MessagePipeDispatcher::Create(validated_options); | 208 MessagePipeDispatcher::Create(validated_options); |
| 209 scoped_refptr<MessagePipeDispatcher> dispatcher1 = | 209 scoped_refptr<MessagePipeDispatcher> dispatcher1 = |
| 210 MessagePipeDispatcher::Create(validated_options); | 210 MessagePipeDispatcher::Create(validated_options); |
| 211 | 211 |
| 212 std::pair<MojoHandle, MojoHandle> handle_pair; | 212 std::pair<MojoHandle, MojoHandle> handle_pair; |
| 213 { | 213 { |
| 214 MutexLocker locker(&handle_table_mutex_); | 214 base::AutoLock locker(handle_table_lock_); |
| 215 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); | 215 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); |
| 216 } | 216 } |
| 217 if (handle_pair.first == MOJO_HANDLE_INVALID) { | 217 if (handle_pair.first == MOJO_HANDLE_INVALID) { |
| 218 DCHECK_EQ(handle_pair.second, MOJO_HANDLE_INVALID); | 218 DCHECK_EQ(handle_pair.second, MOJO_HANDLE_INVALID); |
| 219 LOG(ERROR) << "Handle table full"; | 219 LOG(ERROR) << "Handle table full"; |
| 220 dispatcher0->Close(); | 220 dispatcher0->Close(); |
| 221 dispatcher1->Close(); | 221 dispatcher1->Close(); |
| 222 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 222 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 223 } | 223 } |
| 224 | 224 |
| 225 scoped_refptr<MessagePipe> message_pipe(MessagePipe::CreateLocalLocal()); | 225 PlatformChannelPair channel_pair; |
| 226 dispatcher0->Init(message_pipe, 0); | 226 dispatcher0->Init(channel_pair.PassServerHandle()); |
| 227 dispatcher1->Init(message_pipe, 1); | 227 dispatcher1->Init(channel_pair.PassClientHandle()); |
| 228 | 228 |
| 229 message_pipe_handle0.Put(handle_pair.first); | 229 message_pipe_handle0.Put(handle_pair.first); |
| 230 message_pipe_handle1.Put(handle_pair.second); | 230 message_pipe_handle1.Put(handle_pair.second); |
| 231 return MOJO_RESULT_OK; | 231 return MOJO_RESULT_OK; |
| 232 } | 232 } |
| 233 | 233 |
| 234 // Implementation note: To properly cancel waiters and avoid other races, this | 234 // Implementation note: To properly cancel waiters and avoid other races, this |
| 235 // does not transfer dispatchers from one handle to another, even when sending a | 235 // does not transfer dispatchers from one handle to another, even when sending a |
| 236 // message in-process. Instead, it must transfer the "contents" of the | 236 // message in-process. Instead, it must transfer the "contents" of the |
| 237 // dispatcher to a new dispatcher, and then close the old dispatcher. If this | 237 // dispatcher to a new dispatcher, and then close the old dispatcher. If this |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 // |WriteMessage()| and also so that we can unlock their locks afterwards | 269 // |WriteMessage()| and also so that we can unlock their locks afterwards |
| 270 // without accessing the handle table. These can be dumb pointers, since their | 270 // without accessing the handle table. These can be dumb pointers, since their |
| 271 // entries in the handle table won't get removed (since they'll be marked as | 271 // entries in the handle table won't get removed (since they'll be marked as |
| 272 // busy). | 272 // busy). |
| 273 std::vector<DispatcherTransport> transports(num_handles); | 273 std::vector<DispatcherTransport> transports(num_handles); |
| 274 | 274 |
| 275 // When we pass handles, we have to try to take all their dispatchers' locks | 275 // When we pass handles, we have to try to take all their dispatchers' locks |
| 276 // and mark the handles as busy. If the call succeeds, we then remove the | 276 // and mark the handles as busy. If the call succeeds, we then remove the |
| 277 // handles from the handle table. | 277 // handles from the handle table. |
| 278 { | 278 { |
| 279 MutexLocker locker(&handle_table_mutex_); | 279 base::AutoLock locker(handle_table_lock_); |
| 280 MojoResult result = handle_table_.MarkBusyAndStartTransport( | 280 MojoResult result = handle_table_.MarkBusyAndStartTransport( |
| 281 message_pipe_handle, handles_reader.GetPointer(), num_handles, | 281 message_pipe_handle, handles_reader.GetPointer(), num_handles, |
| 282 &transports); | 282 &transports); |
| 283 if (result != MOJO_RESULT_OK) | 283 if (result != MOJO_RESULT_OK) |
| 284 return result; | 284 return result; |
| 285 } | 285 } |
| 286 | 286 |
| 287 MojoResult rv = | 287 MojoResult rv = |
| 288 dispatcher->WriteMessage(bytes, num_bytes, &transports, flags); | 288 dispatcher->WriteMessage(bytes, num_bytes, &transports, flags); |
| 289 | 289 |
| 290 // We need to release the dispatcher locks before we take the handle table | 290 // We need to release the dispatcher locks before we take the handle table |
| 291 // lock. | 291 // lock. |
| 292 for (uint32_t i = 0; i < num_handles; i++) | 292 for (uint32_t i = 0; i < num_handles; i++) |
| 293 transports[i].End(); | 293 transports[i].End(); |
| 294 | 294 |
| 295 { | 295 { |
| 296 MutexLocker locker(&handle_table_mutex_); | 296 base::AutoLock locker(handle_table_lock_); |
| 297 if (rv == MOJO_RESULT_OK) { | 297 if (rv == MOJO_RESULT_OK) { |
| 298 handle_table_.RemoveBusyHandles(handles_reader.GetPointer(), num_handles); | 298 handle_table_.RemoveBusyHandles(handles_reader.GetPointer(), num_handles); |
| 299 } else { | 299 } else { |
| 300 handle_table_.RestoreBusyHandles(handles_reader.GetPointer(), | 300 handle_table_.RestoreBusyHandles(handles_reader.GetPointer(), |
| 301 num_handles); | 301 num_handles); |
| 302 } | 302 } |
| 303 } | 303 } |
| 304 | 304 |
| 305 return rv; | 305 return rv; |
| 306 } | 306 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 328 &num_handles_value, flags); | 328 &num_handles_value, flags); |
| 329 if (!dispatchers.empty()) { | 329 if (!dispatchers.empty()) { |
| 330 DCHECK_EQ(rv, MOJO_RESULT_OK); | 330 DCHECK_EQ(rv, MOJO_RESULT_OK); |
| 331 DCHECK(!num_handles.IsNull()); | 331 DCHECK(!num_handles.IsNull()); |
| 332 DCHECK_LE(dispatchers.size(), static_cast<size_t>(num_handles_value)); | 332 DCHECK_LE(dispatchers.size(), static_cast<size_t>(num_handles_value)); |
| 333 | 333 |
| 334 bool success; | 334 bool success; |
| 335 UserPointer<MojoHandle>::Writer handles_writer(handles, | 335 UserPointer<MojoHandle>::Writer handles_writer(handles, |
| 336 dispatchers.size()); | 336 dispatchers.size()); |
| 337 { | 337 { |
| 338 MutexLocker locker(&handle_table_mutex_); | 338 base::AutoLock locker(handle_table_lock_); |
| 339 success = handle_table_.AddDispatcherVector( | 339 success = handle_table_.AddDispatcherVector( |
| 340 dispatchers, handles_writer.GetPointer()); | 340 dispatchers, handles_writer.GetPointer()); |
| 341 } | 341 } |
| 342 if (success) { | 342 if (success) { |
| 343 handles_writer.Commit(); | 343 handles_writer.Commit(); |
| 344 } else { | 344 } else { |
| 345 LOG(ERROR) << "Received message with " << dispatchers.size() | 345 LOG(ERROR) << "Received message with " << dispatchers.size() |
| 346 << " handles, but handle table full"; | 346 << " handles, but handle table full"; |
| 347 // Close dispatchers (outside the lock). | 347 // Close dispatchers (outside the lock). |
| 348 for (size_t i = 0; i < dispatchers.size(); i++) { | 348 for (size_t i = 0; i < dispatchers.size(); i++) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 364 UserPointer<const MojoCreateDataPipeOptions> options, | 364 UserPointer<const MojoCreateDataPipeOptions> options, |
| 365 UserPointer<MojoHandle> data_pipe_producer_handle, | 365 UserPointer<MojoHandle> data_pipe_producer_handle, |
| 366 UserPointer<MojoHandle> data_pipe_consumer_handle) { | 366 UserPointer<MojoHandle> data_pipe_consumer_handle) { |
| 367 MojoCreateDataPipeOptions validated_options = {}; | 367 MojoCreateDataPipeOptions validated_options = {}; |
| 368 MojoResult result = | 368 MojoResult result = |
| 369 DataPipe::ValidateCreateOptions(options, &validated_options); | 369 DataPipe::ValidateCreateOptions(options, &validated_options); |
| 370 if (result != MOJO_RESULT_OK) | 370 if (result != MOJO_RESULT_OK) |
| 371 return result; | 371 return result; |
| 372 | 372 |
| 373 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher = | 373 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher = |
| 374 DataPipeProducerDispatcher::Create(); | 374 DataPipeProducerDispatcher::Create(validated_options); |
| 375 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher = | 375 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher = |
| 376 DataPipeConsumerDispatcher::Create(); | 376 DataPipeConsumerDispatcher::Create(validated_options); |
| 377 | 377 |
| 378 std::pair<MojoHandle, MojoHandle> handle_pair; | 378 std::pair<MojoHandle, MojoHandle> handle_pair; |
| 379 { | 379 { |
| 380 MutexLocker locker(&handle_table_mutex_); | 380 base::AutoLock locker(handle_table_lock_); |
| 381 handle_pair = handle_table_.AddDispatcherPair(producer_dispatcher, | 381 handle_pair = handle_table_.AddDispatcherPair(producer_dispatcher, |
| 382 consumer_dispatcher); | 382 consumer_dispatcher); |
| 383 } | 383 } |
| 384 if (handle_pair.first == MOJO_HANDLE_INVALID) { | 384 if (handle_pair.first == MOJO_HANDLE_INVALID) { |
| 385 DCHECK_EQ(handle_pair.second, MOJO_HANDLE_INVALID); | 385 DCHECK_EQ(handle_pair.second, MOJO_HANDLE_INVALID); |
| 386 LOG(ERROR) << "Handle table full"; | 386 LOG(ERROR) << "Handle table full"; |
| 387 producer_dispatcher->Close(); | 387 producer_dispatcher->Close(); |
| 388 consumer_dispatcher->Close(); | 388 consumer_dispatcher->Close(); |
| 389 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 389 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 390 } | 390 } |
| 391 DCHECK_NE(handle_pair.second, MOJO_HANDLE_INVALID); | 391 DCHECK_NE(handle_pair.second, MOJO_HANDLE_INVALID); |
| 392 | 392 |
| 393 scoped_refptr<DataPipe> data_pipe(DataPipe::CreateLocal(validated_options)); | 393 PlatformChannelPair channel_pair; |
| 394 producer_dispatcher->Init(data_pipe); | 394 producer_dispatcher->Init(channel_pair.PassServerHandle()); |
| 395 consumer_dispatcher->Init(data_pipe); | 395 consumer_dispatcher->Init(channel_pair.PassClientHandle()); |
| 396 | 396 |
| 397 data_pipe_producer_handle.Put(handle_pair.first); | 397 data_pipe_producer_handle.Put(handle_pair.first); |
| 398 data_pipe_consumer_handle.Put(handle_pair.second); | 398 data_pipe_consumer_handle.Put(handle_pair.second); |
| 399 return MOJO_RESULT_OK; | 399 return MOJO_RESULT_OK; |
| 400 } | 400 } |
| 401 | 401 |
| 402 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, | 402 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, |
| 403 UserPointer<const void> elements, | 403 UserPointer<const void> elements, |
| 404 UserPointer<uint32_t> num_bytes, | 404 UserPointer<uint32_t> num_bytes, |
| 405 MojoWriteDataFlags flags) { | 405 MojoWriteDataFlags flags) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 | 524 |
| 525 MojoResult Core::MapBuffer(MojoHandle buffer_handle, | 525 MojoResult Core::MapBuffer(MojoHandle buffer_handle, |
| 526 uint64_t offset, | 526 uint64_t offset, |
| 527 uint64_t num_bytes, | 527 uint64_t num_bytes, |
| 528 UserPointer<void*> buffer, | 528 UserPointer<void*> buffer, |
| 529 MojoMapBufferFlags flags) { | 529 MojoMapBufferFlags flags) { |
| 530 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 530 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
| 531 if (!dispatcher) | 531 if (!dispatcher) |
| 532 return MOJO_RESULT_INVALID_ARGUMENT; | 532 return MOJO_RESULT_INVALID_ARGUMENT; |
| 533 | 533 |
| 534 scoped_ptr<embedder::PlatformSharedBufferMapping> mapping; | 534 scoped_ptr<PlatformSharedBufferMapping> mapping; |
| 535 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); | 535 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); |
| 536 if (result != MOJO_RESULT_OK) | 536 if (result != MOJO_RESULT_OK) |
| 537 return result; | 537 return result; |
| 538 | 538 |
| 539 DCHECK(mapping); | 539 DCHECK(mapping); |
| 540 void* address = mapping->GetBase(); | 540 void* address = mapping->GetBase(); |
| 541 { | 541 { |
| 542 MutexLocker locker(&mapping_table_mutex_); | 542 base::AutoLock locker(mapping_table_lock_); |
| 543 result = mapping_table_.AddMapping(mapping.Pass()); | 543 result = mapping_table_.AddMapping(mapping.Pass()); |
| 544 } | 544 } |
| 545 if (result != MOJO_RESULT_OK) | 545 if (result != MOJO_RESULT_OK) |
| 546 return result; | 546 return result; |
| 547 | 547 |
| 548 buffer.Put(address); | 548 buffer.Put(address); |
| 549 return MOJO_RESULT_OK; | 549 return MOJO_RESULT_OK; |
| 550 } | 550 } |
| 551 | 551 |
| 552 MojoResult Core::UnmapBuffer(UserPointer<void> buffer) { | 552 MojoResult Core::UnmapBuffer(UserPointer<void> buffer) { |
| 553 MutexLocker locker(&mapping_table_mutex_); | 553 base::AutoLock locker(mapping_table_lock_); |
| 554 return mapping_table_.RemoveMapping(buffer.GetPointerValue()); | 554 return mapping_table_.RemoveMapping(buffer.GetPointerValue()); |
| 555 } | 555 } |
| 556 | 556 |
| 557 // Note: We allow |handles| to repeat the same handle multiple times, since | 557 // Note: We allow |handles| to repeat the same handle multiple times, since |
| 558 // different flags may be specified. | 558 // different flags may be specified. |
| 559 // TODO(vtl): This incurs a performance cost in |Remove()|. Analyze this | 559 // TODO(vtl): This incurs a performance cost in |Remove()|. Analyze this |
| 560 // more carefully and address it if necessary. | 560 // more carefully and address it if necessary. |
| 561 MojoResult Core::WaitManyInternal(const MojoHandle* handles, | 561 MojoResult Core::WaitManyInternal(const MojoHandle* handles, |
| 562 const MojoHandleSignals* signals, | 562 const MojoHandleSignals* signals, |
| 563 uint32_t num_handles, | 563 uint32_t num_handles, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 &waiter, signals_states ? &signals_states[i] : nullptr); | 607 &waiter, signals_states ? &signals_states[i] : nullptr); |
| 608 } | 608 } |
| 609 if (signals_states) { | 609 if (signals_states) { |
| 610 for (; i < num_handles; i++) | 610 for (; i < num_handles; i++) |
| 611 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); | 611 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); |
| 612 } | 612 } |
| 613 | 613 |
| 614 return rv; | 614 return rv; |
| 615 } | 615 } |
| 616 | 616 |
| 617 } // namespace system | 617 } // namespace edk |
| 618 } // namespace mojo | 618 } // namespace mojo |
| OLD | NEW |