diff options
-rw-r--r-- | mojo/embedder/platform_channel_pair_posix_unittest.cc | 39 | ||||
-rw-r--r-- | mojo/embedder/platform_channel_utils_posix.cc | 10 | ||||
-rw-r--r-- | mojo/embedder/platform_channel_utils_posix.h | 10 | ||||
-rw-r--r-- | mojo/embedder/platform_handle_utils.h | 27 | ||||
-rw-r--r-- | mojo/embedder/platform_handle_vector.cc | 18 | ||||
-rw-r--r-- | mojo/embedder/platform_handle_vector.h | 6 | ||||
-rw-r--r-- | mojo/mojo.gyp | 2 | ||||
-rw-r--r-- | mojo/system/raw_channel_posix.cc | 40 |
8 files changed, 87 insertions, 65 deletions
diff --git a/mojo/embedder/platform_channel_pair_posix_unittest.cc b/mojo/embedder/platform_channel_pair_posix_unittest.cc index 8f57c5c..97f5deb 100644 --- a/mojo/embedder/platform_channel_pair_posix_unittest.cc +++ b/mojo/embedder/platform_channel_pair_posix_unittest.cc @@ -13,7 +13,7 @@ #include <sys/uio.h> #include <unistd.h> -#include <vector> +#include <deque> #include "base/file_util.h" #include "base/files/file_path.h" @@ -22,6 +22,8 @@ #include "base/macros.h" #include "mojo/common/test/test_utils.h" #include "mojo/embedder/platform_channel_utils_posix.h" +#include "mojo/embedder/platform_handle.h" +#include "mojo/embedder/platform_handle_vector.h" #include "mojo/embedder/scoped_platform_handle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -117,12 +119,12 @@ TEST_F(PlatformChannelPairPosixTest, SendReceiveData) { WaitReadable(client_handle.get()); char buf[10000] = {}; - ScopedPlatformHandleVectorPtr received_handles; + std::deque<PlatformHandle> received_handles; ssize_t result = PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), &received_handles); EXPECT_EQ(static_cast<ssize_t>(send_string.size()), result); EXPECT_EQ(send_string, std::string(buf, static_cast<size_t>(result))); - EXPECT_FALSE(received_handles); + EXPECT_TRUE(received_handles.empty()); } } @@ -152,17 +154,17 @@ TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { WaitReadable(client_handle.get()); char buf[100] = { 'a' }; - ScopedPlatformHandleVectorPtr received_handles; + std::deque<PlatformHandle> received_handles; EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), &received_handles)); EXPECT_EQ('\0', buf[0]); - ASSERT_TRUE(received_handles); - EXPECT_EQ(i, received_handles->size()); + ASSERT_FALSE(received_handles.empty()); + EXPECT_EQ(i, received_handles.size()); - for (size_t j = 0; j < received_handles->size(); j++) { + for (size_t j = 0; !received_handles.empty(); j++) { base::ScopedFILE fp(test::FILEFromPlatformHandle( - ScopedPlatformHandle((*received_handles)[j]), "rb")); - (*received_handles)[j] = PlatformHandle(); + ScopedPlatformHandle(received_handles.front()), "rb")); + received_handles.pop_front(); ASSERT_TRUE(fp); rewind(fp.get()); char read_buf[100]; @@ -198,23 +200,22 @@ TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) { WaitReadable(client_handle.get()); - // Start with an invalid handle in the vector. - ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector()); - handles->push_back(PlatformHandle()); + // Start with an invalid handle in the deque. + std::deque<PlatformHandle> received_handles; + received_handles.push_back(PlatformHandle()); char buf[100] = { 'a' }; EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), - &handles)); + &received_handles)); EXPECT_EQ('\0', buf[0]); - ASSERT_TRUE(handles); - ASSERT_EQ(2u, handles->size()); - EXPECT_FALSE((*handles)[0].is_valid()); - EXPECT_TRUE((*handles)[1].is_valid()); + ASSERT_EQ(2u, received_handles.size()); + EXPECT_FALSE(received_handles[0].is_valid()); + EXPECT_TRUE(received_handles[1].is_valid()); { base::ScopedFILE fp(test::FILEFromPlatformHandle( - ScopedPlatformHandle((*handles)[1]), "rb")); - (*handles)[1] = PlatformHandle(); + ScopedPlatformHandle(received_handles[1]), "rb")); + received_handles[1] = PlatformHandle(); ASSERT_TRUE(fp); rewind(fp.get()); char read_buf[100]; diff --git a/mojo/embedder/platform_channel_utils_posix.cc b/mojo/embedder/platform_channel_utils_posix.cc index ec5ef59..7dba371 100644 --- a/mojo/embedder/platform_channel_utils_posix.cc +++ b/mojo/embedder/platform_channel_utils_posix.cc @@ -105,10 +105,10 @@ bool PlatformChannelSendHandles(PlatformHandle h, ssize_t PlatformChannelRecvmsg(PlatformHandle h, void* buf, size_t num_bytes, - ScopedPlatformHandleVectorPtr* handles) { + std::deque<PlatformHandle>* platform_handles) { DCHECK(buf); DCHECK_GT(num_bytes, 0u); - DCHECK(handles); + DCHECK(platform_handles); struct iovec iov = { buf, num_bytes }; char cmsg_buf[CMSG_SPACE(kPlatformChannelMaxNumHandles * sizeof(int))]; @@ -137,10 +137,8 @@ ssize_t PlatformChannelRecvmsg(PlatformHandle h, size_t num_fds = payload_length / sizeof(int); const int* fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); for (size_t i = 0; i < num_fds; i++) { - if (!*handles) - (*handles).reset(new PlatformHandleVector()); - (*handles)->push_back(PlatformHandle(fds[i])); - DCHECK((*handles)->back().is_valid()); + platform_handles->push_back(PlatformHandle(fds[i])); + DCHECK(platform_handles->back().is_valid()); } } } diff --git a/mojo/embedder/platform_channel_utils_posix.h b/mojo/embedder/platform_channel_utils_posix.h index 044199f..5146ce5 100644 --- a/mojo/embedder/platform_channel_utils_posix.h +++ b/mojo/embedder/platform_channel_utils_posix.h @@ -8,11 +8,10 @@ #include <stddef.h> #include <sys/types.h> // For |ssize_t|. -#include <vector> +#include <deque> #include "base/memory/scoped_ptr.h" #include "mojo/embedder/platform_handle.h" -#include "mojo/embedder/platform_handle_vector.h" #include "mojo/system/system_impl_export.h" struct iovec; // Declared in <sys/uio.h>. @@ -48,14 +47,13 @@ MOJO_SYSTEM_IMPL_EXPORT bool PlatformChannelSendHandles(PlatformHandle h, size_t num_handles); // Wrapper around |recvmsg()|, which will extract any attached file descriptors -// (in the control message) to |PlatformHandle|s. (This also handles |EINTR|.) -// If |*handles| is null and handles are received, a vector will be allocated; -// otherwise, any handles received will be appended to the existing vector. +// (in the control message) to |PlatformHandle|s (and append them to +// |platform_handles|). (This also handles |EINTR|.) MOJO_SYSTEM_IMPL_EXPORT ssize_t PlatformChannelRecvmsg( PlatformHandle h, void* buf, size_t num_bytes, - ScopedPlatformHandleVectorPtr* handles); + std::deque<PlatformHandle>* platform_handles); } // namespace embedder } // namespace mojo diff --git a/mojo/embedder/platform_handle_utils.h b/mojo/embedder/platform_handle_utils.h new file mode 100644 index 0000000..2cf280a --- /dev/null +++ b/mojo/embedder/platform_handle_utils.h @@ -0,0 +1,27 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_EMBEDDER_PLATFORM_HANDLE_UTILS_H_ +#define MOJO_EMBEDDER_PLATFORM_HANDLE_UTILS_H_ + +#include "mojo/embedder/platform_handle.h" +#include "mojo/system/system_impl_export.h" + +namespace mojo { +namespace embedder { + +template <typename PlatformHandleContainer> +MOJO_SYSTEM_IMPL_EXPORT inline void CloseAllPlatformHandles( + PlatformHandleContainer* platform_handles) { + for (typename PlatformHandleContainer::iterator it = + platform_handles->begin(); + it != platform_handles->end(); + ++it) + it->CloseIfNecessary(); +} + +} // namespace embedder +} // namespace mojo + +#endif // MOJO_EMBEDDER_PLATFORM_HANDLE_UTILS_H_ diff --git a/mojo/embedder/platform_handle_vector.cc b/mojo/embedder/platform_handle_vector.cc deleted file mode 100644 index 04a846f..0000000 --- a/mojo/embedder/platform_handle_vector.cc +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/embedder/platform_handle_vector.h" - -namespace mojo { -namespace embedder { - -void CloseAllHandles(PlatformHandleVector* platform_handles) { - for (PlatformHandleVector::iterator it = platform_handles->begin(); - it != platform_handles->end(); - ++it) - it->CloseIfNecessary(); -} - -} // namespace embedder -} // namespace mojo diff --git a/mojo/embedder/platform_handle_vector.h b/mojo/embedder/platform_handle_vector.h index b4ed930..db53419 100644 --- a/mojo/embedder/platform_handle_vector.h +++ b/mojo/embedder/platform_handle_vector.h @@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "mojo/embedder/platform_handle.h" +#include "mojo/embedder/platform_handle_utils.h" #include "mojo/system/system_impl_export.h" namespace mojo { @@ -16,14 +17,11 @@ namespace embedder { typedef std::vector<PlatformHandle> PlatformHandleVector; -MOJO_SYSTEM_IMPL_EXPORT void CloseAllHandles( - PlatformHandleVector* platform_handles); - // A deleter (for use with |scoped_ptr|) which closes all handles and then // |delete|s the |PlatformHandleVector|. struct MOJO_SYSTEM_IMPL_EXPORT PlatformHandleVectorDeleter { void operator()(PlatformHandleVector* platform_handles) const { - CloseAllHandles(platform_handles); + CloseAllPlatformHandles(platform_handles); delete platform_handles; } }; diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index 5c9198f..c9f74d8 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -152,7 +152,7 @@ 'embedder/platform_channel_utils_posix.h', 'embedder/platform_handle.cc', 'embedder/platform_handle.h', - 'embedder/platform_handle_vector.cc', + 'embedder/platform_handle_utils.h', 'embedder/platform_handle_vector.h', 'embedder/scoped_platform_handle.h', 'system/channel.cc', diff --git a/mojo/system/raw_channel_posix.cc b/mojo/system/raw_channel_posix.cc index d50ff8b..64f46c6 100644 --- a/mojo/system/raw_channel_posix.cc +++ b/mojo/system/raw_channel_posix.cc @@ -9,6 +9,7 @@ #include <unistd.h> #include <algorithm> +#include <deque> #include "base/basictypes.h" #include "base/bind.h" @@ -68,7 +69,7 @@ class RawChannelPosix : public RawChannel, bool pending_read_; - embedder::ScopedPlatformHandleVectorPtr read_platform_handles_; + std::deque<embedder::PlatformHandle> read_platform_handles_; // The following members are used on multiple threads and protected by // |write_lock()|: @@ -102,6 +103,8 @@ RawChannelPosix::~RawChannelPosix() { // These must have been shut down/destroyed on the I/O thread. DCHECK(!read_watcher_.get()); DCHECK(!write_watcher_.get()); + + embedder::CloseAllPlatformHandles(&read_platform_handles_); } size_t RawChannelPosix::GetSerializedPlatformHandleSize() const { @@ -117,23 +120,31 @@ RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) { size_t bytes_to_read = 0; read_buffer()->GetBuffer(&buffer, &bytes_to_read); - size_t old_num_platform_handles = - read_platform_handles_ ? read_platform_handles_->size() : 0; + size_t old_num_platform_handles = read_platform_handles_.size(); ssize_t read_result = embedder::PlatformChannelRecvmsg(fd_.get(), buffer, bytes_to_read, &read_platform_handles_); - if (read_platform_handles_ && - read_platform_handles_->size() > old_num_platform_handles) { + if (read_platform_handles_.size() > old_num_platform_handles) { + DCHECK_LE(read_platform_handles_.size() - old_num_platform_handles, + embedder::kPlatformChannelMaxNumHandles); + if (read_result != 1) { LOG(WARNING) << "Invalid control message with platform handles"; return IO_FAILED; } - if (read_platform_handles_->size() > TransportData::kMaxPlatformHandles) { + // We should never accumulate more than |TransportData::kMaxPlatformHandles + // + embedder::kPlatformChannelMaxNumHandles| handles. (The latter part is + // possible because we could have accumulated all the handles for a message, + // then received the message data plus the first set of handles for the next + // message in the subsequent |recvmsg()|.) + if (read_platform_handles_.size() > (TransportData::kMaxPlatformHandles + + embedder::kPlatformChannelMaxNumHandles)) { LOG(WARNING) << "Received too many platform handles"; - read_platform_handles_.reset(); + embedder::CloseAllPlatformHandles(&read_platform_handles_); + read_platform_handles_.clear(); return IO_FAILED; } @@ -173,13 +184,20 @@ embedder::ScopedPlatformHandleVectorPtr RawChannelPosix::GetReadPlatformHandles( const void* /*platform_handle_table*/) { DCHECK_GT(num_platform_handles, 0u); - if (!read_platform_handles_ || - read_platform_handles_->size() != num_platform_handles) { - read_platform_handles_.reset(); + if (read_platform_handles_.size() < num_platform_handles) { + embedder::CloseAllPlatformHandles(&read_platform_handles_); + read_platform_handles_.clear(); return embedder::ScopedPlatformHandleVectorPtr(); } - return read_platform_handles_.Pass(); + embedder::ScopedPlatformHandleVectorPtr rv( + new embedder::PlatformHandleVector(num_platform_handles)); + rv->assign(read_platform_handles_.begin(), + read_platform_handles_.begin() + num_platform_handles); + read_platform_handles_.erase( + read_platform_handles_.begin(), + read_platform_handles_.begin() + num_platform_handles); + return rv.Pass(); } RawChannel::IOResult RawChannelPosix::WriteNoLock( |