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

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

Issue 1223813007: Convert core.{h,cc} to use mojo::system::Mutex (and MutexLocker). (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 5 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
« no previous file with comments | « mojo/edk/system/core.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(embedder::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 base::AutoLock locker(handle_table_lock_); 89 MutexLocker locker(&handle_table_mutex_);
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 base::AutoLock locker(handle_table_lock_); 97 MutexLocker locker(&handle_table_mutex_);
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 base::AutoLock locker(handle_table_lock_); 106 MutexLocker locker(&handle_table_mutex_);
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 base::AutoLock locker(handle_table_lock_); 133 MutexLocker locker(&handle_table_mutex_);
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_lock_|. As a result, there's a 141 // Note: This is done outside of |handle_table_mutex_|. 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 base::AutoLock locker(handle_table_lock_); 214 MutexLocker locker(&handle_table_mutex_);
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
(...skipping 44 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 base::AutoLock locker(handle_table_lock_); 279 MutexLocker locker(&handle_table_mutex_);
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 base::AutoLock locker(handle_table_lock_); 296 MutexLocker locker(&handle_table_mutex_);
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 base::AutoLock locker(handle_table_lock_); 338 MutexLocker locker(&handle_table_mutex_);
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 21 matching lines...) Expand all
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();
375 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher = 375 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher =
376 DataPipeConsumerDispatcher::Create(); 376 DataPipeConsumerDispatcher::Create();
377 377
378 std::pair<MojoHandle, MojoHandle> handle_pair; 378 std::pair<MojoHandle, MojoHandle> handle_pair;
379 { 379 {
380 base::AutoLock locker(handle_table_lock_); 380 MutexLocker locker(&handle_table_mutex_);
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 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 return MOJO_RESULT_INVALID_ARGUMENT; 532 return MOJO_RESULT_INVALID_ARGUMENT;
533 533
534 scoped_ptr<embedder::PlatformSharedBufferMapping> mapping; 534 scoped_ptr<embedder::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 base::AutoLock locker(mapping_table_lock_); 542 MutexLocker locker(&mapping_table_mutex_);
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 base::AutoLock locker(mapping_table_lock_); 553 MutexLocker locker(&mapping_table_mutex_);
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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 system
618 } // namespace mojo 618 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/core.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698