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/proxy_message_pipe_endpoint.h" | 5 #include "mojo/system/proxy_message_pipe_endpoint.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
| 9 #include "base/containers/hash_tables.h" |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
11 #include "mojo/system/channel.h" | 12 #include "mojo/system/channel.h" |
| 13 #include "mojo/system/message_pipe_dispatcher.h" |
12 | 14 |
13 namespace mojo { | 15 namespace mojo { |
14 namespace system { | 16 namespace system { |
15 | 17 |
16 ProxyMessagePipeEndpoint::ProxyMessagePipeEndpoint() | 18 ProxyMessagePipeEndpoint::ProxyMessagePipeEndpoint() |
17 : local_id_(MessageInTransit::kInvalidEndpointId), | 19 : local_id_(MessageInTransit::kInvalidEndpointId), |
18 remote_id_(MessageInTransit::kInvalidEndpointId), | 20 remote_id_(MessageInTransit::kInvalidEndpointId), |
19 is_open_(true), | 21 is_open_(true), |
20 is_peer_open_(true) { | 22 is_peer_open_(true) { |
21 } | 23 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 MessageInTransit::kSubtypeMessagePipePeerClosed, | 58 MessageInTransit::kSubtypeMessagePipePeerClosed, |
57 NULL, 0); | 59 NULL, 0); |
58 EnqueueMessageInternal(message, NULL); | 60 EnqueueMessageInternal(message, NULL); |
59 } | 61 } |
60 | 62 |
61 MojoResult ProxyMessagePipeEndpoint::EnqueueMessage( | 63 MojoResult ProxyMessagePipeEndpoint::EnqueueMessage( |
62 MessageInTransit* message, | 64 MessageInTransit* message, |
63 const std::vector<Dispatcher*>* dispatchers) { | 65 const std::vector<Dispatcher*>* dispatchers) { |
64 DCHECK(!dispatchers || !dispatchers->empty()); | 66 DCHECK(!dispatchers || !dispatchers->empty()); |
65 | 67 |
66 MojoResult result = CanEnqueueDispatchers(dispatchers); | 68 // No need to preflight if there are no dispatchers. |
| 69 if (!dispatchers) { |
| 70 EnqueueMessageInternal(message, NULL); |
| 71 return MOJO_RESULT_OK; |
| 72 } |
| 73 |
| 74 std::vector<PreflightDispatcherInfo> preflight_dispatcher_infos; |
| 75 MojoResult result = PreflightDispatchers(dispatchers, |
| 76 &preflight_dispatcher_infos); |
67 if (result != MOJO_RESULT_OK) { | 77 if (result != MOJO_RESULT_OK) { |
68 message->Destroy(); | 78 message->Destroy(); |
69 return result; | 79 return result; |
70 } | 80 } |
71 | 81 |
72 EnqueueMessageInternal(message, dispatchers); | 82 EnqueueMessageInternal(message, dispatchers); |
73 return MOJO_RESULT_OK; | 83 return MOJO_RESULT_OK; |
74 } | 84 } |
75 | 85 |
76 void ProxyMessagePipeEndpoint::Attach(scoped_refptr<Channel> channel, | 86 void ProxyMessagePipeEndpoint::Attach(scoped_refptr<Channel> channel, |
(...skipping 21 matching lines...) Expand all Loading... |
98 remote_id_ = remote_id; | 108 remote_id_ = remote_id; |
99 AssertConsistentState(); | 109 AssertConsistentState(); |
100 | 110 |
101 for (std::deque<MessageInTransit*>::iterator it = | 111 for (std::deque<MessageInTransit*>::iterator it = |
102 paused_message_queue_.begin(); it != paused_message_queue_.end(); | 112 paused_message_queue_.begin(); it != paused_message_queue_.end(); |
103 ++it) | 113 ++it) |
104 EnqueueMessageInternal(*it, NULL); | 114 EnqueueMessageInternal(*it, NULL); |
105 paused_message_queue_.clear(); | 115 paused_message_queue_.clear(); |
106 } | 116 } |
107 | 117 |
108 MojoResult ProxyMessagePipeEndpoint::CanEnqueueDispatchers( | 118 MojoResult ProxyMessagePipeEndpoint::PreflightDispatchers( |
109 const std::vector<Dispatcher*>* dispatchers) { | 119 const std::vector<Dispatcher*>* dispatchers, |
| 120 std::vector<PreflightDispatcherInfo>* preflight_dispatcher_infos) { |
| 121 DCHECK(!dispatchers || !dispatchers->empty()); |
| 122 DCHECK(preflight_dispatcher_infos); |
| 123 DCHECK(preflight_dispatcher_infos->empty()); |
| 124 |
| 125 // Size it to fit everything. |
| 126 preflight_dispatcher_infos->resize(dispatchers->size()); |
| 127 |
| 128 // TODO(vtl): We'll begin with limited support for sending message pipe |
| 129 // handles. We won't support: |
| 130 // - sending both handles (the |hash_set| below is to detect this case and |
| 131 // fail gracefully); |
| 132 // - sending a handle whose peer is remote. |
| 133 base::hash_set<intptr_t> message_pipes; |
| 134 |
| 135 for (size_t i = 0; i < dispatchers->size(); i++) { |
| 136 Dispatcher* dispatcher = (*dispatchers)[i]; |
| 137 switch (dispatcher->GetType()) { |
| 138 case Dispatcher::kTypeUnknown: |
| 139 LOG(ERROR) << "Unknown dispatcher type"; |
| 140 return MOJO_RESULT_INTERNAL; |
| 141 |
| 142 case Dispatcher::kTypeMessagePipe: { |
| 143 MessagePipeDispatcher* mp_dispatcher = |
| 144 static_cast<MessagePipeDispatcher*>(dispatcher); |
| 145 (*preflight_dispatcher_infos)[i].message_pipe = |
| 146 mp_dispatcher->GetMessagePipeNoLock(); |
| 147 DCHECK((*preflight_dispatcher_infos)[i].message_pipe); |
| 148 (*preflight_dispatcher_infos)[i].port = mp_dispatcher->GetPortNoLock(); |
| 149 |
| 150 // Check for unsupported cases (see TODO above). |
| 151 bool is_new_element = message_pipes.insert(reinterpret_cast<intptr_t>( |
| 152 (*preflight_dispatcher_infos)[i].message_pipe)).second; |
| 153 if (!is_new_element) { |
| 154 NOTIMPLEMENTED() |
| 155 << "Sending both sides of a message pipe not yet supported"; |
| 156 return MOJO_RESULT_UNIMPLEMENTED; |
| 157 } |
| 158 // TODO(vtl): Check that peer isn't remote (per above TODO). |
| 159 |
| 160 break; |
| 161 } |
| 162 |
| 163 case Dispatcher::kTypeDataPipeProducer: |
| 164 NOTIMPLEMENTED() << "Sending data pipe producers not yet supported"; |
| 165 return MOJO_RESULT_UNIMPLEMENTED; |
| 166 |
| 167 case Dispatcher::kTypeDataPipeConsumer: |
| 168 NOTIMPLEMENTED() << "Sending data pipe consumers not yet supported"; |
| 169 return MOJO_RESULT_UNIMPLEMENTED; |
| 170 |
| 171 default: |
| 172 LOG(ERROR) << "Invalid or unsupported dispatcher type"; |
| 173 return MOJO_RESULT_UNIMPLEMENTED; |
| 174 } |
| 175 } |
| 176 |
110 // TODO(vtl): Support sending handles over OS pipes. | 177 // TODO(vtl): Support sending handles over OS pipes. |
111 if (dispatchers) { | 178 NOTIMPLEMENTED(); |
112 NOTIMPLEMENTED(); | 179 return MOJO_RESULT_UNIMPLEMENTED; |
113 return MOJO_RESULT_UNIMPLEMENTED; | |
114 } | |
115 return MOJO_RESULT_OK; | |
116 } | 180 } |
117 | 181 |
118 // Note: We may have to enqueue messages even when our (local) peer isn't open | 182 // Note: We may have to enqueue messages even when our (local) peer isn't open |
119 // -- it may have been written to and closed immediately, before we were ready. | 183 // -- it may have been written to and closed immediately, before we were ready. |
120 // This case is handled in |Run()| (which will call us). | 184 // This case is handled in |Run()| (which will call us). |
121 void ProxyMessagePipeEndpoint::EnqueueMessageInternal( | 185 void ProxyMessagePipeEndpoint::EnqueueMessageInternal( |
122 MessageInTransit* message, | 186 MessageInTransit* message, |
123 const std::vector<Dispatcher*>* dispatchers) { | 187 const std::vector<Dispatcher*>* dispatchers) { |
124 DCHECK(is_open_); | 188 DCHECK(is_open_); |
125 | 189 |
(...skipping 21 matching lines...) Expand all Loading... |
147 DCHECK_NE(local_id_, MessageInTransit::kInvalidEndpointId); | 211 DCHECK_NE(local_id_, MessageInTransit::kInvalidEndpointId); |
148 } else { // Not attached. | 212 } else { // Not attached. |
149 DCHECK_EQ(local_id_, MessageInTransit::kInvalidEndpointId); | 213 DCHECK_EQ(local_id_, MessageInTransit::kInvalidEndpointId); |
150 DCHECK_EQ(remote_id_, MessageInTransit::kInvalidEndpointId); | 214 DCHECK_EQ(remote_id_, MessageInTransit::kInvalidEndpointId); |
151 } | 215 } |
152 } | 216 } |
153 #endif | 217 #endif |
154 | 218 |
155 } // namespace system | 219 } // namespace system |
156 } // namespace mojo | 220 } // namespace mojo |
OLD | NEW |