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 17 matching lines...) Expand all Loading... |
28 namespace system { | 28 namespace system { |
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(embedder::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 embedder::ScopedPlatformHandle ReleaseHandleNoLock( |
| 48 std::vector<char>* read_buffer_out) override; |
| 49 embedder::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 embedder::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, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 embedder::CloseAllPlatformHandles(&read_platform_handles_); |
115 } | 116 } |
116 | 117 |
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 } | |
121 | |
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 embedder::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() > embedder::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 > |
134 embedder::kPlatformChannelMaxNumHandles; | 130 embedder::kPlatformChannelMaxNumHandles; |
135 i += embedder::kPlatformChannelMaxNumHandles) { | 131 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)); | |
140 embedder::ScopedPlatformHandleVectorPtr fds( | 135 embedder::ScopedPlatformHandleVectorPtr fds( |
141 new embedder::PlatformHandleVector( | 136 new embedder::PlatformHandleVector( |
142 platform_handles->begin() + i, | 137 platform_handles->begin() + i, |
143 platform_handles->begin() + i + | 138 platform_handles->begin() + i + |
144 embedder::kPlatformChannelMaxNumHandles)); | 139 embedder::kPlatformChannelMaxNumHandles)); |
145 fd_message->SetTransportData(make_scoped_ptr( | 140 fd_message->SetTransportData(make_scoped_ptr( |
146 new TransportData(fds.Pass(), GetSerializedPlatformHandleSize()))); | 141 new TransportData(fds.Pass(), GetSerializedPlatformHandleSize()))); |
147 RawChannel::EnqueueMessageNoLock(fd_message.Pass()); | 142 RawChannel::EnqueueMessageNoLock(fd_message.Pass()); |
148 } | 143 } |
149 | 144 |
150 // Remove the handles that we "moved" into the other messages. | 145 // Remove the handles that we "moved" into the other messages. |
151 platform_handles->erase(platform_handles->begin(), | 146 platform_handles->erase(platform_handles->begin(), |
152 platform_handles->begin() + i); | 147 platform_handles->begin() + i); |
153 } | 148 } |
154 } | 149 } |
155 | 150 |
156 RawChannel::EnqueueMessageNoLock(message.Pass()); | 151 RawChannel::EnqueueMessageNoLock(message.Pass()); |
157 } | 152 } |
158 | 153 |
159 bool RawChannelPosix::OnReadMessageForRawChannel( | 154 bool RawChannelPosix::OnReadMessageForRawChannel( |
160 const MessageInTransit::View& message_view) { | 155 const MessageInTransit::View& message_view) { |
161 DCHECK_EQ(message_view.type(), MessageInTransit::Type::RAW_CHANNEL); | 156 if (message_view.type() == |
162 | 157 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 | 158 // We don't need to do anything. |RawChannel| won't extract the platform |
166 // handles, and they'll be accumulated in |Read()|. | 159 // handles, and they'll be accumulated in |Read()|. |
167 return true; | 160 return true; |
168 } | 161 } |
169 | 162 |
170 return RawChannel::OnReadMessageForRawChannel(message_view); | 163 return RawChannel::OnReadMessageForRawChannel(message_view); |
171 } | 164 } |
172 | 165 |
| 166 |
| 167 embedder::ScopedPlatformHandle RawChannelPosix::ReleaseHandleNoLock( |
| 168 std::vector<char>* read_buffer_out) { |
| 169 std::vector<WriteBuffer::Buffer> buffers; |
| 170 write_buffer_no_lock()->GetBuffers(&buffers); |
| 171 if (!buffers.empty()) { |
| 172 // TODO(jam): copy code in OnShutdownNoLock |
| 173 NOTREACHED() << "releasing handle with pending write buffer"; |
| 174 } |
| 175 |
| 176 NOTREACHED() << "TODO(jam) IMPLEMENT";/* |
| 177 if (handle_.is_valid()) { |
| 178 // SetInitialBuffer could have been called on main thread before OnInit |
| 179 // is called on Io thread. and in meantime releasehandle called. |
| 180 //DCHECK(read_buffer()->num_valid_bytes() == 0); |
| 181 if (read_buffer()->num_valid_bytes()) { |
| 182 read_buffer_out->resize(read_buffer()->num_valid_bytes()); |
| 183 memcpy(&(*read_buffer_out)[0], read_buffer()->buffer(), |
| 184 read_buffer()->num_valid_bytes()); |
| 185 read_buffer()->Reset(); |
| 186 } |
| 187 DCHECK(write_buffer_no_lock()->queue_size() == 0); |
| 188 return embedder::ScopedPlatformHandle( |
| 189 embedder::PlatformHandle(handle_.release().handle)); |
| 190 } |
| 191 |
| 192 return io_handler_->ReleaseHandle(read_buffer_out); |
| 193 */ |
| 194 return fd_.Pass(); |
| 195 } |
| 196 |
| 197 embedder::PlatformHandle RawChannelPosix::HandleForDebuggingNoLock() { |
| 198 return fd_.get(); |
| 199 } |
| 200 |
173 RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) { | 201 RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) { |
174 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 202 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
175 DCHECK(!pending_read_); | 203 DCHECK(!pending_read_); |
176 | 204 |
177 IOResult rv = ReadImpl(bytes_read); | 205 IOResult rv = ReadImpl(bytes_read); |
178 if (rv != IO_SUCCEEDED && rv != IO_PENDING) { | 206 if (rv != IO_SUCCEEDED && rv != IO_PENDING) { |
179 // Make sure that |OnFileCanReadWithoutBlocking()| won't be called again. | 207 // Make sure that |OnFileCanReadWithoutBlocking()| won't be called again. |
180 read_watcher_.reset(); | 208 read_watcher_.reset(); |
181 } | 209 } |
182 return rv; | 210 return rv; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 return; // |this| may have been destroyed in |OnWriteCompleted()|. | 491 return; // |this| may have been destroyed in |OnWriteCompleted()|. |
464 } | 492 } |
465 } | 493 } |
466 | 494 |
467 } // namespace | 495 } // namespace |
468 | 496 |
469 // ----------------------------------------------------------------------------- | 497 // ----------------------------------------------------------------------------- |
470 | 498 |
471 // Static factory method declared in raw_channel.h. | 499 // Static factory method declared in raw_channel.h. |
472 // static | 500 // static |
473 scoped_ptr<RawChannel> RawChannel::Create( | 501 RawChannel* RawChannel::Create(embedder::ScopedPlatformHandle handle) { |
474 embedder::ScopedPlatformHandle handle) { | 502 return new RawChannelPosix(handle.Pass()); |
475 return make_scoped_ptr(new RawChannelPosix(handle.Pass())); | 503 } |
| 504 |
| 505 size_t RawChannel::GetSerializedPlatformHandleSize() { |
| 506 // We don't actually need any space on POSIX (since we just send FDs). |
| 507 return 0; |
476 } | 508 } |
477 | 509 |
478 } // namespace system | 510 } // namespace system |
479 } // namespace mojo | 511 } // namespace mojo |
OLD | NEW |