| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "ipc/mojo/ipc_channel_mojo.h" | 5 #include "ipc/mojo/ipc_channel_mojo.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "ipc/ipc_listener.h" | 10 #include "ipc/ipc_listener.h" |
| 11 #include "ipc/mojo/ipc_channel_mojo_readers.h" |
| 11 #include "mojo/embedder/embedder.h" | 12 #include "mojo/embedder/embedder.h" |
| 12 | 13 |
| 13 #if defined(OS_POSIX) && !defined(OS_NACL) | 14 #if defined(OS_POSIX) && !defined(OS_NACL) |
| 14 #include "ipc/file_descriptor_set_posix.h" | 15 #include "ipc/file_descriptor_set_posix.h" |
| 15 #endif | 16 #endif |
| 16 | 17 |
| 17 namespace IPC { | 18 namespace IPC { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 const ChannelHandle& handle) { | 76 const ChannelHandle& handle) { |
| 76 #if defined(OS_POSIX) && !defined(OS_NACL) | 77 #if defined(OS_POSIX) && !defined(OS_NACL) |
| 77 return mojo::embedder::PlatformHandle(handle.socket.fd); | 78 return mojo::embedder::PlatformHandle(handle.socket.fd); |
| 78 #elif defined(OS_WIN) | 79 #elif defined(OS_WIN) |
| 79 return mojo::embedder::PlatformHandle(handle.pipe.handle); | 80 return mojo::embedder::PlatformHandle(handle.pipe.handle); |
| 80 #else | 81 #else |
| 81 #error "Unsupported Platform!" | 82 #error "Unsupported Platform!" |
| 82 #endif | 83 #endif |
| 83 } | 84 } |
| 84 | 85 |
| 85 //------------------------------------------------------------------------------ | |
| 86 | |
| 87 // TODO(morrita): This should be built using higher-level Mojo construct | |
| 88 // for clarity and extensibility. | |
| 89 class HelloMessage { | |
| 90 public: | |
| 91 static Pickle CreateRequest(int32 pid) { | |
| 92 Pickle request; | |
| 93 request.WriteString(kHelloRequestMagic); | |
| 94 request.WriteInt(pid); | |
| 95 return request; | |
| 96 } | |
| 97 | |
| 98 static bool ReadRequest(Pickle& pickle, int32* pid) { | |
| 99 PickleIterator iter(pickle); | |
| 100 std::string hello; | |
| 101 if (!iter.ReadString(&hello)) { | |
| 102 DLOG(WARNING) << "Failed to Read magic string."; | |
| 103 return false; | |
| 104 } | |
| 105 | |
| 106 if (hello != kHelloRequestMagic) { | |
| 107 DLOG(WARNING) << "Magic mismatch:" << hello; | |
| 108 return false; | |
| 109 } | |
| 110 | |
| 111 int read_pid; | |
| 112 if (!iter.ReadInt(&read_pid)) { | |
| 113 DLOG(WARNING) << "Failed to Read PID."; | |
| 114 return false; | |
| 115 } | |
| 116 | |
| 117 *pid = read_pid; | |
| 118 return true; | |
| 119 } | |
| 120 | |
| 121 static Pickle CreateResponse(int32 pid) { | |
| 122 Pickle request; | |
| 123 request.WriteString(kHelloResponseMagic); | |
| 124 request.WriteInt(pid); | |
| 125 return request; | |
| 126 } | |
| 127 | |
| 128 static bool ReadResponse(Pickle& pickle, int32* pid) { | |
| 129 PickleIterator iter(pickle); | |
| 130 std::string hello; | |
| 131 if (!iter.ReadString(&hello)) { | |
| 132 DLOG(WARNING) << "Failed to read magic string."; | |
| 133 return false; | |
| 134 } | |
| 135 | |
| 136 if (hello != kHelloResponseMagic) { | |
| 137 DLOG(WARNING) << "Magic mismatch:" << hello; | |
| 138 return false; | |
| 139 } | |
| 140 | |
| 141 int read_pid; | |
| 142 if (!iter.ReadInt(&read_pid)) { | |
| 143 DLOG(WARNING) << "Failed to read PID."; | |
| 144 return false; | |
| 145 } | |
| 146 | |
| 147 *pid = read_pid; | |
| 148 return true; | |
| 149 } | |
| 150 | |
| 151 private: | |
| 152 static const char* kHelloRequestMagic; | |
| 153 static const char* kHelloResponseMagic; | |
| 154 }; | |
| 155 | |
| 156 const char* HelloMessage::kHelloRequestMagic = "MREQ"; | |
| 157 const char* HelloMessage::kHelloResponseMagic = "MRES"; | |
| 158 | |
| 159 } // namespace | 86 } // namespace |
| 160 | 87 |
| 161 //------------------------------------------------------------------------------ | 88 //------------------------------------------------------------------------------ |
| 162 | 89 |
| 163 // A MessagePipeReader implemenation for IPC::Message communication. | |
| 164 class ChannelMojo::MessageReader : public internal::MessagePipeReader { | |
| 165 public: | |
| 166 MessageReader(mojo::ScopedMessagePipeHandle pipe, ChannelMojo* owner) | |
| 167 : internal::MessagePipeReader(pipe.Pass()), | |
| 168 owner_(owner) {} | |
| 169 | |
| 170 bool Send(scoped_ptr<Message> message); | |
| 171 virtual void OnMessageReceived() OVERRIDE; | |
| 172 virtual void OnPipeClosed() OVERRIDE; | |
| 173 virtual void OnPipeError(MojoResult error) OVERRIDE; | |
| 174 | |
| 175 private: | |
| 176 ChannelMojo* owner_; | |
| 177 }; | |
| 178 | |
| 179 void ChannelMojo::MessageReader::OnMessageReceived() { | |
| 180 Message message(data_buffer().empty() ? "" : &data_buffer()[0], | |
| 181 static_cast<uint32>(data_buffer().size())); | |
| 182 | |
| 183 std::vector<MojoHandle> handle_buffer; | |
| 184 TakeHandleBuffer(&handle_buffer); | |
| 185 #if defined(OS_POSIX) && !defined(OS_NACL) | |
| 186 for (size_t i = 0; i < handle_buffer.size(); ++i) { | |
| 187 mojo::embedder::ScopedPlatformHandle platform_handle; | |
| 188 MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle( | |
| 189 handle_buffer[i], &platform_handle); | |
| 190 if (unwrap_result != MOJO_RESULT_OK) { | |
| 191 DLOG(WARNING) << "Pipe failed to covert handles. Closing: " | |
| 192 << unwrap_result; | |
| 193 CloseWithError(unwrap_result); | |
| 194 return; | |
| 195 } | |
| 196 | |
| 197 bool ok = message.file_descriptor_set()->Add(platform_handle.release().fd); | |
| 198 DCHECK(ok); | |
| 199 } | |
| 200 #else | |
| 201 DCHECK(handle_buffer.empty()); | |
| 202 #endif | |
| 203 | |
| 204 message.TraceMessageEnd(); | |
| 205 owner_->OnMessageReceived(message); | |
| 206 } | |
| 207 | |
| 208 void ChannelMojo::MessageReader::OnPipeClosed() { | |
| 209 if (!owner_) | |
| 210 return; | |
| 211 owner_->OnPipeClosed(this); | |
| 212 owner_ = NULL; | |
| 213 } | |
| 214 | |
| 215 void ChannelMojo::MessageReader::OnPipeError(MojoResult error) { | |
| 216 if (!owner_) | |
| 217 return; | |
| 218 owner_->OnPipeError(this); | |
| 219 } | |
| 220 | |
| 221 bool ChannelMojo::MessageReader::Send(scoped_ptr<Message> message) { | |
| 222 DCHECK(IsValid()); | |
| 223 | |
| 224 message->TraceMessageBegin(); | |
| 225 std::vector<MojoHandle> handles; | |
| 226 #if defined(OS_POSIX) && !defined(OS_NACL) | |
| 227 // We dup() the handles in IPC::Message to transmit. | |
| 228 // IPC::FileDescriptorSet has intricate lifecycle semantics | |
| 229 // of FDs, so just to dup()-and-own them is the safest option. | |
| 230 if (message->HasFileDescriptors()) { | |
| 231 FileDescriptorSet* fdset = message->file_descriptor_set(); | |
| 232 for (size_t i = 0; i < fdset->size(); ++i) { | |
| 233 int fd_to_send = dup(fdset->GetDescriptorAt(i)); | |
| 234 if (-1 == fd_to_send) { | |
| 235 DPLOG(WARNING) << "Failed to dup FD to transmit."; | |
| 236 std::for_each(handles.begin(), handles.end(), &MojoClose); | |
| 237 CloseWithError(MOJO_RESULT_UNKNOWN); | |
| 238 return false; | |
| 239 } | |
| 240 | |
| 241 MojoHandle wrapped_handle; | |
| 242 MojoResult wrap_result = CreatePlatformHandleWrapper( | |
| 243 mojo::embedder::ScopedPlatformHandle( | |
| 244 mojo::embedder::PlatformHandle(fd_to_send)), | |
| 245 &wrapped_handle); | |
| 246 if (MOJO_RESULT_OK != wrap_result) { | |
| 247 DLOG(WARNING) << "Pipe failed to wrap handles. Closing: " | |
| 248 << wrap_result; | |
| 249 std::for_each(handles.begin(), handles.end(), &MojoClose); | |
| 250 CloseWithError(wrap_result); | |
| 251 return false; | |
| 252 } | |
| 253 | |
| 254 handles.push_back(wrapped_handle); | |
| 255 } | |
| 256 } | |
| 257 #endif | |
| 258 MojoResult write_result = MojoWriteMessage( | |
| 259 handle(), | |
| 260 message->data(), static_cast<uint32>(message->size()), | |
| 261 handles.empty() ? NULL : &handles[0], | |
| 262 static_cast<uint32>(handles.size()), | |
| 263 MOJO_WRITE_MESSAGE_FLAG_NONE); | |
| 264 if (MOJO_RESULT_OK != write_result) { | |
| 265 std::for_each(handles.begin(), handles.end(), &MojoClose); | |
| 266 CloseWithError(write_result); | |
| 267 return false; | |
| 268 } | |
| 269 | |
| 270 return true; | |
| 271 } | |
| 272 | |
| 273 //------------------------------------------------------------------------------ | |
| 274 | |
| 275 // MessagePipeReader implementation for control messages. | |
| 276 // Actual message handling is implemented by sublcasses. | |
| 277 class ChannelMojo::ControlReader : public internal::MessagePipeReader { | |
| 278 public: | |
| 279 ControlReader(mojo::ScopedMessagePipeHandle pipe, ChannelMojo* owner) | |
| 280 : internal::MessagePipeReader(pipe.Pass()), | |
| 281 owner_(owner) {} | |
| 282 | |
| 283 virtual bool Connect() { return true; } | |
| 284 virtual void OnPipeClosed() OVERRIDE; | |
| 285 virtual void OnPipeError(MojoResult error) OVERRIDE; | |
| 286 | |
| 287 protected: | |
| 288 ChannelMojo* owner_; | |
| 289 }; | |
| 290 | |
| 291 void ChannelMojo::ControlReader::OnPipeClosed() { | |
| 292 if (!owner_) | |
| 293 return; | |
| 294 owner_->OnPipeClosed(this); | |
| 295 owner_ = NULL; | |
| 296 } | |
| 297 | |
| 298 void ChannelMojo::ControlReader::OnPipeError(MojoResult error) { | |
| 299 if (!owner_) | |
| 300 return; | |
| 301 owner_->OnPipeError(this); | |
| 302 } | |
| 303 | |
| 304 //------------------------------------------------------------------------------ | |
| 305 | |
| 306 // ControlReader for server-side ChannelMojo. | |
| 307 class ChannelMojo::ServerControlReader : public ChannelMojo::ControlReader { | |
| 308 public: | |
| 309 ServerControlReader(mojo::ScopedMessagePipeHandle pipe, ChannelMojo* owner) | |
| 310 : ControlReader(pipe.Pass(), owner) { } | |
| 311 | |
| 312 virtual bool Connect() OVERRIDE; | |
| 313 virtual void OnMessageReceived() OVERRIDE; | |
| 314 | |
| 315 private: | |
| 316 MojoResult SendHelloRequest(); | |
| 317 MojoResult RespondHelloResponse(); | |
| 318 | |
| 319 mojo::ScopedMessagePipeHandle message_pipe_; | |
| 320 }; | |
| 321 | |
| 322 bool ChannelMojo::ServerControlReader::Connect() { | |
| 323 MojoResult result = SendHelloRequest(); | |
| 324 if (result != MOJO_RESULT_OK) { | |
| 325 CloseWithError(result); | |
| 326 return false; | |
| 327 } | |
| 328 | |
| 329 return true; | |
| 330 } | |
| 331 | |
| 332 MojoResult ChannelMojo::ServerControlReader::SendHelloRequest() { | |
| 333 DCHECK(IsValid()); | |
| 334 DCHECK(!message_pipe_.is_valid()); | |
| 335 | |
| 336 mojo::ScopedMessagePipeHandle self; | |
| 337 mojo::ScopedMessagePipeHandle peer; | |
| 338 MojoResult create_result = mojo::CreateMessagePipe( | |
| 339 NULL, &message_pipe_, &peer); | |
| 340 if (MOJO_RESULT_OK != create_result) { | |
| 341 DLOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result; | |
| 342 return create_result; | |
| 343 } | |
| 344 | |
| 345 MojoHandle peer_to_send = peer.get().value(); | |
| 346 Pickle request = HelloMessage::CreateRequest(owner_->GetSelfPID()); | |
| 347 MojoResult write_result = MojoWriteMessage( | |
| 348 handle(), | |
| 349 request.data(), static_cast<uint32>(request.size()), | |
| 350 &peer_to_send, 1, | |
| 351 MOJO_WRITE_MESSAGE_FLAG_NONE); | |
| 352 if (MOJO_RESULT_OK != write_result) { | |
| 353 DLOG(WARNING) << "Writing Hello request failed: " << create_result; | |
| 354 return write_result; | |
| 355 } | |
| 356 | |
| 357 // |peer| is sent and no longer owned by |this|. | |
| 358 (void)peer.release(); | |
| 359 return MOJO_RESULT_OK; | |
| 360 } | |
| 361 | |
| 362 MojoResult ChannelMojo::ServerControlReader::RespondHelloResponse() { | |
| 363 Pickle request(data_buffer().empty() ? "" : &data_buffer()[0], | |
| 364 static_cast<uint32>(data_buffer().size())); | |
| 365 | |
| 366 int32 read_pid = 0; | |
| 367 if (!HelloMessage::ReadResponse(request, &read_pid)) { | |
| 368 DLOG(ERROR) << "Failed to parse Hello response."; | |
| 369 return MOJO_RESULT_UNKNOWN; | |
| 370 } | |
| 371 | |
| 372 base::ProcessId pid = static_cast<base::ProcessId>(read_pid); | |
| 373 owner_->set_peer_pid(pid); | |
| 374 owner_->OnConnected(message_pipe_.Pass()); | |
| 375 return MOJO_RESULT_OK; | |
| 376 } | |
| 377 | |
| 378 void ChannelMojo::ServerControlReader::OnMessageReceived() { | |
| 379 MojoResult result = RespondHelloResponse(); | |
| 380 if (result != MOJO_RESULT_OK) | |
| 381 CloseWithError(result); | |
| 382 } | |
| 383 | |
| 384 //------------------------------------------------------------------------------ | |
| 385 | |
| 386 // ControlReader for client-side ChannelMojo. | |
| 387 class ChannelMojo::ClientControlReader : public ChannelMojo::ControlReader { | |
| 388 public: | |
| 389 ClientControlReader(mojo::ScopedMessagePipeHandle pipe, ChannelMojo* owner) | |
| 390 : ControlReader(pipe.Pass(), owner) {} | |
| 391 | |
| 392 virtual void OnMessageReceived() OVERRIDE; | |
| 393 | |
| 394 private: | |
| 395 MojoResult RespondHelloRequest(MojoHandle message_channel); | |
| 396 }; | |
| 397 | |
| 398 MojoResult ChannelMojo::ClientControlReader::RespondHelloRequest( | |
| 399 MojoHandle message_channel) { | |
| 400 DCHECK(IsValid()); | |
| 401 | |
| 402 mojo::ScopedMessagePipeHandle received_pipe( | |
| 403 (mojo::MessagePipeHandle(message_channel))); | |
| 404 | |
| 405 int32 read_request = 0; | |
| 406 Pickle request(data_buffer().empty() ? "" : &data_buffer()[0], | |
| 407 static_cast<uint32>(data_buffer().size())); | |
| 408 if (!HelloMessage::ReadRequest(request, &read_request)) { | |
| 409 DLOG(ERROR) << "Hello request has wrong magic."; | |
| 410 return MOJO_RESULT_UNKNOWN; | |
| 411 } | |
| 412 | |
| 413 base::ProcessId pid = read_request; | |
| 414 Pickle response = HelloMessage::CreateResponse(owner_->GetSelfPID()); | |
| 415 MojoResult write_result = MojoWriteMessage( | |
| 416 handle(), | |
| 417 response.data(), static_cast<uint32>(response.size()), | |
| 418 NULL, 0, | |
| 419 MOJO_WRITE_MESSAGE_FLAG_NONE); | |
| 420 if (MOJO_RESULT_OK != write_result) { | |
| 421 DLOG(ERROR) << "Writing Hello response failed: " << write_result; | |
| 422 return write_result; | |
| 423 } | |
| 424 | |
| 425 owner_->set_peer_pid(pid); | |
| 426 owner_->OnConnected(received_pipe.Pass()); | |
| 427 return MOJO_RESULT_OK; | |
| 428 } | |
| 429 | |
| 430 void ChannelMojo::ClientControlReader::OnMessageReceived() { | |
| 431 std::vector<MojoHandle> handle_buffer; | |
| 432 TakeHandleBuffer(&handle_buffer); | |
| 433 if (handle_buffer.size() != 1) { | |
| 434 DLOG(ERROR) << "Hello request doesn't contains required handle: " | |
| 435 << handle_buffer.size(); | |
| 436 CloseWithError(MOJO_RESULT_UNKNOWN); | |
| 437 return; | |
| 438 } | |
| 439 | |
| 440 MojoResult result = RespondHelloRequest(handle_buffer[0]); | |
| 441 if (result != MOJO_RESULT_OK) { | |
| 442 DLOG(ERROR) << "Failed to respond Hello request. Closing: " | |
| 443 << result; | |
| 444 CloseWithError(result); | |
| 445 } | |
| 446 } | |
| 447 | |
| 448 //------------------------------------------------------------------------------ | |
| 449 | |
| 450 void ChannelMojo::ChannelInfoDeleter::operator()( | 90 void ChannelMojo::ChannelInfoDeleter::operator()( |
| 451 mojo::embedder::ChannelInfo* ptr) const { | 91 mojo::embedder::ChannelInfo* ptr) const { |
| 452 mojo::embedder::DestroyChannelOnIOThread(ptr); | 92 mojo::embedder::DestroyChannelOnIOThread(ptr); |
| 453 } | 93 } |
| 454 | 94 |
| 455 //------------------------------------------------------------------------------ | 95 //------------------------------------------------------------------------------ |
| 456 | 96 |
| 457 // static | 97 // static |
| 458 scoped_ptr<ChannelMojo> ChannelMojo::Create( | 98 scoped_ptr<ChannelMojo> ChannelMojo::Create( |
| 459 const ChannelHandle &channel_handle, Mode mode, Listener* listener, | 99 const ChannelHandle &channel_handle, Mode mode, Listener* listener, |
| 460 scoped_refptr<base::TaskRunner> io_thread_task_runner) { | 100 scoped_refptr<base::TaskRunner> io_thread_task_runner) { |
| 461 return make_scoped_ptr(new ChannelMojo( | 101 return make_scoped_ptr( |
| 462 Channel::Create(channel_handle, mode, g_null_listener.Pointer()), | 102 new ChannelMojo(channel_handle, mode, listener, io_thread_task_runner)); |
| 463 mode, listener, io_thread_task_runner)); | |
| 464 } | 103 } |
| 465 | 104 |
| 466 // static | 105 // static |
| 467 scoped_ptr<ChannelFactory> ChannelMojo::CreateFactory( | 106 scoped_ptr<ChannelFactory> ChannelMojo::CreateFactory( |
| 468 const ChannelHandle &channel_handle, Mode mode, | 107 const ChannelHandle &channel_handle, Mode mode, |
| 469 scoped_refptr<base::TaskRunner> io_thread_task_runner) { | 108 scoped_refptr<base::TaskRunner> io_thread_task_runner) { |
| 470 return make_scoped_ptr( | 109 return make_scoped_ptr( |
| 471 new MojoChannelFactory( | 110 new MojoChannelFactory( |
| 472 channel_handle, mode, | 111 channel_handle, mode, |
| 473 io_thread_task_runner)).PassAs<ChannelFactory>(); | 112 io_thread_task_runner)).PassAs<ChannelFactory>(); |
| 474 } | 113 } |
| 475 | 114 |
| 476 ChannelMojo::ChannelMojo( | 115 ChannelMojo::ChannelMojo(const ChannelHandle& channel_handle, |
| 477 scoped_ptr<Channel> bootstrap, Mode mode, Listener* listener, | 116 Mode mode, |
| 478 scoped_refptr<base::TaskRunner> io_thread_task_runner) | 117 Listener* listener, |
| 479 : bootstrap_(bootstrap.Pass()), | 118 scoped_refptr<base::TaskRunner> io_thread_task_runner) |
| 480 mode_(mode), listener_(listener), | 119 : bootstrap_( |
| 120 Channel::Create(channel_handle, mode, g_null_listener.Pointer())), |
| 121 mode_(mode), |
| 122 listener_(listener), |
| 481 peer_pid_(base::kNullProcessId), | 123 peer_pid_(base::kNullProcessId), |
| 482 weak_factory_(this) { | 124 weak_factory_(this) { |
| 483 if (base::MessageLoopProxy::current() == io_thread_task_runner.get()) { | 125 if (base::MessageLoopProxy::current() == io_thread_task_runner.get()) { |
| 484 InitOnIOThread(); | 126 InitOnIOThread(); |
| 485 } else { | 127 } else { |
| 486 io_thread_task_runner->PostTask(FROM_HERE, | 128 io_thread_task_runner->PostTask(FROM_HERE, |
| 487 base::Bind(&ChannelMojo::InitOnIOThread, | 129 base::Bind(&ChannelMojo::InitOnIOThread, |
| 488 weak_factory_.GetWeakPtr())); | 130 weak_factory_.GetWeakPtr())); |
| 489 } | 131 } |
| 490 } | 132 } |
| 491 | 133 |
| 492 ChannelMojo::~ChannelMojo() { | 134 ChannelMojo::~ChannelMojo() { |
| 493 Close(); | 135 Close(); |
| 494 } | 136 } |
| 495 | 137 |
| 496 void ChannelMojo::InitOnIOThread() { | 138 void ChannelMojo::InitOnIOThread() { |
| 497 mojo::embedder::ChannelInfo* channel_info; | 139 mojo::embedder::ChannelInfo* channel_info; |
| 498 mojo::ScopedMessagePipeHandle control_pipe = | 140 mojo::ScopedMessagePipeHandle control_pipe = |
| 499 mojo::embedder::CreateChannelOnIOThread( | 141 mojo::embedder::CreateChannelOnIOThread( |
| 500 mojo::embedder::ScopedPlatformHandle( | 142 mojo::embedder::ScopedPlatformHandle( |
| 501 ToPlatformHandle(bootstrap_->TakePipeHandle())), | 143 ToPlatformHandle(bootstrap_->TakePipeHandle())), |
| 502 &channel_info); | 144 &channel_info); |
| 503 channel_info_.reset(channel_info); | 145 channel_info_.reset(channel_info); |
| 504 | 146 |
| 505 switch (mode_) { | 147 switch (mode_) { |
| 506 case MODE_SERVER: | 148 case MODE_SERVER: |
| 507 control_reader_.reset(new ServerControlReader(control_pipe.Pass(), this)); | 149 control_reader_.reset( |
| 150 new internal::ServerControlReader(control_pipe.Pass(), this)); |
| 508 break; | 151 break; |
| 509 case MODE_CLIENT: | 152 case MODE_CLIENT: |
| 510 control_reader_.reset(new ClientControlReader(control_pipe.Pass(), this)); | 153 control_reader_.reset( |
| 154 new internal::ClientControlReader(control_pipe.Pass(), this)); |
| 511 break; | 155 break; |
| 512 default: | 156 default: |
| 513 NOTREACHED(); | 157 NOTREACHED(); |
| 514 break; | 158 break; |
| 515 } | 159 } |
| 516 } | 160 } |
| 517 | 161 |
| 518 bool ChannelMojo::Connect() { | 162 bool ChannelMojo::Connect() { |
| 519 DCHECK(!message_reader_); | 163 DCHECK(!message_reader_); |
| 520 return control_reader_->Connect(); | 164 return control_reader_->Connect(); |
| 521 } | 165 } |
| 522 | 166 |
| 523 void ChannelMojo::Close() { | 167 void ChannelMojo::Close() { |
| 524 control_reader_.reset(); | 168 control_reader_.reset(); |
| 525 message_reader_.reset(); | 169 message_reader_.reset(); |
| 526 channel_info_.reset(); | 170 channel_info_.reset(); |
| 527 } | 171 } |
| 528 | 172 |
| 529 void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { | 173 void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { |
| 530 message_reader_ = make_scoped_ptr(new MessageReader(pipe.Pass(), this)); | 174 message_reader_ = |
| 175 make_scoped_ptr(new internal::MessageReader(pipe.Pass(), this)); |
| 531 | 176 |
| 532 for (size_t i = 0; i < pending_messages_.size(); ++i) { | 177 for (size_t i = 0; i < pending_messages_.size(); ++i) { |
| 533 message_reader_->Send(make_scoped_ptr(pending_messages_[i])); | 178 message_reader_->Send(make_scoped_ptr(pending_messages_[i])); |
| 534 pending_messages_[i] = NULL; | 179 pending_messages_[i] = NULL; |
| 535 } | 180 } |
| 536 | 181 |
| 537 pending_messages_.clear(); | 182 pending_messages_.clear(); |
| 538 | 183 |
| 539 listener_->OnChannelConnected(GetPeerPID()); | 184 listener_->OnChannelConnected(GetPeerPID()); |
| 540 } | 185 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 } | 221 } |
| 577 | 222 |
| 578 #if defined(OS_POSIX) && !defined(OS_NACL) | 223 #if defined(OS_POSIX) && !defined(OS_NACL) |
| 579 int ChannelMojo::GetClientFileDescriptor() const { | 224 int ChannelMojo::GetClientFileDescriptor() const { |
| 580 return bootstrap_->GetClientFileDescriptor(); | 225 return bootstrap_->GetClientFileDescriptor(); |
| 581 } | 226 } |
| 582 | 227 |
| 583 int ChannelMojo::TakeClientFileDescriptor() { | 228 int ChannelMojo::TakeClientFileDescriptor() { |
| 584 return bootstrap_->TakeClientFileDescriptor(); | 229 return bootstrap_->TakeClientFileDescriptor(); |
| 585 } | 230 } |
| 231 |
| 232 // static |
| 233 MojoResult ChannelMojo::WriteToFileDescriptorSet( |
| 234 const std::vector<MojoHandle>& handle_buffer, |
| 235 Message* message) { |
| 236 for (size_t i = 0; i < handle_buffer.size(); ++i) { |
| 237 mojo::embedder::ScopedPlatformHandle platform_handle; |
| 238 MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle( |
| 239 handle_buffer[i], &platform_handle); |
| 240 if (unwrap_result != MOJO_RESULT_OK) { |
| 241 DLOG(WARNING) << "Pipe failed to covert handles. Closing: " |
| 242 << unwrap_result; |
| 243 return unwrap_result; |
| 244 } |
| 245 |
| 246 bool ok = message->file_descriptor_set()->Add(platform_handle.release().fd); |
| 247 DCHECK(ok); |
| 248 } |
| 249 |
| 250 return MOJO_RESULT_OK; |
| 251 } |
| 252 |
| 253 // static |
| 254 MojoResult ChannelMojo::ReadFromFileDescriptorSet( |
| 255 const Message& message, |
| 256 std::vector<MojoHandle>* handles) { |
| 257 // We dup() the handles in IPC::Message to transmit. |
| 258 // IPC::FileDescriptorSet has intricate lifecycle semantics |
| 259 // of FDs, so just to dup()-and-own them is the safest option. |
| 260 if (message.HasFileDescriptors()) { |
| 261 const FileDescriptorSet* fdset = message.file_descriptor_set(); |
| 262 for (size_t i = 0; i < fdset->size(); ++i) { |
| 263 int fd_to_send = dup(fdset->GetDescriptorAt(i)); |
| 264 if (-1 == fd_to_send) { |
| 265 DPLOG(WARNING) << "Failed to dup FD to transmit."; |
| 266 return MOJO_RESULT_UNKNOWN; |
| 267 } |
| 268 |
| 269 MojoHandle wrapped_handle; |
| 270 MojoResult wrap_result = CreatePlatformHandleWrapper( |
| 271 mojo::embedder::ScopedPlatformHandle( |
| 272 mojo::embedder::PlatformHandle(fd_to_send)), |
| 273 &wrapped_handle); |
| 274 if (MOJO_RESULT_OK != wrap_result) { |
| 275 DLOG(WARNING) << "Pipe failed to wrap handles. Closing: " |
| 276 << wrap_result; |
| 277 return wrap_result; |
| 278 } |
| 279 |
| 280 handles->push_back(wrapped_handle); |
| 281 } |
| 282 } |
| 283 |
| 284 return MOJO_RESULT_OK; |
| 285 } |
| 286 |
| 586 #endif // defined(OS_POSIX) && !defined(OS_NACL) | 287 #endif // defined(OS_POSIX) && !defined(OS_NACL) |
| 587 | 288 |
| 588 } // namespace IPC | 289 } // namespace IPC |
| OLD | NEW |