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

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

Issue 559723002: Refactoring: Move MessagePipeReader subclasess out from ChannelMojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Landing Created 6 years, 3 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
« no previous file with comments | « ipc/mojo/ipc_channel_mojo.h ('k') | ipc/mojo/ipc_channel_mojo_readers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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
OLDNEW
« no previous file with comments | « ipc/mojo/ipc_channel_mojo.h ('k') | ipc/mojo/ipc_channel_mojo_readers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698