Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: mojo/edk/system/core.cc

Issue 1350023003: Add a Mojo EDK for Chrome that uses one OS pipe per message pipe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move to mojo::edk namespace in preparation for runtim flag Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698