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 <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 using mojo::platform::PlatformSharedBufferMapping; | 32 using mojo::platform::PlatformSharedBufferMapping; |
33 using mojo::util::MutexLocker; | 33 using mojo::util::MutexLocker; |
34 using mojo::util::RefPtr; | 34 using mojo::util::RefPtr; |
35 | 35 |
36 namespace mojo { | 36 namespace mojo { |
37 namespace system { | 37 namespace system { |
38 | 38 |
39 // Implementation notes | 39 // Implementation notes |
40 // | 40 // |
41 // Mojo primitives are implemented by the singleton |Core| object. Most calls | 41 // Mojo primitives are implemented by the singleton |Core| object. Most calls |
42 // are for a "primary" handle (the first argument). |Core::GetDispatcher()| is | 42 // are for a "primary" handle (the first argument). |Core::GetHandle()| is used |
43 // used to look up a |Dispatcher| object for a given handle. That object | 43 // to look up a |Handle| (in particular, a |Dispatcher| object) for a given |
44 // implements most primitives for that object. The wait primitives are not | 44 // handle value. The |Dispatcher| object implements most primitives for that |
45 // attached to objects and are implemented by |Core| itself. | 45 // (conceptual/logical) object. The wait primitives are not attached to objects |
| 46 // and are implemented by |Core| itself. |
46 // | 47 // |
47 // Some objects have multiple handles associated to them, e.g., message pipes | 48 // Some objects have multiple handles associated to them, e.g., message pipes |
48 // (which have two). In such a case, there is still a |Dispatcher| (e.g., | 49 // (which have two). In such a case, there is still a |Dispatcher| (e.g., |
49 // |MessagePipeDispatcher|) for each handle, with each handle having a strong | 50 // |MessagePipeDispatcher|) for each handle, with each handle having a strong |
50 // reference to the common "secondary" object (e.g., |MessagePipe|). This | 51 // reference to the common "secondary" object (e.g., |MessagePipe|). This |
51 // secondary object does NOT have any references to the |Dispatcher|s (even if | 52 // secondary object does NOT have any references to the |Dispatcher|s (even if |
52 // it did, it wouldn't be able to do anything with them due to lock order | 53 // it did, it wouldn't be able to do anything with them due to lock order |
53 // requirements -- see below). | 54 // requirements -- see below). |
54 // | 55 // |
55 // Waiting is implemented by having the thread that wants to wait call the | 56 // Waiting is implemented by having the thread that wants to wait call the |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 handle_table_(GetConfiguration().max_handle_table_size) {} | 91 handle_table_(GetConfiguration().max_handle_table_size) {} |
91 | 92 |
92 Core::~Core() { | 93 Core::~Core() { |
93 } | 94 } |
94 | 95 |
95 MojoHandle Core::AddHandle(Handle&& handle) { | 96 MojoHandle Core::AddHandle(Handle&& handle) { |
96 MutexLocker locker(&handle_table_mutex_); | 97 MutexLocker locker(&handle_table_mutex_); |
97 return handle_table_.AddHandle(std::move(handle)); | 98 return handle_table_.AddHandle(std::move(handle)); |
98 } | 99 } |
99 | 100 |
100 MojoResult Core::GetDispatcher(MojoHandle handle, | 101 MojoResult Core::GetDispatcher(MojoHandle handle_value, |
101 RefPtr<Dispatcher>* dispatcher) { | 102 RefPtr<Dispatcher>* dispatcher) { |
102 if (handle == MOJO_HANDLE_INVALID) | 103 if (handle_value == MOJO_HANDLE_INVALID) |
103 return MOJO_RESULT_INVALID_ARGUMENT; | 104 return MOJO_RESULT_INVALID_ARGUMENT; |
104 | 105 |
105 MutexLocker locker(&handle_table_mutex_); | 106 MutexLocker locker(&handle_table_mutex_); |
106 return handle_table_.GetDispatcher(handle, dispatcher); | 107 Handle handle; |
| 108 MojoResult rv = handle_table_.GetHandle(handle_value, &handle); |
| 109 if (rv == MOJO_RESULT_OK) |
| 110 *dispatcher = std::move(handle.dispatcher); |
| 111 return rv; |
107 } | 112 } |
108 | 113 |
109 MojoResult Core::GetAndRemoveDispatcher(MojoHandle handle, | 114 MojoResult Core::GetAndRemoveDispatcher(MojoHandle handle_value, |
110 RefPtr<Dispatcher>* dispatcher) { | 115 RefPtr<Dispatcher>* dispatcher) { |
111 if (handle == MOJO_HANDLE_INVALID) | 116 if (handle_value == MOJO_HANDLE_INVALID) |
112 return MOJO_RESULT_INVALID_ARGUMENT; | 117 return MOJO_RESULT_INVALID_ARGUMENT; |
113 | 118 |
114 MutexLocker locker(&handle_table_mutex_); | 119 MutexLocker locker(&handle_table_mutex_); |
115 return handle_table_.GetAndRemoveDispatcher(handle, dispatcher); | 120 return handle_table_.GetAndRemoveDispatcher(handle_value, dispatcher); |
116 } | 121 } |
117 | 122 |
118 MojoResult Core::AsyncWait(MojoHandle handle, | 123 MojoResult Core::AsyncWait(MojoHandle handle, |
119 MojoHandleSignals signals, | 124 MojoHandleSignals signals, |
120 const std::function<void(MojoResult)>& callback) { | 125 const std::function<void(MojoResult)>& callback) { |
121 RefPtr<Dispatcher> dispatcher; | 126 RefPtr<Dispatcher> dispatcher; |
122 MojoResult result = GetDispatcher(handle, &dispatcher); | 127 MojoResult result = GetDispatcher(handle, &dispatcher); |
123 if (result != MOJO_RESULT_OK) | 128 if (result != MOJO_RESULT_OK) |
124 return result; | 129 return result; |
125 | 130 |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 dispatchers.reserve(num_handles); | 649 dispatchers.reserve(num_handles); |
645 | 650 |
646 { | 651 { |
647 MutexLocker locker(&handle_table_mutex_); | 652 MutexLocker locker(&handle_table_mutex_); |
648 for (uint32_t i = 0; i < num_handles; i++) { | 653 for (uint32_t i = 0; i < num_handles; i++) { |
649 if (handles[i] == MOJO_HANDLE_INVALID) { | 654 if (handles[i] == MOJO_HANDLE_INVALID) { |
650 *result_index = i; | 655 *result_index = i; |
651 return MOJO_RESULT_INVALID_ARGUMENT; | 656 return MOJO_RESULT_INVALID_ARGUMENT; |
652 } | 657 } |
653 | 658 |
654 RefPtr<Dispatcher> dispatcher; | 659 Handle handle; |
655 MojoResult result = handle_table_.GetDispatcher(handles[i], &dispatcher); | 660 MojoResult result = handle_table_.GetHandle(handles[i], &handle); |
656 if (result != MOJO_RESULT_OK) { | 661 if (result != MOJO_RESULT_OK) { |
657 *result_index = i; | 662 *result_index = i; |
658 return result; | 663 return result; |
659 } | 664 } |
660 dispatchers.push_back(std::move(dispatcher)); | 665 dispatchers.push_back(std::move(handle.dispatcher)); |
661 } | 666 } |
662 } | 667 } |
663 | 668 |
664 // TODO(vtl): Should make the waiter live (permanently) in TLS. | 669 // TODO(vtl): Should make the waiter live (permanently) in TLS. |
665 Waiter waiter; | 670 Waiter waiter; |
666 waiter.Init(); | 671 waiter.Init(); |
667 | 672 |
668 uint32_t i; | 673 uint32_t i; |
669 MojoResult result = MOJO_RESULT_OK; | 674 MojoResult result = MOJO_RESULT_OK; |
670 for (i = 0; i < num_handles; i++) { | 675 for (i = 0; i < num_handles; i++) { |
(...skipping 21 matching lines...) Expand all Loading... |
692 if (signals_states) { | 697 if (signals_states) { |
693 for (; i < num_handles; i++) | 698 for (; i < num_handles; i++) |
694 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); | 699 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); |
695 } | 700 } |
696 | 701 |
697 return result; | 702 return result; |
698 } | 703 } |
699 | 704 |
700 } // namespace system | 705 } // namespace system |
701 } // namespace mojo | 706 } // namespace mojo |
OLD | NEW |