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> |
Ken Rockot(use gerrit already)
2015/09/23 22:32:17
need sys/stat.h
| |
9 #include <unistd.h> | 9 #include <unistd.h> |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 #include <deque> | 12 #include <deque> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/location.h" | 15 #include "base/location.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
18 #include "base/memory/weak_ptr.h" | 18 #include "base/memory/weak_ptr.h" |
19 #include "base/message_loop/message_loop.h" | 19 #include "base/message_loop/message_loop.h" |
20 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
21 #include "mojo/edk/embedder/platform_channel_utils_posix.h" | 21 #include "mojo/edk/embedder/platform_channel_utils_posix.h" |
22 #include "mojo/edk/embedder/platform_handle.h" | 22 #include "mojo/edk/embedder/platform_handle.h" |
23 #include "mojo/edk/embedder/platform_handle_vector.h" | 23 #include "mojo/edk/embedder/platform_handle_vector.h" |
24 #include "mojo/edk/system/transport_data.h" | 24 #include "mojo/edk/system/transport_data.h" |
25 #include "mojo/public/cpp/system/macros.h" | 25 #include "mojo/public/cpp/system/macros.h" |
26 | 26 |
27 namespace mojo { | 27 namespace mojo { |
28 namespace system { | 28 namespace edk { |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 class RawChannelPosix final : public RawChannel, | 32 class RawChannelPosix final : public RawChannel, |
33 public base::MessageLoopForIO::Watcher { | 33 public base::MessageLoopForIO::Watcher { |
34 public: | 34 public: |
35 explicit RawChannelPosix(embedder::ScopedPlatformHandle handle); | 35 explicit RawChannelPosix(ScopedPlatformHandle handle); |
36 ~RawChannelPosix() override; | 36 ~RawChannelPosix() override; |
37 | 37 |
38 // |RawChannel| public methods: | |
39 size_t GetSerializedPlatformHandleSize() const override; | |
40 | |
41 private: | 38 private: |
42 // |RawChannel| protected methods: | 39 // |RawChannel| protected methods: |
43 // Actually override this so that we can send multiple messages with (only) | 40 // Actually override this so that we can send multiple messages with (only) |
44 // FDs if necessary. | 41 // FDs if necessary. |
45 void EnqueueMessageNoLock(scoped_ptr<MessageInTransit> message) override; | 42 void EnqueueMessageNoLock(scoped_ptr<MessageInTransit> message) override; |
46 // Override this to handle those extra FD-only messages. | 43 // Override this to handle those extra FD-only messages. |
47 bool OnReadMessageForRawChannel( | 44 bool OnReadMessageForRawChannel( |
48 const MessageInTransit::View& message_view) override; | 45 const MessageInTransit::View& message_view) override; |
46 | |
47 ScopedPlatformHandle ReleaseHandleNoLock( | |
48 std::vector<char>* read_buffer_out) override; | |
49 PlatformHandle HandleForDebuggingNoLock() override; | |
49 IOResult Read(size_t* bytes_read) override; | 50 IOResult Read(size_t* bytes_read) override; |
50 IOResult ScheduleRead() override; | 51 IOResult ScheduleRead() override; |
51 embedder::ScopedPlatformHandleVectorPtr GetReadPlatformHandles( | 52 ScopedPlatformHandleVectorPtr GetReadPlatformHandles( |
52 size_t num_platform_handles, | 53 size_t num_platform_handles, |
53 const void* platform_handle_table) override; | 54 const void* platform_handle_table) override; |
54 IOResult WriteNoLock(size_t* platform_handles_written, | 55 IOResult WriteNoLock(size_t* platform_handles_written, |
55 size_t* bytes_written) override; | 56 size_t* bytes_written) override; |
56 IOResult ScheduleWriteNoLock() override; | 57 IOResult ScheduleWriteNoLock() override; |
57 void OnInit() override; | 58 void OnInit() override; |
58 void OnShutdownNoLock(scoped_ptr<ReadBuffer> read_buffer, | 59 void OnShutdownNoLock(scoped_ptr<ReadBuffer> read_buffer, |
59 scoped_ptr<WriteBuffer> write_buffer) override; | 60 scoped_ptr<WriteBuffer> write_buffer) override; |
60 | 61 |
61 // |base::MessageLoopForIO::Watcher| implementation: | 62 // |base::MessageLoopForIO::Watcher| implementation: |
62 void OnFileCanReadWithoutBlocking(int fd) override; | 63 void OnFileCanReadWithoutBlocking(int fd) override; |
63 void OnFileCanWriteWithoutBlocking(int fd) override; | 64 void OnFileCanWriteWithoutBlocking(int fd) override; |
64 | 65 |
65 // Implements most of |Read()| (except for a bit of clean-up): | 66 // Implements most of |Read()| (except for a bit of clean-up): |
66 IOResult ReadImpl(size_t* bytes_read); | 67 IOResult ReadImpl(size_t* bytes_read); |
67 | 68 |
68 // Watches for |fd_| to become writable. Must be called on the I/O thread. | 69 // Watches for |fd_| to become writable. Must be called on the I/O thread. |
69 void WaitToWrite(); | 70 void WaitToWrite(); |
70 | 71 |
71 embedder::ScopedPlatformHandle fd_; | 72 ScopedPlatformHandle fd_; |
72 | 73 |
73 // The following members are only used on the I/O thread: | 74 // The following members are only used on the I/O thread: |
74 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> read_watcher_; | 75 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> read_watcher_; |
75 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> write_watcher_; | 76 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> write_watcher_; |
76 | 77 |
77 bool pending_read_; | 78 bool pending_read_; |
78 | 79 |
79 std::deque<embedder::PlatformHandle> read_platform_handles_; | 80 std::deque<PlatformHandle> read_platform_handles_; |
80 | 81 |
81 // The following members are used on multiple threads and protected by | 82 // The following members are used on multiple threads and protected by |
82 // |write_lock()|: | 83 // |write_lock()|: |
83 bool pending_write_; | 84 bool pending_write_; |
84 | 85 |
85 // This is used for posting tasks from write threads to the I/O thread. It | 86 // This is used for posting tasks from write threads to the I/O thread. It |
86 // must only be accessed under |write_lock_|. The weak pointers it produces | 87 // must only be accessed under |write_lock_|. The weak pointers it produces |
87 // are only used/invalidated on the I/O thread. | 88 // are only used/invalidated on the I/O thread. |
88 base::WeakPtrFactory<RawChannelPosix> weak_ptr_factory_; | 89 base::WeakPtrFactory<RawChannelPosix> weak_ptr_factory_; |
89 | 90 |
90 MOJO_DISALLOW_COPY_AND_ASSIGN(RawChannelPosix); | 91 MOJO_DISALLOW_COPY_AND_ASSIGN(RawChannelPosix); |
91 }; | 92 }; |
92 | 93 |
93 RawChannelPosix::RawChannelPosix(embedder::ScopedPlatformHandle handle) | 94 RawChannelPosix::RawChannelPosix(ScopedPlatformHandle handle) |
94 : fd_(handle.Pass()), | 95 : fd_(handle.Pass()), |
95 pending_read_(false), | 96 pending_read_(false), |
96 pending_write_(false), | 97 pending_write_(false), |
97 weak_ptr_factory_(this) { | 98 weak_ptr_factory_(this) { |
98 DCHECK(fd_.is_valid()); | 99 DCHECK(fd_.is_valid()); |
99 } | 100 } |
100 | 101 |
101 RawChannelPosix::~RawChannelPosix() { | 102 RawChannelPosix::~RawChannelPosix() { |
102 DCHECK(!pending_read_); | 103 DCHECK(!pending_read_); |
103 DCHECK(!pending_write_); | 104 DCHECK(!pending_write_); |
104 | 105 |
105 // No need to take the |write_lock()| here -- if there are still weak pointers | 106 // No need to take the |write_lock()| here -- if there are still weak pointers |
106 // outstanding, then we're hosed anyway (since we wouldn't be able to | 107 // outstanding, then we're hosed anyway (since we wouldn't be able to |
107 // invalidate them cleanly, since we might not be on the I/O thread). | 108 // invalidate them cleanly, since we might not be on the I/O thread). |
108 DCHECK(!weak_ptr_factory_.HasWeakPtrs()); | 109 DCHECK(!weak_ptr_factory_.HasWeakPtrs()); |
109 | 110 |
110 // These must have been shut down/destroyed on the I/O thread. | 111 // These must have been shut down/destroyed on the I/O thread. |
111 DCHECK(!read_watcher_); | 112 DCHECK(!read_watcher_); |
112 DCHECK(!write_watcher_); | 113 DCHECK(!write_watcher_); |
113 | 114 |
114 embedder::CloseAllPlatformHandles(&read_platform_handles_); | 115 CloseAllPlatformHandles(&read_platform_handles_); |
115 } | |
116 | |
117 size_t RawChannelPosix::GetSerializedPlatformHandleSize() const { | |
118 // We don't actually need any space on POSIX (since we just send FDs). | |
119 return 0; | |
120 } | 116 } |
121 | 117 |
122 void RawChannelPosix::EnqueueMessageNoLock( | 118 void RawChannelPosix::EnqueueMessageNoLock( |
123 scoped_ptr<MessageInTransit> message) { | 119 scoped_ptr<MessageInTransit> message) { |
124 if (message->transport_data()) { | 120 if (message->transport_data()) { |
125 embedder::PlatformHandleVector* const platform_handles = | 121 PlatformHandleVector* const platform_handles = |
126 message->transport_data()->platform_handles(); | 122 message->transport_data()->platform_handles(); |
127 if (platform_handles && | 123 if (platform_handles && |
128 platform_handles->size() > embedder::kPlatformChannelMaxNumHandles) { | 124 platform_handles->size() > kPlatformChannelMaxNumHandles) { |
129 // We can't attach all the FDs to a single message, so we have to "split" | 125 // 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 | 126 // the message. Send as many control messages as needed first with FDs |
131 // attached (and no data). | 127 // attached (and no data). |
132 size_t i = 0; | 128 size_t i = 0; |
133 for (; platform_handles->size() - i > | 129 for (; platform_handles->size() - i > kPlatformChannelMaxNumHandles; |
134 embedder::kPlatformChannelMaxNumHandles; | 130 i += kPlatformChannelMaxNumHandles) { |
135 i += embedder::kPlatformChannelMaxNumHandles) { | |
136 scoped_ptr<MessageInTransit> fd_message(new MessageInTransit( | 131 scoped_ptr<MessageInTransit> fd_message(new MessageInTransit( |
137 MessageInTransit::Type::RAW_CHANNEL, | 132 MessageInTransit::Type::RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES, 0, |
138 MessageInTransit::Subtype::RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES, | 133 nullptr)); |
139 0, nullptr)); | 134 ScopedPlatformHandleVectorPtr fds( |
140 embedder::ScopedPlatformHandleVectorPtr fds( | 135 new PlatformHandleVector( |
141 new embedder::PlatformHandleVector( | |
142 platform_handles->begin() + i, | 136 platform_handles->begin() + i, |
143 platform_handles->begin() + i + | 137 platform_handles->begin() + i + kPlatformChannelMaxNumHandles)); |
144 embedder::kPlatformChannelMaxNumHandles)); | |
145 fd_message->SetTransportData(make_scoped_ptr( | 138 fd_message->SetTransportData(make_scoped_ptr( |
146 new TransportData(fds.Pass(), GetSerializedPlatformHandleSize()))); | 139 new TransportData(fds.Pass(), GetSerializedPlatformHandleSize()))); |
147 RawChannel::EnqueueMessageNoLock(fd_message.Pass()); | 140 RawChannel::EnqueueMessageNoLock(fd_message.Pass()); |
148 } | 141 } |
149 | 142 |
150 // Remove the handles that we "moved" into the other messages. | 143 // Remove the handles that we "moved" into the other messages. |
151 platform_handles->erase(platform_handles->begin(), | 144 platform_handles->erase(platform_handles->begin(), |
152 platform_handles->begin() + i); | 145 platform_handles->begin() + i); |
153 } | 146 } |
154 } | 147 } |
155 | 148 |
156 RawChannel::EnqueueMessageNoLock(message.Pass()); | 149 RawChannel::EnqueueMessageNoLock(message.Pass()); |
157 } | 150 } |
158 | 151 |
159 bool RawChannelPosix::OnReadMessageForRawChannel( | 152 bool RawChannelPosix::OnReadMessageForRawChannel( |
160 const MessageInTransit::View& message_view) { | 153 const MessageInTransit::View& message_view) { |
161 DCHECK_EQ(message_view.type(), MessageInTransit::Type::RAW_CHANNEL); | 154 if (message_view.type() == |
162 | 155 MessageInTransit::Type::RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES) { |
163 if (message_view.subtype() == | |
164 MessageInTransit::Subtype::RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES) { | |
165 // We don't need to do anything. |RawChannel| won't extract the platform | 156 // We don't need to do anything. |RawChannel| won't extract the platform |
166 // handles, and they'll be accumulated in |Read()|. | 157 // handles, and they'll be accumulated in |Read()|. |
167 return true; | 158 return true; |
168 } | 159 } |
169 | 160 |
170 return RawChannel::OnReadMessageForRawChannel(message_view); | 161 return RawChannel::OnReadMessageForRawChannel(message_view); |
171 } | 162 } |
172 | 163 |
164 | |
165 ScopedPlatformHandle RawChannelPosix::ReleaseHandleNoLock( | |
166 std::vector<char>* read_buffer_out) { | |
167 std::vector<WriteBuffer::Buffer> buffers; | |
168 write_buffer_no_lock()->GetBuffers(&buffers); | |
169 if (!buffers.empty()) { | |
170 // TODO(jam): copy code in OnShutdownNoLock | |
171 NOTREACHED() << "releasing handle with pending write buffer"; | |
172 } | |
173 | |
174 NOTREACHED() << "TODO(jam) IMPLEMENT";/* | |
175 if (handle_.is_valid()) { | |
176 // SetInitialBuffer could have been called on main thread before OnInit | |
177 // is called on Io thread. and in meantime releasehandle called. | |
178 //DCHECK(read_buffer()->num_valid_bytes() == 0); | |
179 if (read_buffer()->num_valid_bytes()) { | |
180 read_buffer_out->resize(read_buffer()->num_valid_bytes()); | |
181 memcpy(&(*read_buffer_out)[0], read_buffer()->buffer(), | |
182 read_buffer()->num_valid_bytes()); | |
183 read_buffer()->Reset(); | |
184 } | |
185 DCHECK(write_buffer_no_lock()->queue_size() == 0); | |
186 return ScopedPlatformHandle(PlatformHandle(handle_.release().handle)); | |
187 } | |
188 | |
189 return io_handler_->ReleaseHandle(read_buffer_out); | |
190 */ | |
191 return fd_.Pass(); | |
192 } | |
193 | |
194 PlatformHandle RawChannelPosix::HandleForDebuggingNoLock() { | |
195 return fd_.get(); | |
196 } | |
197 | |
173 RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) { | 198 RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) { |
174 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 199 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
175 DCHECK(!pending_read_); | 200 DCHECK(!pending_read_); |
176 | 201 |
177 IOResult rv = ReadImpl(bytes_read); | 202 IOResult rv = ReadImpl(bytes_read); |
178 if (rv != IO_SUCCEEDED && rv != IO_PENDING) { | 203 if (rv != IO_SUCCEEDED && rv != IO_PENDING) { |
179 // Make sure that |OnFileCanReadWithoutBlocking()| won't be called again. | 204 // Make sure that |OnFileCanReadWithoutBlocking()| won't be called again. |
180 read_watcher_.reset(); | 205 read_watcher_.reset(); |
181 } | 206 } |
182 return rv; | 207 return rv; |
183 } | 208 } |
184 | 209 |
185 RawChannel::IOResult RawChannelPosix::ScheduleRead() { | 210 RawChannel::IOResult RawChannelPosix::ScheduleRead() { |
186 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 211 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
187 DCHECK(!pending_read_); | 212 DCHECK(!pending_read_); |
188 | 213 |
189 pending_read_ = true; | 214 pending_read_ = true; |
190 | 215 |
191 return IO_PENDING; | 216 return IO_PENDING; |
192 } | 217 } |
193 | 218 |
194 embedder::ScopedPlatformHandleVectorPtr RawChannelPosix::GetReadPlatformHandles( | 219 ScopedPlatformHandleVectorPtr RawChannelPosix::GetReadPlatformHandles( |
195 size_t num_platform_handles, | 220 size_t num_platform_handles, |
196 const void* /*platform_handle_table*/) { | 221 const void* /*platform_handle_table*/) { |
197 DCHECK_GT(num_platform_handles, 0u); | 222 DCHECK_GT(num_platform_handles, 0u); |
198 | 223 |
199 if (read_platform_handles_.size() < num_platform_handles) { | 224 if (read_platform_handles_.size() < num_platform_handles) { |
200 embedder::CloseAllPlatformHandles(&read_platform_handles_); | 225 CloseAllPlatformHandles(&read_platform_handles_); |
201 read_platform_handles_.clear(); | 226 read_platform_handles_.clear(); |
202 return embedder::ScopedPlatformHandleVectorPtr(); | 227 return ScopedPlatformHandleVectorPtr(); |
203 } | 228 } |
204 | 229 |
205 embedder::ScopedPlatformHandleVectorPtr rv( | 230 ScopedPlatformHandleVectorPtr rv( |
206 new embedder::PlatformHandleVector(num_platform_handles)); | 231 new PlatformHandleVector(num_platform_handles)); |
207 rv->assign(read_platform_handles_.begin(), | 232 rv->assign(read_platform_handles_.begin(), |
208 read_platform_handles_.begin() + num_platform_handles); | 233 read_platform_handles_.begin() + num_platform_handles); |
209 read_platform_handles_.erase( | 234 read_platform_handles_.erase( |
210 read_platform_handles_.begin(), | 235 read_platform_handles_.begin(), |
211 read_platform_handles_.begin() + num_platform_handles); | 236 read_platform_handles_.begin() + num_platform_handles); |
212 return rv.Pass(); | 237 return rv.Pass(); |
213 } | 238 } |
214 | 239 |
215 RawChannel::IOResult RawChannelPosix::WriteNoLock( | 240 RawChannel::IOResult RawChannelPosix::WriteNoLock( |
216 size_t* platform_handles_written, | 241 size_t* platform_handles_written, |
217 size_t* bytes_written) { | 242 size_t* bytes_written) { |
218 write_lock().AssertAcquired(); | 243 write_lock().AssertAcquired(); |
219 | 244 |
220 DCHECK(!pending_write_); | 245 DCHECK(!pending_write_); |
221 | 246 |
222 size_t num_platform_handles = 0; | 247 size_t num_platform_handles = 0; |
223 ssize_t write_result; | 248 ssize_t write_result; |
224 if (write_buffer_no_lock()->HavePlatformHandlesToSend()) { | 249 if (write_buffer_no_lock()->HavePlatformHandlesToSend()) { |
225 embedder::PlatformHandle* platform_handles; | 250 PlatformHandle* platform_handles; |
226 void* serialization_data; // Actually unused. | 251 void* serialization_data; // Actually unused. |
227 write_buffer_no_lock()->GetPlatformHandlesToSend( | 252 write_buffer_no_lock()->GetPlatformHandlesToSend( |
228 &num_platform_handles, &platform_handles, &serialization_data); | 253 &num_platform_handles, &platform_handles, &serialization_data); |
229 DCHECK_GT(num_platform_handles, 0u); | 254 DCHECK_GT(num_platform_handles, 0u); |
230 DCHECK_LE(num_platform_handles, embedder::kPlatformChannelMaxNumHandles); | 255 DCHECK_LE(num_platform_handles, kPlatformChannelMaxNumHandles); |
231 DCHECK(platform_handles); | 256 DCHECK(platform_handles); |
232 | 257 |
233 // TODO(vtl): Reduce code duplication. (This is duplicated from below.) | 258 // TODO(vtl): Reduce code duplication. (This is duplicated from below.) |
234 std::vector<WriteBuffer::Buffer> buffers; | 259 std::vector<WriteBuffer::Buffer> buffers; |
235 write_buffer_no_lock()->GetBuffers(&buffers); | 260 write_buffer_no_lock()->GetBuffers(&buffers); |
236 DCHECK(!buffers.empty()); | 261 DCHECK(!buffers.empty()); |
237 const size_t kMaxBufferCount = 10; | 262 const size_t kMaxBufferCount = 10; |
238 iovec iov[kMaxBufferCount]; | 263 iovec iov[kMaxBufferCount]; |
239 size_t buffer_count = std::min(buffers.size(), kMaxBufferCount); | 264 size_t buffer_count = std::min(buffers.size(), kMaxBufferCount); |
240 for (size_t i = 0; i < buffer_count; ++i) { | 265 for (size_t i = 0; i < buffer_count; ++i) { |
241 iov[i].iov_base = const_cast<char*>(buffers[i].addr); | 266 iov[i].iov_base = const_cast<char*>(buffers[i].addr); |
242 iov[i].iov_len = buffers[i].size; | 267 iov[i].iov_len = buffers[i].size; |
243 } | 268 } |
244 | 269 |
245 write_result = embedder::PlatformChannelSendmsgWithHandles( | 270 write_result = PlatformChannelSendmsgWithHandles( |
246 fd_.get(), iov, buffer_count, platform_handles, num_platform_handles); | 271 fd_.get(), iov, buffer_count, platform_handles, num_platform_handles); |
247 if (write_result >= 0) { | 272 if (write_result >= 0) { |
248 for (size_t i = 0; i < num_platform_handles; i++) | 273 for (size_t i = 0; i < num_platform_handles; i++) |
249 platform_handles[i].CloseIfNecessary(); | 274 platform_handles[i].CloseIfNecessary(); |
250 } | 275 } |
251 } else { | 276 } else { |
252 std::vector<WriteBuffer::Buffer> buffers; | 277 std::vector<WriteBuffer::Buffer> buffers; |
253 write_buffer_no_lock()->GetBuffers(&buffers); | 278 write_buffer_no_lock()->GetBuffers(&buffers); |
254 DCHECK(!buffers.empty()); | 279 DCHECK(!buffers.empty()); |
255 | 280 |
256 if (buffers.size() == 1) { | 281 if (buffers.size() == 1) { |
257 write_result = embedder::PlatformChannelWrite(fd_.get(), buffers[0].addr, | 282 write_result = PlatformChannelWrite(fd_.get(), buffers[0].addr, |
258 buffers[0].size); | 283 buffers[0].size); |
259 } else { | 284 } else { |
260 const size_t kMaxBufferCount = 10; | 285 const size_t kMaxBufferCount = 10; |
261 iovec iov[kMaxBufferCount]; | 286 iovec iov[kMaxBufferCount]; |
262 size_t buffer_count = std::min(buffers.size(), kMaxBufferCount); | 287 size_t buffer_count = std::min(buffers.size(), kMaxBufferCount); |
263 for (size_t i = 0; i < buffer_count; ++i) { | 288 for (size_t i = 0; i < buffer_count; ++i) { |
264 iov[i].iov_base = const_cast<char*>(buffers[i].addr); | 289 iov[i].iov_base = const_cast<char*>(buffers[i].addr); |
265 iov[i].iov_len = buffers[i].size; | 290 iov[i].iov_len = buffers[i].size; |
266 } | 291 } |
267 | 292 |
268 write_result = | 293 write_result = PlatformChannelWritev(fd_.get(), iov, buffer_count); |
269 embedder::PlatformChannelWritev(fd_.get(), iov, buffer_count); | |
270 } | 294 } |
271 } | 295 } |
272 | 296 |
273 if (write_result >= 0) { | 297 if (write_result >= 0) { |
274 *platform_handles_written = num_platform_handles; | 298 *platform_handles_written = num_platform_handles; |
275 *bytes_written = static_cast<size_t>(write_result); | 299 *bytes_written = static_cast<size_t>(write_result); |
276 return IO_SUCCEEDED; | 300 return IO_SUCCEEDED; |
277 } | 301 } |
278 | 302 |
279 if (errno == EPIPE) | 303 if (errno == EPIPE) |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 return; // |this| may have been destroyed in |OnWriteCompleted()|. | 422 return; // |this| may have been destroyed in |OnWriteCompleted()|. |
399 } | 423 } |
400 } | 424 } |
401 | 425 |
402 RawChannel::IOResult RawChannelPosix::ReadImpl(size_t* bytes_read) { | 426 RawChannel::IOResult RawChannelPosix::ReadImpl(size_t* bytes_read) { |
403 char* buffer = nullptr; | 427 char* buffer = nullptr; |
404 size_t bytes_to_read = 0; | 428 size_t bytes_to_read = 0; |
405 read_buffer()->GetBuffer(&buffer, &bytes_to_read); | 429 read_buffer()->GetBuffer(&buffer, &bytes_to_read); |
406 | 430 |
407 size_t old_num_platform_handles = read_platform_handles_.size(); | 431 size_t old_num_platform_handles = read_platform_handles_.size(); |
408 ssize_t read_result = embedder::PlatformChannelRecvmsg( | 432 ssize_t read_result = PlatformChannelRecvmsg( |
409 fd_.get(), buffer, bytes_to_read, &read_platform_handles_); | 433 fd_.get(), buffer, bytes_to_read, &read_platform_handles_); |
410 if (read_platform_handles_.size() > old_num_platform_handles) { | 434 if (read_platform_handles_.size() > old_num_platform_handles) { |
411 DCHECK_LE(read_platform_handles_.size() - old_num_platform_handles, | 435 DCHECK_LE(read_platform_handles_.size() - old_num_platform_handles, |
412 embedder::kPlatformChannelMaxNumHandles); | 436 kPlatformChannelMaxNumHandles); |
413 | 437 |
414 // We should never accumulate more than |TransportData::kMaxPlatformHandles | 438 // We should never accumulate more than |TransportData::kMaxPlatformHandles |
415 // + embedder::kPlatformChannelMaxNumHandles| handles. (The latter part is | 439 // + kPlatformChannelMaxNumHandles| handles. (The latter part is |
416 // possible because we could have accumulated all the handles for a message, | 440 // possible because we could have accumulated all the handles for a message, |
417 // then received the message data plus the first set of handles for the next | 441 // then received the message data plus the first set of handles for the next |
418 // message in the subsequent |recvmsg()|.) | 442 // message in the subsequent |recvmsg()|.) |
419 if (read_platform_handles_.size() > | 443 if (read_platform_handles_.size() > |
420 (TransportData::GetMaxPlatformHandles() + | 444 (TransportData::GetMaxPlatformHandles() + |
421 embedder::kPlatformChannelMaxNumHandles)) { | 445 kPlatformChannelMaxNumHandles)) { |
422 LOG(ERROR) << "Received too many platform handles"; | 446 LOG(ERROR) << "Received too many platform handles"; |
423 embedder::CloseAllPlatformHandles(&read_platform_handles_); | 447 CloseAllPlatformHandles(&read_platform_handles_); |
424 read_platform_handles_.clear(); | 448 read_platform_handles_.clear(); |
425 return IO_FAILED_UNKNOWN; | 449 return IO_FAILED_UNKNOWN; |
426 } | 450 } |
427 } | 451 } |
428 | 452 |
429 if (read_result > 0) { | 453 if (read_result > 0) { |
430 *bytes_read = static_cast<size_t>(read_result); | 454 *bytes_read = static_cast<size_t>(read_result); |
431 return IO_SUCCEEDED; | 455 return IO_SUCCEEDED; |
432 } | 456 } |
433 | 457 |
(...skipping 29 matching lines...) Expand all Loading... | |
463 return; // |this| may have been destroyed in |OnWriteCompleted()|. | 487 return; // |this| may have been destroyed in |OnWriteCompleted()|. |
464 } | 488 } |
465 } | 489 } |
466 | 490 |
467 } // namespace | 491 } // namespace |
468 | 492 |
469 // ----------------------------------------------------------------------------- | 493 // ----------------------------------------------------------------------------- |
470 | 494 |
471 // Static factory method declared in raw_channel.h. | 495 // Static factory method declared in raw_channel.h. |
472 // static | 496 // static |
473 scoped_ptr<RawChannel> RawChannel::Create( | 497 RawChannel* RawChannel::Create(ScopedPlatformHandle handle) { |
474 embedder::ScopedPlatformHandle handle) { | 498 return new RawChannelPosix(handle.Pass()); |
475 return make_scoped_ptr(new RawChannelPosix(handle.Pass())); | |
476 } | 499 } |
477 | 500 |
478 } // namespace system | 501 size_t RawChannel::GetSerializedPlatformHandleSize() { |
502 // We don't actually need any space on POSIX (since we just send FDs). | |
503 return 0; | |
504 } | |
505 | |
506 bool RawChannel::IsOtherEndOf(RawChannel* other) { | |
507 PlatformHandle this_handle = HandleForDebuggingNoLock(); | |
508 PlatformHandle other_handle = other->HandleForDebuggingNoLock(); | |
509 | |
510 stat stat1, stat2; | |
Ken Rockot(use gerrit already)
2015/09/23 22:32:17
need struct tag for stat type here
| |
511 if (fstat(this_handle.fd, &stat1) < 0) | |
512 return false; | |
513 if (fstat(other_handle.fd, &stat2) < 0) | |
514 return false; | |
515 return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino); | |
516 } | |
517 | |
518 } // namespace edk | |
479 } // namespace mojo | 519 } // namespace mojo |
OLD | NEW |