OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/channel.h" | 5 #include "mojo/edk/system/channel.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <sys/uio.h> | 8 #include <sys/uio.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 18 matching lines...) Expand all Loading... |
29 const size_t kMaxBatchReadCapacity = 256 * 1024; | 29 const size_t kMaxBatchReadCapacity = 256 * 1024; |
30 | 30 |
31 // A view over a Channel::Message object. The write queue uses these since | 31 // A view over a Channel::Message object. The write queue uses these since |
32 // large messages may need to be sent in chunks. | 32 // large messages may need to be sent in chunks. |
33 class MessageView { | 33 class MessageView { |
34 public: | 34 public: |
35 // Owns |message|. |offset| indexes the first unsent byte in the message. | 35 // Owns |message|. |offset| indexes the first unsent byte in the message. |
36 MessageView(Channel::MessagePtr message, size_t offset) | 36 MessageView(Channel::MessagePtr message, size_t offset) |
37 : message_(std::move(message)), | 37 : message_(std::move(message)), |
38 offset_(offset), | 38 offset_(offset), |
39 handles_(message_->TakeHandles()) { | 39 handles_(message_->TakeHandlesForTransport()) { |
40 DCHECK_GT(message_->data_num_bytes(), offset_); | 40 DCHECK_GT(message_->data_num_bytes(), offset_); |
41 } | 41 } |
42 | 42 |
43 MessageView(MessageView&& other) { *this = std::move(other); } | 43 MessageView(MessageView&& other) { *this = std::move(other); } |
44 | 44 |
45 MessageView& operator=(MessageView&& other) { | 45 MessageView& operator=(MessageView&& other) { |
46 message_ = std::move(other.message_); | 46 message_ = std::move(other.message_); |
47 offset_ = other.offset_; | 47 offset_ = other.offset_; |
48 handles_ = std::move(other.handles_); | 48 handles_ = std::move(other.handles_); |
49 return *this; | 49 return *this; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 // the delegate and we don't want to re-enter it. | 129 // the delegate and we don't want to re-enter it. |
130 io_task_runner_->PostTask(FROM_HERE, | 130 io_task_runner_->PostTask(FROM_HERE, |
131 base::Bind(&ChannelPosix::OnError, this)); | 131 base::Bind(&ChannelPosix::OnError, this)); |
132 } | 132 } |
133 } | 133 } |
134 | 134 |
135 ScopedPlatformHandleVectorPtr GetReadPlatformHandles( | 135 ScopedPlatformHandleVectorPtr GetReadPlatformHandles( |
136 size_t num_handles, | 136 size_t num_handles, |
137 const void* extra_header, | 137 const void* extra_header, |
138 size_t extra_header_size) override { | 138 size_t extra_header_size) override { |
| 139 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 140 // On OSX, we can have mach ports which are located in the extra header |
| 141 // section. |
| 142 using MachPortsEntry = Channel::Message::MachPortsEntry; |
| 143 CHECK(extra_header_size >= num_handles * sizeof(MachPortsEntry)); |
| 144 size_t num_mach_ports = 0; |
| 145 const MachPortsEntry* mach_ports = |
| 146 reinterpret_cast<const MachPortsEntry*>(extra_header); |
| 147 for (size_t i = 0; i < num_handles; i++) { |
| 148 if (mach_ports[i].mach_port != MACH_PORT_NULL) |
| 149 num_mach_ports++; |
| 150 } |
| 151 CHECK(num_mach_ports <= num_handles); |
| 152 if (incoming_platform_handles_.size() + num_mach_ports < num_handles) |
| 153 return nullptr; |
| 154 |
| 155 ScopedPlatformHandleVectorPtr handles( |
| 156 new PlatformHandleVector(num_handles)); |
| 157 for (size_t i = 0, mach_port_index = 0; i < num_handles; ++i) { |
| 158 if (mach_port_index < num_mach_ports && |
| 159 mach_ports[mach_port_index].index == i) { |
| 160 (*handles)[i] = PlatformHandle( |
| 161 static_cast<mach_port_t>(mach_ports[mach_port_index].mach_port)); |
| 162 CHECK((*handles)[i].type == PlatformHandle::Type::MACH); |
| 163 // These are actually just Mach port names until they're resolved from |
| 164 // the remote process. |
| 165 (*handles)[i].type = PlatformHandle::Type::MACH_NAME; |
| 166 mach_port_index++; |
| 167 } else { |
| 168 CHECK(!incoming_platform_handles_.empty()); |
| 169 (*handles)[i] = incoming_platform_handles_.front(); |
| 170 incoming_platform_handles_.pop_front(); |
| 171 } |
| 172 } |
| 173 #else |
139 if (incoming_platform_handles_.size() < num_handles) | 174 if (incoming_platform_handles_.size() < num_handles) |
140 return nullptr; | 175 return nullptr; |
141 | 176 |
142 ScopedPlatformHandleVectorPtr handles( | 177 ScopedPlatformHandleVectorPtr handles( |
143 new PlatformHandleVector(num_handles)); | 178 new PlatformHandleVector(num_handles)); |
144 for (size_t i = 0; i < num_handles; ++i) { | 179 for (size_t i = 0; i < num_handles; ++i) { |
145 (*handles)[i] = incoming_platform_handles_.front(); | 180 (*handles)[i] = incoming_platform_handles_.front(); |
146 incoming_platform_handles_.pop_front(); | 181 incoming_platform_handles_.pop_front(); |
147 } | 182 } |
| 183 #endif |
148 | 184 |
149 return handles; | 185 return handles; |
150 } | 186 } |
151 | 187 |
152 private: | 188 private: |
153 ~ChannelPosix() override { | 189 ~ChannelPosix() override { |
154 DCHECK(!read_watcher_); | 190 DCHECK(!read_watcher_); |
155 DCHECK(!write_watcher_); | 191 DCHECK(!write_watcher_); |
156 for (auto handle : incoming_platform_handles_) | 192 for (auto handle : incoming_platform_handles_) |
157 handle.CloseIfNecessary(); | 193 handle.CloseIfNecessary(); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 // static | 486 // static |
451 scoped_refptr<Channel> Channel::Create( | 487 scoped_refptr<Channel> Channel::Create( |
452 Delegate* delegate, | 488 Delegate* delegate, |
453 ScopedPlatformHandle platform_handle, | 489 ScopedPlatformHandle platform_handle, |
454 scoped_refptr<base::TaskRunner> io_task_runner) { | 490 scoped_refptr<base::TaskRunner> io_task_runner) { |
455 return new ChannelPosix(delegate, std::move(platform_handle), io_task_runner); | 491 return new ChannelPosix(delegate, std::move(platform_handle), io_task_runner); |
456 } | 492 } |
457 | 493 |
458 } // namespace edk | 494 } // namespace edk |
459 } // namespace mojo | 495 } // namespace mojo |
OLD | NEW |