| 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_impl.h" | 5 #include "mojo/system/core_impl.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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 | 52 |
| 53 // Thread-safety notes | 53 // Thread-safety notes |
| 54 // | 54 // |
| 55 // Mojo primitives calls are thread-safe. We achieve this with relatively | 55 // Mojo primitives calls are thread-safe. We achieve this with relatively |
| 56 // fine-grained locking. There is a global handle table lock. This lock should | 56 // fine-grained locking. There is a global handle table lock. This lock should |
| 57 // be held as briefly as possible (TODO(vtl): a future improvement would be to | 57 // be held as briefly as possible (TODO(vtl): a future improvement would be to |
| 58 // switch it to a reader-writer lock). Each |Dispatcher| object then has a lock | 58 // switch it to a reader-writer lock). Each |Dispatcher| object then has a lock |
| 59 // (which subclasses can use to protect their data). | 59 // (which subclasses can use to protect their data). |
| 60 // | 60 // |
| 61 // The lock ordering is as follows: | 61 // The lock ordering is as follows: |
| 62 // 1. global handle table lock | 62 // 1. global handle table lock, global mapping table lock |
| 63 // 2. |Dispatcher| locks | 63 // 2. |Dispatcher| locks |
| 64 // 3. secondary object locks | 64 // 3. secondary object locks |
| 65 // ... | 65 // ... |
| 66 // INF. |Waiter| locks | 66 // INF. |Waiter| locks |
| 67 // | 67 // |
| 68 // Notes: | 68 // Notes: |
| 69 // - While holding a |Dispatcher| lock, you may not unconditionally attempt | 69 // - While holding a |Dispatcher| lock, you may not unconditionally attempt |
| 70 // to take another |Dispatcher| lock. (This has consequences on the | 70 // to take another |Dispatcher| lock. (This has consequences on the |
| 71 // concurrency semantics of |MojoWriteMessage()| when passing handles.) | 71 // concurrency semantics of |MojoWriteMessage()| when passing handles.) |
| 72 // Doing so would lead to deadlock. | 72 // Doing so would lead to deadlock. |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 | 496 |
| 497 if (!VerifyUserPointer<void*>(buffer, 1)) | 497 if (!VerifyUserPointer<void*>(buffer, 1)) |
| 498 return MOJO_RESULT_INVALID_ARGUMENT; | 498 return MOJO_RESULT_INVALID_ARGUMENT; |
| 499 | 499 |
| 500 scoped_ptr<RawSharedBufferMapping> mapping; | 500 scoped_ptr<RawSharedBufferMapping> mapping; |
| 501 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); | 501 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); |
| 502 if (result != MOJO_RESULT_OK) | 502 if (result != MOJO_RESULT_OK) |
| 503 return result; | 503 return result; |
| 504 | 504 |
| 505 DCHECK(mapping); | 505 DCHECK(mapping); |
| 506 *buffer = mapping->base(); | 506 void* address = mapping->base(); |
| 507 { |
| 508 base::AutoLock locker(mapping_table_lock_); |
| 509 result = mapping_table_.AddMapping(mapping.Pass()); |
| 510 } |
| 511 if (result != MOJO_RESULT_OK) |
| 512 return result; |
| 507 | 513 |
| 508 // TODO(vtl): FIXME -- Record the mapping somewhere, so that it can be | 514 *buffer = address; |
| 509 // unmapped properly. For now, just leak it. | |
| 510 ignore_result(mapping.release()); | |
| 511 | |
| 512 return MOJO_RESULT_OK; | 515 return MOJO_RESULT_OK; |
| 513 } | 516 } |
| 514 | 517 |
| 515 MojoResult CoreImpl::UnmapBuffer(void* buffer) { | 518 MojoResult CoreImpl::UnmapBuffer(void* buffer) { |
| 516 // TODO(vtl): FIXME | 519 base::AutoLock locker(mapping_table_lock_); |
| 517 NOTIMPLEMENTED(); | 520 return mapping_table_.RemoveMapping(buffer); |
| 518 return MOJO_RESULT_UNIMPLEMENTED; | |
| 519 } | 521 } |
| 520 | 522 |
| 521 scoped_refptr<Dispatcher> CoreImpl::GetDispatcher(MojoHandle handle) { | 523 scoped_refptr<Dispatcher> CoreImpl::GetDispatcher(MojoHandle handle) { |
| 522 if (handle == MOJO_HANDLE_INVALID) | 524 if (handle == MOJO_HANDLE_INVALID) |
| 523 return NULL; | 525 return NULL; |
| 524 | 526 |
| 525 base::AutoLock locker(handle_table_lock_); | 527 base::AutoLock locker(handle_table_lock_); |
| 526 return handle_table_.GetDispatcher(handle); | 528 return handle_table_.GetDispatcher(handle); |
| 527 } | 529 } |
| 528 | 530 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be | 571 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be |
| 570 // destroyed, but this would still be required if the waiter were in TLS.) | 572 // destroyed, but this would still be required if the waiter were in TLS.) |
| 571 for (i = 0; i < num_added; i++) | 573 for (i = 0; i < num_added; i++) |
| 572 dispatchers[i]->RemoveWaiter(&waiter); | 574 dispatchers[i]->RemoveWaiter(&waiter); |
| 573 | 575 |
| 574 return rv; | 576 return rv; |
| 575 } | 577 } |
| 576 | 578 |
| 577 } // namespace system | 579 } // namespace system |
| 578 } // namespace mojo | 580 } // namespace mojo |
| OLD | NEW |