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/raw_channel.h" | 5 #include "mojo/edk/system/raw_channel.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <sys/uio.h> | 8 #include <sys/uio.h> |
9 #include <unistd.h> | 9 #include <unistd.h> |
10 | 10 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 platform_handles->size() > embedder::kPlatformChannelMaxNumHandles) { | 128 platform_handles->size() > embedder::kPlatformChannelMaxNumHandles) { |
129 // We can't attach all the FDs to a single message, so we have to "split" | 129 // We can't attach all the FDs to a single message, so we have to "split" |
130 // the message. Send as many control messages as needed first with FDs | 130 // the message. Send as many control messages as needed first with FDs |
131 // attached (and no data). | 131 // attached (and no data). |
132 size_t i = 0; | 132 size_t i = 0; |
133 for (; platform_handles->size() - i > | 133 for (; platform_handles->size() - i > |
134 embedder::kPlatformChannelMaxNumHandles; | 134 embedder::kPlatformChannelMaxNumHandles; |
135 i += embedder::kPlatformChannelMaxNumHandles) { | 135 i += embedder::kPlatformChannelMaxNumHandles) { |
136 scoped_ptr<MessageInTransit> fd_message(new MessageInTransit( | 136 scoped_ptr<MessageInTransit> fd_message(new MessageInTransit( |
137 MessageInTransit::kTypeRawChannel, | 137 MessageInTransit::kTypeRawChannel, |
138 MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles, 0, | 138 MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles, |
| 139 0, |
139 nullptr)); | 140 nullptr)); |
140 embedder::ScopedPlatformHandleVectorPtr fds( | 141 embedder::ScopedPlatformHandleVectorPtr fds( |
141 new embedder::PlatformHandleVector( | 142 new embedder::PlatformHandleVector( |
142 platform_handles->begin() + i, | 143 platform_handles->begin() + i, |
143 platform_handles->begin() + i + | 144 platform_handles->begin() + i + |
144 embedder::kPlatformChannelMaxNumHandles)); | 145 embedder::kPlatformChannelMaxNumHandles)); |
145 fd_message->SetTransportData( | 146 fd_message->SetTransportData( |
146 make_scoped_ptr(new TransportData(fds.Pass()))); | 147 make_scoped_ptr(new TransportData(fds.Pass()))); |
147 RawChannel::EnqueueMessageNoLock(fd_message.Pass()); | 148 RawChannel::EnqueueMessageNoLock(fd_message.Pass()); |
148 } | 149 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 write_result = embedder::PlatformChannelSendmsgWithHandles( | 246 write_result = embedder::PlatformChannelSendmsgWithHandles( |
246 fd_.get(), iov, buffer_count, platform_handles, num_platform_handles); | 247 fd_.get(), iov, buffer_count, platform_handles, num_platform_handles); |
247 for (size_t i = 0; i < num_platform_handles; i++) | 248 for (size_t i = 0; i < num_platform_handles; i++) |
248 platform_handles[i].CloseIfNecessary(); | 249 platform_handles[i].CloseIfNecessary(); |
249 } else { | 250 } else { |
250 std::vector<WriteBuffer::Buffer> buffers; | 251 std::vector<WriteBuffer::Buffer> buffers; |
251 write_buffer_no_lock()->GetBuffers(&buffers); | 252 write_buffer_no_lock()->GetBuffers(&buffers); |
252 DCHECK(!buffers.empty()); | 253 DCHECK(!buffers.empty()); |
253 | 254 |
254 if (buffers.size() == 1) { | 255 if (buffers.size() == 1) { |
255 write_result = embedder::PlatformChannelWrite(fd_.get(), buffers[0].addr, | 256 write_result = embedder::PlatformChannelWrite( |
256 buffers[0].size); | 257 fd_.get(), buffers[0].addr, buffers[0].size); |
257 } else { | 258 } else { |
258 const size_t kMaxBufferCount = 10; | 259 const size_t kMaxBufferCount = 10; |
259 iovec iov[kMaxBufferCount]; | 260 iovec iov[kMaxBufferCount]; |
260 size_t buffer_count = std::min(buffers.size(), kMaxBufferCount); | 261 size_t buffer_count = std::min(buffers.size(), kMaxBufferCount); |
261 for (size_t i = 0; i < buffer_count; ++i) { | 262 for (size_t i = 0; i < buffer_count; ++i) { |
262 iov[i].iov_base = const_cast<char*>(buffers[i].addr); | 263 iov[i].iov_base = const_cast<char*>(buffers[i].addr); |
263 iov[i].iov_len = buffers[i].size; | 264 iov[i].iov_len = buffers[i].size; |
264 } | 265 } |
265 | 266 |
266 write_result = | 267 write_result = |
(...skipping 27 matching lines...) Expand all Loading... |
294 // If we're not on the I/O thread, we have to post a task to do this. | 295 // If we're not on the I/O thread, we have to post a task to do this. |
295 if (base::MessageLoop::current() != message_loop_for_io()) { | 296 if (base::MessageLoop::current() != message_loop_for_io()) { |
296 message_loop_for_io()->PostTask(FROM_HERE, | 297 message_loop_for_io()->PostTask(FROM_HERE, |
297 base::Bind(&RawChannelPosix::WaitToWrite, | 298 base::Bind(&RawChannelPosix::WaitToWrite, |
298 weak_ptr_factory_.GetWeakPtr())); | 299 weak_ptr_factory_.GetWeakPtr())); |
299 pending_write_ = true; | 300 pending_write_ = true; |
300 return IO_PENDING; | 301 return IO_PENDING; |
301 } | 302 } |
302 | 303 |
303 if (message_loop_for_io()->WatchFileDescriptor( | 304 if (message_loop_for_io()->WatchFileDescriptor( |
304 fd_.get().fd, false, base::MessageLoopForIO::WATCH_WRITE, | 305 fd_.get().fd, |
305 write_watcher_.get(), this)) { | 306 false, |
| 307 base::MessageLoopForIO::WATCH_WRITE, |
| 308 write_watcher_.get(), |
| 309 this)) { |
306 pending_write_ = true; | 310 pending_write_ = true; |
307 return IO_PENDING; | 311 return IO_PENDING; |
308 } | 312 } |
309 | 313 |
310 return IO_FAILED_UNKNOWN; | 314 return IO_FAILED_UNKNOWN; |
311 } | 315 } |
312 | 316 |
313 bool RawChannelPosix::OnInit() { | 317 bool RawChannelPosix::OnInit() { |
314 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 318 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
315 | 319 |
316 DCHECK(!read_watcher_); | 320 DCHECK(!read_watcher_); |
317 read_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); | 321 read_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); |
318 DCHECK(!write_watcher_); | 322 DCHECK(!write_watcher_); |
319 write_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); | 323 write_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); |
320 | 324 |
321 if (!message_loop_for_io()->WatchFileDescriptor( | 325 if (!message_loop_for_io()->WatchFileDescriptor( |
322 fd_.get().fd, true, base::MessageLoopForIO::WATCH_READ, | 326 fd_.get().fd, |
323 read_watcher_.get(), this)) { | 327 true, |
| 328 base::MessageLoopForIO::WATCH_READ, |
| 329 read_watcher_.get(), |
| 330 this)) { |
324 // TODO(vtl): I'm not sure |WatchFileDescriptor()| actually fails cleanly | 331 // TODO(vtl): I'm not sure |WatchFileDescriptor()| actually fails cleanly |
325 // (in the sense of returning the message loop's state to what it was before | 332 // (in the sense of returning the message loop's state to what it was before |
326 // it was called). | 333 // it was called). |
327 read_watcher_.reset(); | 334 read_watcher_.reset(); |
328 write_watcher_.reset(); | 335 write_watcher_.reset(); |
329 return false; | 336 return false; |
330 } | 337 } |
331 | 338 |
332 return true; | 339 return true; |
333 } | 340 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 if (read_platform_handles_.size() > old_num_platform_handles) { | 414 if (read_platform_handles_.size() > old_num_platform_handles) { |
408 DCHECK_LE(read_platform_handles_.size() - old_num_platform_handles, | 415 DCHECK_LE(read_platform_handles_.size() - old_num_platform_handles, |
409 embedder::kPlatformChannelMaxNumHandles); | 416 embedder::kPlatformChannelMaxNumHandles); |
410 | 417 |
411 // We should never accumulate more than |TransportData::kMaxPlatformHandles | 418 // We should never accumulate more than |TransportData::kMaxPlatformHandles |
412 // + embedder::kPlatformChannelMaxNumHandles| handles. (The latter part is | 419 // + embedder::kPlatformChannelMaxNumHandles| handles. (The latter part is |
413 // possible because we could have accumulated all the handles for a message, | 420 // possible because we could have accumulated all the handles for a message, |
414 // then received the message data plus the first set of handles for the next | 421 // then received the message data plus the first set of handles for the next |
415 // message in the subsequent |recvmsg()|.) | 422 // message in the subsequent |recvmsg()|.) |
416 if (read_platform_handles_.size() > | 423 if (read_platform_handles_.size() > |
417 (TransportData::GetMaxPlatformHandles() + | 424 (TransportData::kMaxPlatformHandles + |
418 embedder::kPlatformChannelMaxNumHandles)) { | 425 embedder::kPlatformChannelMaxNumHandles)) { |
419 LOG(ERROR) << "Received too many platform handles"; | 426 LOG(ERROR) << "Received too many platform handles"; |
420 embedder::CloseAllPlatformHandles(&read_platform_handles_); | 427 embedder::CloseAllPlatformHandles(&read_platform_handles_); |
421 read_platform_handles_.clear(); | 428 read_platform_handles_.clear(); |
422 return IO_FAILED_UNKNOWN; | 429 return IO_FAILED_UNKNOWN; |
423 } | 430 } |
424 } | 431 } |
425 | 432 |
426 if (read_result > 0) { | 433 if (read_result > 0) { |
427 *bytes_read = static_cast<size_t>(read_result); | 434 *bytes_read = static_cast<size_t>(read_result); |
(...skipping 13 matching lines...) Expand all Loading... |
441 PLOG(WARNING) << "recvmsg"; | 448 PLOG(WARNING) << "recvmsg"; |
442 return IO_FAILED_UNKNOWN; | 449 return IO_FAILED_UNKNOWN; |
443 } | 450 } |
444 | 451 |
445 void RawChannelPosix::WaitToWrite() { | 452 void RawChannelPosix::WaitToWrite() { |
446 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 453 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
447 | 454 |
448 DCHECK(write_watcher_); | 455 DCHECK(write_watcher_); |
449 | 456 |
450 if (!message_loop_for_io()->WatchFileDescriptor( | 457 if (!message_loop_for_io()->WatchFileDescriptor( |
451 fd_.get().fd, false, base::MessageLoopForIO::WATCH_WRITE, | 458 fd_.get().fd, |
452 write_watcher_.get(), this)) { | 459 false, |
| 460 base::MessageLoopForIO::WATCH_WRITE, |
| 461 write_watcher_.get(), |
| 462 this)) { |
453 { | 463 { |
454 base::AutoLock locker(write_lock()); | 464 base::AutoLock locker(write_lock()); |
455 | 465 |
456 DCHECK(pending_write_); | 466 DCHECK(pending_write_); |
457 pending_write_ = false; | 467 pending_write_ = false; |
458 } | 468 } |
459 OnWriteCompleted(IO_FAILED_UNKNOWN, 0, 0); | 469 OnWriteCompleted(IO_FAILED_UNKNOWN, 0, 0); |
460 } | 470 } |
461 } | 471 } |
462 | 472 |
463 } // namespace | 473 } // namespace |
464 | 474 |
465 // ----------------------------------------------------------------------------- | 475 // ----------------------------------------------------------------------------- |
466 | 476 |
467 // Static factory method declared in raw_channel.h. | 477 // Static factory method declared in raw_channel.h. |
468 // static | 478 // static |
469 scoped_ptr<RawChannel> RawChannel::Create( | 479 scoped_ptr<RawChannel> RawChannel::Create( |
470 embedder::ScopedPlatformHandle handle) { | 480 embedder::ScopedPlatformHandle handle) { |
471 return make_scoped_ptr(new RawChannelPosix(handle.Pass())); | 481 return make_scoped_ptr(new RawChannelPosix(handle.Pass())); |
472 } | 482 } |
473 | 483 |
474 } // namespace system | 484 } // namespace system |
475 } // namespace mojo | 485 } // namespace mojo |
OLD | NEW |