Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(699)

Side by Side Diff: ipc/mojo/ipc_channel_mojo.cc

Issue 1350023003: Add a Mojo EDK for Chrome that uses one OS pipe per message pipe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more cleanup Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/command_line.h"
9 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
10 #include "base/thread_task_runner_handle.h" 11 #include "base/thread_task_runner_handle.h"
11 #include "ipc/ipc_listener.h" 12 #include "ipc/ipc_listener.h"
12 #include "ipc/ipc_logging.h" 13 #include "ipc/ipc_logging.h"
13 #include "ipc/ipc_message_attachment_set.h" 14 #include "ipc/ipc_message_attachment_set.h"
14 #include "ipc/ipc_message_macros.h" 15 #include "ipc/ipc_message_macros.h"
15 #include "ipc/mojo/client_channel.mojom.h" 16 #include "ipc/mojo/client_channel.mojom.h"
16 #include "ipc/mojo/ipc_mojo_bootstrap.h" 17 #include "ipc/mojo/ipc_mojo_bootstrap.h"
17 #include "ipc/mojo/ipc_mojo_handle_attachment.h" 18 #include "ipc/mojo/ipc_mojo_handle_attachment.h"
19 #include "mojo/edk/embedder/embedder.h"
18 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" 20 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
19 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" 21 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
20 22
21 #if defined(OS_POSIX) && !defined(OS_NACL) 23 #if defined(OS_POSIX) && !defined(OS_NACL)
22 #include "ipc/ipc_platform_file_attachment_posix.h" 24 #include "ipc/ipc_platform_file_attachment_posix.h"
23 #endif 25 #endif
24 26
25 namespace IPC { 27 namespace IPC {
26 28
27 namespace { 29 namespace {
28 30
31 // TODO(jam): do more tests on using channel on same thread if it supports it (
32 // i.e. with use-new-edk and Windows). Also see message_pipe_dispatcher.cc
33 bool g_use_channel_on_io_thread_only = true;
34
29 class MojoChannelFactory : public ChannelFactory { 35 class MojoChannelFactory : public ChannelFactory {
30 public: 36 public:
31 MojoChannelFactory(scoped_refptr<base::TaskRunner> io_runner, 37 MojoChannelFactory(scoped_refptr<base::TaskRunner> io_runner,
32 ChannelHandle channel_handle, 38 ChannelHandle channel_handle,
33 Channel::Mode mode) 39 Channel::Mode mode)
34 : io_runner_(io_runner), channel_handle_(channel_handle), mode_(mode) {} 40 : io_runner_(io_runner), channel_handle_(channel_handle), mode_(mode) {}
35 41
36 std::string GetName() const override { 42 std::string GetName() const override {
37 return channel_handle_.name; 43 return channel_handle_.name;
38 } 44 }
39 45
40 scoped_ptr<Channel> BuildChannel(Listener* listener) override { 46 scoped_ptr<Channel> BuildChannel(Listener* listener) override {
41 return ChannelMojo::Create(io_runner_, channel_handle_, mode_, listener); 47 return ChannelMojo::Create(io_runner_, channel_handle_, mode_, listener);
42 } 48 }
43 49
44 private: 50 private:
45 scoped_refptr<base::TaskRunner> io_runner_; 51 scoped_refptr<base::TaskRunner> io_runner_;
46 ChannelHandle channel_handle_; 52 ChannelHandle channel_handle_;
47 Channel::Mode mode_; 53 Channel::Mode mode_;
48 }; 54 };
49 55
50 //------------------------------------------------------------------------------ 56 //------------------------------------------------------------------------------
51 57
52 class ClientChannelMojo : public ChannelMojo, public ClientChannel { 58 class ClientChannelMojo : public ChannelMojo, public ClientChannel {
53 public: 59 public:
54 ClientChannelMojo(scoped_refptr<base::TaskRunner> io_runner, 60 ClientChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
55 const ChannelHandle& handle, 61 const ChannelHandle& handle,
56 Listener* listener); 62 Listener* listener)
57 ~ClientChannelMojo() override; 63 : ChannelMojo(io_runner, handle, Channel::MODE_CLIENT, listener),
64 binding_(this),
65 weak_factory_(this) {
66 }
67 ~ClientChannelMojo() override {}
68
58 // MojoBootstrap::Delegate implementation 69 // MojoBootstrap::Delegate implementation
59 void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; 70 void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle,
71 int32 peer_pid) override {
72 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) {
73 mojo::edk::ScopedPlatformHandle edk_handle(mojo::edk::PlatformHandle(
74 #if defined(OS_WIN)
75 handle.release().handle));
76 #else
77 handle.release().fd));
78 #endif
79 InitMessageReader(
80 mojo::edk::CreateMessagePipe(edk_handle.Pass()), peer_pid);
81 return;
82 }
83 CreateMessagingPipe(handle.Pass(), base::Bind(&ClientChannelMojo::BindPipe,
84 weak_factory_.GetWeakPtr()));
85 }
60 86
61 // ClientChannel implementation 87 // ClientChannel implementation
62 void Init( 88 void Init(
63 mojo::ScopedMessagePipeHandle pipe, 89 mojo::ScopedMessagePipeHandle pipe,
64 int32_t peer_pid, 90 int32_t peer_pid,
65 const mojo::Callback<void(int32_t)>& callback) override; 91 const mojo::Callback<void(int32_t)>& callback) override {
92 InitMessageReader(pipe.Pass(), static_cast<base::ProcessId>(peer_pid));
93 callback.Run(GetSelfPID());
94 }
66 95
67 private: 96 private:
68 void BindPipe(mojo::ScopedMessagePipeHandle handle); 97 void BindPipe(mojo::ScopedMessagePipeHandle handle) {
69 void OnConnectionError(); 98 binding_.Bind(handle.Pass());
99 }
100 void OnConnectionError() {
101 listener()->OnChannelError();
102 }
70 103
71 mojo::Binding<ClientChannel> binding_; 104 mojo::Binding<ClientChannel> binding_;
72 base::WeakPtrFactory<ClientChannelMojo> weak_factory_; 105 base::WeakPtrFactory<ClientChannelMojo> weak_factory_;
73 106
74 DISALLOW_COPY_AND_ASSIGN(ClientChannelMojo); 107 DISALLOW_COPY_AND_ASSIGN(ClientChannelMojo);
75 }; 108 };
76 109
77 ClientChannelMojo::ClientChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
78 const ChannelHandle& handle,
79 Listener* listener)
80 : ChannelMojo(io_runner, handle, Channel::MODE_CLIENT, listener),
81 binding_(this),
82 weak_factory_(this) {}
83
84 ClientChannelMojo::~ClientChannelMojo() {
85 }
86
87 void ClientChannelMojo::OnPipeAvailable(
88 mojo::embedder::ScopedPlatformHandle handle) {
89 CreateMessagingPipe(handle.Pass(), base::Bind(&ClientChannelMojo::BindPipe,
90 weak_factory_.GetWeakPtr()));
91 }
92
93 void ClientChannelMojo::Init(
94 mojo::ScopedMessagePipeHandle pipe,
95 int32_t peer_pid,
96 const mojo::Callback<void(int32_t)>& callback) {
97 InitMessageReader(pipe.Pass(), static_cast<base::ProcessId>(peer_pid));
98 callback.Run(GetSelfPID());
99 }
100
101 void ClientChannelMojo::BindPipe(mojo::ScopedMessagePipeHandle handle) {
102 binding_.Bind(handle.Pass());
103 }
104
105 void ClientChannelMojo::OnConnectionError() {
106 listener()->OnChannelError();
107 }
108
109 //------------------------------------------------------------------------------ 110 //------------------------------------------------------------------------------
110 111
111 class ServerChannelMojo : public ChannelMojo { 112 class ServerChannelMojo : public ChannelMojo {
112 public: 113 public:
113 ServerChannelMojo(scoped_refptr<base::TaskRunner> io_runner, 114 ServerChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
114 const ChannelHandle& handle, 115 const ChannelHandle& handle,
115 Listener* listener); 116 Listener* listener)
116 ~ServerChannelMojo() override; 117 : ChannelMojo(io_runner, handle, Channel::MODE_SERVER, listener),
118 weak_factory_(this) {
119 }
120 ~ServerChannelMojo() override {
121 Close();
122 }
117 123
118 // MojoBootstrap::Delegate implementation 124 // MojoBootstrap::Delegate implementation
119 void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; 125 void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle,
126 int32 peer_pid) override {
127 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) {
128 mojo::edk::ScopedPlatformHandle edk_handle(mojo::edk::PlatformHandle(
129 #if defined(OS_WIN)
130 handle.release().handle));
131 #else
132 handle.release().fd));
133 #endif
134 message_pipe_ = mojo::edk::CreateMessagePipe(edk_handle.Pass());
135 if (!message_pipe_.is_valid()) {
136 LOG(WARNING) << "mojo::CreateMessagePipe failed: ";
137 listener()->OnChannelError();
138 return;
139 }
140 InitMessageReader(message_pipe_.Pass(), peer_pid);
141 return;
142 }
143
144 mojo::ScopedMessagePipeHandle peer;
145 MojoResult create_result =
146 mojo::CreateMessagePipe(nullptr, &message_pipe_, &peer);
147 if (create_result != MOJO_RESULT_OK) {
148 LOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result;
149 listener()->OnChannelError();
150 return;
151 }
152 CreateMessagingPipe(
153 handle.Pass(),
154 base::Bind(&ServerChannelMojo::InitClientChannel,
155 weak_factory_.GetWeakPtr(), base::Passed(&peer)));
156 }
120 // Channel override 157 // Channel override
121 void Close() override; 158 void Close() override {
159 client_channel_.reset();
160 message_pipe_.reset();
161 ChannelMojo::Close();
162 }
122 163
123 private: 164 private:
124 void InitClientChannel(mojo::ScopedMessagePipeHandle peer_handle, 165 void InitClientChannel(mojo::ScopedMessagePipeHandle peer_handle,
125 mojo::ScopedMessagePipeHandle handle); 166 mojo::ScopedMessagePipeHandle handle) {
126 void OnConnectionError(); 167 client_channel_.Bind(
168 mojo::InterfacePtrInfo<ClientChannel>(handle.Pass(), 0u));
169 client_channel_.set_connection_error_handler(base::Bind(
170 &ServerChannelMojo::OnConnectionError, base::Unretained(this)));
171 client_channel_->Init(
172 peer_handle.Pass(), static_cast<int32_t>(GetSelfPID()),
173 base::Bind(&ServerChannelMojo::ClientChannelWasInitialized,
174 base::Unretained(this)));
175 }
176
177 void OnConnectionError() {
178 listener()->OnChannelError();
179 }
127 180
128 // ClientChannelClient implementation 181 // ClientChannelClient implementation
129 void ClientChannelWasInitialized(int32_t peer_pid); 182 void ClientChannelWasInitialized(int32_t peer_pid) {
183 InitMessageReader(message_pipe_.Pass(), peer_pid);
184 }
130 185
131 mojo::InterfacePtr<ClientChannel> client_channel_; 186 mojo::InterfacePtr<ClientChannel> client_channel_;
132 mojo::ScopedMessagePipeHandle message_pipe_; 187 mojo::ScopedMessagePipeHandle message_pipe_;
133 base::WeakPtrFactory<ServerChannelMojo> weak_factory_; 188 base::WeakPtrFactory<ServerChannelMojo> weak_factory_;
134 189
135 DISALLOW_COPY_AND_ASSIGN(ServerChannelMojo); 190 DISALLOW_COPY_AND_ASSIGN(ServerChannelMojo);
136 }; 191 };
137 192
138 ServerChannelMojo::ServerChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
139 const ChannelHandle& handle,
140 Listener* listener)
141 : ChannelMojo(io_runner, handle, Channel::MODE_SERVER, listener),
142 weak_factory_(this) {}
143
144 ServerChannelMojo::~ServerChannelMojo() {
145 Close();
146 }
147
148 void ServerChannelMojo::OnPipeAvailable(
149 mojo::embedder::ScopedPlatformHandle handle) {
150 mojo::ScopedMessagePipeHandle peer;
151 MojoResult create_result =
152 mojo::CreateMessagePipe(nullptr, &message_pipe_, &peer);
153 if (create_result != MOJO_RESULT_OK) {
154 LOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result;
155 listener()->OnChannelError();
156 return;
157 }
158 CreateMessagingPipe(
159 handle.Pass(),
160 base::Bind(&ServerChannelMojo::InitClientChannel,
161 weak_factory_.GetWeakPtr(), base::Passed(&peer)));
162 }
163
164 void ServerChannelMojo::Close() {
165 client_channel_.reset();
166 message_pipe_.reset();
167 ChannelMojo::Close();
168 }
169
170 void ServerChannelMojo::InitClientChannel(
171 mojo::ScopedMessagePipeHandle peer_handle,
172 mojo::ScopedMessagePipeHandle handle) {
173 client_channel_.Bind(
174 mojo::InterfacePtrInfo<ClientChannel>(handle.Pass(), 0u));
175 client_channel_.set_connection_error_handler(base::Bind(
176 &ServerChannelMojo::OnConnectionError, base::Unretained(this)));
177 client_channel_->Init(
178 peer_handle.Pass(), static_cast<int32_t>(GetSelfPID()),
179 base::Bind(&ServerChannelMojo::ClientChannelWasInitialized,
180 base::Unretained(this)));
181 }
182
183 void ServerChannelMojo::OnConnectionError() {
184 listener()->OnChannelError();
185 }
186
187 void ServerChannelMojo::ClientChannelWasInitialized(int32_t peer_pid) {
188 InitMessageReader(message_pipe_.Pass(), peer_pid);
189 }
190
191 #if defined(OS_POSIX) && !defined(OS_NACL) 193 #if defined(OS_POSIX) && !defined(OS_NACL)
192 194
193 base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) { 195 base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
194 return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile()) 196 return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile())
195 : base::ScopedFD(dup(attachment->file())); 197 : base::ScopedFD(dup(attachment->file()));
196 } 198 }
197 199
198 #endif 200 #endif
199 201
200 } // namespace 202 } // namespace
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 Listener* listener) 271 Listener* listener)
270 : listener_(listener), 272 : listener_(listener),
271 peer_pid_(base::kNullProcessId), 273 peer_pid_(base::kNullProcessId),
272 io_runner_(io_runner), 274 io_runner_(io_runner),
273 channel_info_(nullptr, ChannelInfoDeleter(nullptr)), 275 channel_info_(nullptr, ChannelInfoDeleter(nullptr)),
274 waiting_connect_(true), 276 waiting_connect_(true),
275 weak_factory_(this) { 277 weak_factory_(this) {
276 // Create MojoBootstrap after all members are set as it touches 278 // Create MojoBootstrap after all members are set as it touches
277 // ChannelMojo from a different thread. 279 // ChannelMojo from a different thread.
278 bootstrap_ = MojoBootstrap::Create(handle, mode, this); 280 bootstrap_ = MojoBootstrap::Create(handle, mode, this);
279 if (io_runner == base::MessageLoop::current()->task_runner()) { 281 if (!g_use_channel_on_io_thread_only ||
282 io_runner == base::MessageLoop::current()->task_runner()) {
280 InitOnIOThread(); 283 InitOnIOThread();
281 } else { 284 } else {
282 io_runner->PostTask(FROM_HERE, base::Bind(&ChannelMojo::InitOnIOThread, 285 io_runner->PostTask(FROM_HERE, base::Bind(&ChannelMojo::InitOnIOThread,
283 base::Unretained(this))); 286 base::Unretained(this)));
284 } 287 }
285 } 288 }
286 289
287 ChannelMojo::~ChannelMojo() { 290 ChannelMojo::~ChannelMojo() {
288 Close(); 291 Close();
289 } 292 }
290 293
291 void ChannelMojo::InitOnIOThread() { 294 void ChannelMojo::InitOnIOThread() {
292 ipc_support_.reset( 295 ipc_support_.reset(
293 new ScopedIPCSupport(base::MessageLoop::current()->task_runner())); 296 new ScopedIPCSupport(base::MessageLoop::current()->task_runner()));
294 } 297 }
295 298
296 void ChannelMojo::CreateMessagingPipe( 299 void ChannelMojo::CreateMessagingPipe(
297 mojo::embedder::ScopedPlatformHandle handle, 300 mojo::embedder::ScopedPlatformHandle handle,
298 const CreateMessagingPipeCallback& callback) { 301 const CreateMessagingPipeCallback& callback) {
299 auto return_callback = base::Bind(&ChannelMojo::OnMessagingPipeCreated, 302 auto return_callback = base::Bind(&ChannelMojo::OnMessagingPipeCreated,
300 weak_factory_.GetWeakPtr(), callback); 303 weak_factory_.GetWeakPtr(), callback);
301 if (base::ThreadTaskRunnerHandle::Get() == io_runner_) { 304 if (!g_use_channel_on_io_thread_only ||
305 base::ThreadTaskRunnerHandle::Get() == io_runner_) {
302 CreateMessagingPipeOnIOThread( 306 CreateMessagingPipeOnIOThread(
303 handle.Pass(), base::ThreadTaskRunnerHandle::Get(), return_callback); 307 handle.Pass(), base::ThreadTaskRunnerHandle::Get(), return_callback);
304 } else { 308 } else {
305 io_runner_->PostTask( 309 io_runner_->PostTask(
306 FROM_HERE, 310 FROM_HERE,
307 base::Bind(&ChannelMojo::CreateMessagingPipeOnIOThread, 311 base::Bind(&ChannelMojo::CreateMessagingPipeOnIOThread,
308 base::Passed(&handle), base::ThreadTaskRunnerHandle::Get(), 312 base::Passed(&handle), base::ThreadTaskRunnerHandle::Get(),
309 return_callback)); 313 return_callback));
310 } 314 }
311 } 315 }
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 base::ScopedFD file = 484 base::ScopedFD file =
481 TakeOrDupFile(static_cast<IPC::internal::PlatformFileAttachment*>( 485 TakeOrDupFile(static_cast<IPC::internal::PlatformFileAttachment*>(
482 attachment.get())); 486 attachment.get()));
483 if (!file.is_valid()) { 487 if (!file.is_valid()) {
484 DPLOG(WARNING) << "Failed to dup FD to transmit."; 488 DPLOG(WARNING) << "Failed to dup FD to transmit.";
485 set->CommitAll(); 489 set->CommitAll();
486 return MOJO_RESULT_UNKNOWN; 490 return MOJO_RESULT_UNKNOWN;
487 } 491 }
488 492
489 MojoHandle wrapped_handle; 493 MojoHandle wrapped_handle;
490 MojoResult wrap_result = CreatePlatformHandleWrapper( 494 MojoResult wrap_result = mojo::embedder::CreatePlatformHandleWrapper(
491 mojo::embedder::ScopedPlatformHandle( 495 mojo::embedder::ScopedPlatformHandle(
492 mojo::embedder::PlatformHandle(file.release())), 496 mojo::embedder::PlatformHandle(file.release())),
493 &wrapped_handle); 497 &wrapped_handle);
494 if (MOJO_RESULT_OK != wrap_result) { 498 if (MOJO_RESULT_OK != wrap_result) {
495 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " 499 LOG(WARNING) << "Pipe failed to wrap handles. Closing: "
496 << wrap_result; 500 << wrap_result;
497 set->CommitAll(); 501 set->CommitAll();
498 return wrap_result; 502 return wrap_result;
499 } 503 }
500 504
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 if (!ok) { 540 if (!ok) {
537 LOG(ERROR) << "Failed to add new Mojo handle."; 541 LOG(ERROR) << "Failed to add new Mojo handle.";
538 return MOJO_RESULT_UNKNOWN; 542 return MOJO_RESULT_UNKNOWN;
539 } 543 }
540 } 544 }
541 545
542 return MOJO_RESULT_OK; 546 return MOJO_RESULT_OK;
543 } 547 }
544 548
545 } // namespace IPC 549 } // namespace IPC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698