| 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 |