| 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/message_pipe_dispatcher.h" | 5 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "mojo/edk/system/channel.h" | 8 #include "mojo/edk/system/configuration.h" |
| 9 #include "mojo/edk/system/channel_endpoint.h" | |
| 10 #include "mojo/edk/system/channel_endpoint_id.h" | |
| 11 #include "mojo/edk/system/constants.h" | |
| 12 #include "mojo/edk/system/local_message_pipe_endpoint.h" | 9 #include "mojo/edk/system/local_message_pipe_endpoint.h" |
| 13 #include "mojo/edk/system/memory.h" | 10 #include "mojo/edk/system/memory.h" |
| 14 #include "mojo/edk/system/message_pipe.h" | 11 #include "mojo/edk/system/message_pipe.h" |
| 15 #include "mojo/edk/system/options_validation.h" | 12 #include "mojo/edk/system/options_validation.h" |
| 16 #include "mojo/edk/system/proxy_message_pipe_endpoint.h" | 13 #include "mojo/edk/system/proxy_message_pipe_endpoint.h" |
| 17 | 14 |
| 18 namespace mojo { | 15 namespace mojo { |
| 19 namespace system { | 16 namespace system { |
| 20 | 17 |
| 21 namespace { | |
| 22 | |
| 23 const unsigned kInvalidPort = static_cast<unsigned>(-1); | 18 const unsigned kInvalidPort = static_cast<unsigned>(-1); |
| 24 | 19 |
| 25 struct SerializedMessagePipeDispatcher { | |
| 26 // This is the endpoint ID on the receiving side, and should be a "remote ID". | |
| 27 // (The receiving side should have already have an endpoint attached and run | |
| 28 // via the |Channel|s. This endpoint will have both IDs assigned, so this ID | |
| 29 // is only needed to associated that endpoint with a particular dispatcher.) | |
| 30 ChannelEndpointId receiver_endpoint_id; | |
| 31 }; | |
| 32 | |
| 33 } // namespace | |
| 34 | |
| 35 // MessagePipeDispatcher ------------------------------------------------------- | 20 // MessagePipeDispatcher ------------------------------------------------------- |
| 36 | 21 |
| 37 // static | 22 // static |
| 38 const MojoCreateMessagePipeOptions | 23 const MojoCreateMessagePipeOptions |
| 39 MessagePipeDispatcher::kDefaultCreateOptions = { | 24 MessagePipeDispatcher::kDefaultCreateOptions = { |
| 40 static_cast<uint32_t>(sizeof(MojoCreateMessagePipeOptions)), | 25 static_cast<uint32_t>(sizeof(MojoCreateMessagePipeOptions)), |
| 41 MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE}; | 26 MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE}; |
| 42 | 27 |
| 43 MessagePipeDispatcher::MessagePipeDispatcher( | 28 MessagePipeDispatcher::MessagePipeDispatcher( |
| 44 const MojoCreateMessagePipeOptions& /*validated_options*/) | 29 const MojoCreateMessagePipeOptions& /*validated_options*/) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); | 81 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); |
| 97 dispatcher->Init(message_pipe, 0); | 82 dispatcher->Init(message_pipe, 0); |
| 98 return dispatcher; | 83 return dispatcher; |
| 99 } | 84 } |
| 100 | 85 |
| 101 // static | 86 // static |
| 102 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( | 87 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( |
| 103 Channel* channel, | 88 Channel* channel, |
| 104 const void* source, | 89 const void* source, |
| 105 size_t size) { | 90 size_t size) { |
| 106 if (size != sizeof(SerializedMessagePipeDispatcher)) { | 91 unsigned port = kInvalidPort; |
| 107 LOG(ERROR) << "Invalid serialized message pipe dispatcher"; | 92 scoped_refptr<MessagePipe> message_pipe; |
| 108 return scoped_refptr<MessagePipeDispatcher>(); | 93 if (!MessagePipe::Deserialize(channel, source, size, &message_pipe, &port)) |
| 109 } | 94 return nullptr; |
| 95 DCHECK(message_pipe.get()); |
| 96 DCHECK(port == 0 || port == 1); |
| 110 | 97 |
| 111 const SerializedMessagePipeDispatcher* s = | |
| 112 static_cast<const SerializedMessagePipeDispatcher*>(source); | |
| 113 scoped_refptr<MessagePipe> message_pipe = | |
| 114 channel->PassIncomingMessagePipe(s->receiver_endpoint_id); | |
| 115 if (!message_pipe.get()) { | |
| 116 LOG(ERROR) << "Failed to deserialize message pipe dispatcher (ID = " | |
| 117 << s->receiver_endpoint_id << ")"; | |
| 118 return scoped_refptr<MessagePipeDispatcher>(); | |
| 119 } | |
| 120 | |
| 121 DVLOG(2) << "Deserializing message pipe dispatcher (new local ID = " | |
| 122 << s->receiver_endpoint_id << ")"; | |
| 123 scoped_refptr<MessagePipeDispatcher> dispatcher( | 98 scoped_refptr<MessagePipeDispatcher> dispatcher( |
| 124 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); | 99 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); |
| 125 dispatcher->Init(message_pipe, 0); | 100 dispatcher->Init(message_pipe, port); |
| 126 return dispatcher; | 101 return dispatcher; |
| 127 } | 102 } |
| 128 | 103 |
| 129 MessagePipeDispatcher::~MessagePipeDispatcher() { | 104 MessagePipeDispatcher::~MessagePipeDispatcher() { |
| 130 // |Close()|/|CloseImplNoLock()| should have taken care of the pipe. | 105 // |Close()|/|CloseImplNoLock()| should have taken care of the pipe. |
| 131 DCHECK(!message_pipe_.get()); | 106 DCHECK(!message_pipe_.get()); |
| 132 } | 107 } |
| 133 | 108 |
| 134 MessagePipe* MessagePipeDispatcher::GetMessagePipeNoLock() const { | 109 MessagePipe* MessagePipeDispatcher::GetMessagePipeNoLock() const { |
| 135 lock().AssertAcquired(); | 110 lock().AssertAcquired(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 166 message_pipe_ = nullptr; | 141 message_pipe_ = nullptr; |
| 167 port_ = kInvalidPort; | 142 port_ = kInvalidPort; |
| 168 return scoped_refptr<Dispatcher>(rv.get()); | 143 return scoped_refptr<Dispatcher>(rv.get()); |
| 169 } | 144 } |
| 170 | 145 |
| 171 MojoResult MessagePipeDispatcher::WriteMessageImplNoLock( | 146 MojoResult MessagePipeDispatcher::WriteMessageImplNoLock( |
| 172 UserPointer<const void> bytes, | 147 UserPointer<const void> bytes, |
| 173 uint32_t num_bytes, | 148 uint32_t num_bytes, |
| 174 std::vector<DispatcherTransport>* transports, | 149 std::vector<DispatcherTransport>* transports, |
| 175 MojoWriteMessageFlags flags) { | 150 MojoWriteMessageFlags flags) { |
| 176 DCHECK(!transports || (transports->size() > 0 && | 151 DCHECK(!transports || |
| 177 transports->size() <= kMaxMessageNumHandles)); | 152 (transports->size() > 0 && |
| 153 transports->size() <= GetConfiguration().max_message_num_handles)); |
| 178 | 154 |
| 179 lock().AssertAcquired(); | 155 lock().AssertAcquired(); |
| 180 | 156 |
| 181 if (num_bytes > kMaxMessageNumBytes) | 157 if (num_bytes > GetConfiguration().max_message_num_bytes) |
| 182 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 158 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 183 | 159 |
| 184 return message_pipe_->WriteMessage( | 160 return message_pipe_->WriteMessage(port_, bytes, num_bytes, transports, |
| 185 port_, bytes, num_bytes, transports, flags); | 161 flags); |
| 186 } | 162 } |
| 187 | 163 |
| 188 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock( | 164 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock( |
| 189 UserPointer<void> bytes, | 165 UserPointer<void> bytes, |
| 190 UserPointer<uint32_t> num_bytes, | 166 UserPointer<uint32_t> num_bytes, |
| 191 DispatcherVector* dispatchers, | 167 DispatcherVector* dispatchers, |
| 192 uint32_t* num_dispatchers, | 168 uint32_t* num_dispatchers, |
| 193 MojoReadMessageFlags flags) { | 169 MojoReadMessageFlags flags) { |
| 194 lock().AssertAcquired(); | 170 lock().AssertAcquired(); |
| 195 return message_pipe_->ReadMessage( | 171 return message_pipe_->ReadMessage(port_, bytes, num_bytes, dispatchers, |
| 196 port_, bytes, num_bytes, dispatchers, num_dispatchers, flags); | 172 num_dispatchers, flags); |
| 197 } | 173 } |
| 198 | 174 |
| 199 HandleSignalsState MessagePipeDispatcher::GetHandleSignalsStateImplNoLock() | 175 HandleSignalsState MessagePipeDispatcher::GetHandleSignalsStateImplNoLock() |
| 200 const { | 176 const { |
| 201 lock().AssertAcquired(); | 177 lock().AssertAcquired(); |
| 202 return message_pipe_->GetHandleSignalsState(port_); | 178 return message_pipe_->GetHandleSignalsState(port_); |
| 203 } | 179 } |
| 204 | 180 |
| 205 MojoResult MessagePipeDispatcher::AddWaiterImplNoLock( | 181 MojoResult MessagePipeDispatcher::AddWaiterImplNoLock( |
| 206 Waiter* waiter, | 182 Waiter* waiter, |
| 207 MojoHandleSignals signals, | 183 MojoHandleSignals signals, |
| 208 uint32_t context, | 184 uint32_t context, |
| 209 HandleSignalsState* signals_state) { | 185 HandleSignalsState* signals_state) { |
| 210 lock().AssertAcquired(); | 186 lock().AssertAcquired(); |
| 211 return message_pipe_->AddWaiter( | 187 return message_pipe_->AddWaiter(port_, waiter, signals, context, |
| 212 port_, waiter, signals, context, signals_state); | 188 signals_state); |
| 213 } | 189 } |
| 214 | 190 |
| 215 void MessagePipeDispatcher::RemoveWaiterImplNoLock( | 191 void MessagePipeDispatcher::RemoveWaiterImplNoLock( |
| 216 Waiter* waiter, | 192 Waiter* waiter, |
| 217 HandleSignalsState* signals_state) { | 193 HandleSignalsState* signals_state) { |
| 218 lock().AssertAcquired(); | 194 lock().AssertAcquired(); |
| 219 message_pipe_->RemoveWaiter(port_, waiter, signals_state); | 195 message_pipe_->RemoveWaiter(port_, waiter, signals_state); |
| 220 } | 196 } |
| 221 | 197 |
| 222 void MessagePipeDispatcher::StartSerializeImplNoLock( | 198 void MessagePipeDispatcher::StartSerializeImplNoLock( |
| 223 Channel* /*channel*/, | 199 Channel* channel, |
| 224 size_t* max_size, | 200 size_t* max_size, |
| 225 size_t* max_platform_handles) { | 201 size_t* max_platform_handles) { |
| 226 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 202 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
| 227 *max_size = sizeof(SerializedMessagePipeDispatcher); | 203 return message_pipe_->StartSerialize(port_, channel, max_size, |
| 228 *max_platform_handles = 0; | 204 max_platform_handles); |
| 229 } | 205 } |
| 230 | 206 |
| 231 bool MessagePipeDispatcher::EndSerializeAndCloseImplNoLock( | 207 bool MessagePipeDispatcher::EndSerializeAndCloseImplNoLock( |
| 232 Channel* channel, | 208 Channel* channel, |
| 233 void* destination, | 209 void* destination, |
| 234 size_t* actual_size, | 210 size_t* actual_size, |
| 235 embedder::PlatformHandleVector* /*platform_handles*/) { | 211 embedder::PlatformHandleVector* platform_handles) { |
| 236 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 212 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
| 237 | 213 |
| 238 SerializedMessagePipeDispatcher* s = | 214 bool rv = message_pipe_->EndSerialize(port_, channel, destination, |
| 239 static_cast<SerializedMessagePipeDispatcher*>(destination); | 215 actual_size, platform_handles); |
| 240 | |
| 241 // Convert the local endpoint to a proxy endpoint (moving the message queue) | |
| 242 // and attach it to the channel. | |
| 243 s->receiver_endpoint_id = channel->AttachAndRunEndpoint( | |
| 244 message_pipe_->ConvertLocalToProxy(port_), false); | |
| 245 DVLOG(2) << "Serializing message pipe dispatcher (remote ID = " | |
| 246 << s->receiver_endpoint_id << ")"; | |
| 247 | |
| 248 message_pipe_ = nullptr; | 216 message_pipe_ = nullptr; |
| 249 port_ = kInvalidPort; | 217 port_ = kInvalidPort; |
| 250 | 218 return rv; |
| 251 *actual_size = sizeof(SerializedMessagePipeDispatcher); | |
| 252 return true; | |
| 253 } | 219 } |
| 254 | 220 |
| 255 // MessagePipeDispatcherTransport ---------------------------------------------- | 221 // MessagePipeDispatcherTransport ---------------------------------------------- |
| 256 | 222 |
| 257 MessagePipeDispatcherTransport::MessagePipeDispatcherTransport( | 223 MessagePipeDispatcherTransport::MessagePipeDispatcherTransport( |
| 258 DispatcherTransport transport) | 224 DispatcherTransport transport) |
| 259 : DispatcherTransport(transport) { | 225 : DispatcherTransport(transport) { |
| 260 DCHECK_EQ(message_pipe_dispatcher()->GetType(), Dispatcher::kTypeMessagePipe); | 226 DCHECK_EQ(message_pipe_dispatcher()->GetType(), Dispatcher::kTypeMessagePipe); |
| 261 } | 227 } |
| 262 | 228 |
| 263 } // namespace system | 229 } // namespace system |
| 264 } // namespace mojo | 230 } // namespace mojo |
| OLD | NEW |