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