diff --git a/ipc/chromium/src/chrome/common/ipc_message.h b/ipc/chromium/src/chrome/common/ipc_message.h index 8c77d0d4e516..68781f978e08 100644 --- a/ipc/chromium/src/chrome/common/ipc_message.h +++ b/ipc/chromium/src/chrome/common/ipc_message.h @@ -93,9 +93,8 @@ class Message : public mojo::core::ports::UserMessage, public Pickle { REPLY = 1, }; - // Mac and Linux both limit the number of file descriptors per message to - // slightly more than 250. - enum { MAX_DESCRIPTORS_PER_MESSAGE = 200 }; + // The hard limit of handles or file descriptors allowed in a single message. + static constexpr size_t MAX_DESCRIPTORS_PER_MESSAGE = 32767; class HeaderFlags { friend class Message; diff --git a/ipc/ipdl/test/gtest/PTestManyHandles.ipdl b/ipc/ipdl/test/gtest/PTestManyHandles.ipdl new file mode 100644 index 000000000000..b1db633fdb10 --- /dev/null +++ b/ipc/ipdl/test/gtest/PTestManyHandles.ipdl @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +namespace mozilla { +namespace _ipdltest { + +[ParentImpl=virtual, ChildImpl=virtual] +async protocol PTestManyHandles { +child: + async ManyHandles(FileDescriptor[] descrs); +}; + +} // namespace _ipdltest +} // namespace mozilla diff --git a/ipc/ipdl/test/gtest/TestManyHandles.cpp b/ipc/ipdl/test/gtest/TestManyHandles.cpp new file mode 100644 index 000000000000..0e2da258c5ba --- /dev/null +++ b/ipc/ipdl/test/gtest/TestManyHandles.cpp @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include "mozilla/_ipdltest/IPDLUnitTest.h" +#include "mozilla/_ipdltest/PTestManyHandlesChild.h" +#include "mozilla/_ipdltest/PTestManyHandlesParent.h" + +using namespace mozilla::ipc; + +namespace mozilla::_ipdltest { + +class TestManyHandlesChild : public PTestManyHandlesChild { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestManyHandlesChild, override) + + public: + IPCResult RecvManyHandles(nsTArray&& aDescrs) override { + EXPECT_EQ(aDescrs.Length(), 500u); + for (int i = 0; i < static_cast(aDescrs.Length()); ++i) { + UniqueFileHandle handle = aDescrs[i].TakePlatformHandle(); + int value; + const int size = sizeof(value); +#ifdef XP_WIN + EXPECT_TRUE(::ReadFile(handle.get(), &value, size, nullptr, nullptr)); +#else + EXPECT_EQ(read(handle.get(), &value, size), size); +#endif + EXPECT_EQ(value, i); + } + Close(); + return IPC_OK(); + } + + private: + ~TestManyHandlesChild() = default; +}; + +class TestManyHandlesParent : public PTestManyHandlesParent { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestManyHandlesParent, override) + + private: + ~TestManyHandlesParent() = default; +}; + +IPDL_TEST(TestManyHandles) { + nsTArray descrs; + for (int i = 0; i < 500; ++i) { + const int size = sizeof(i); + UniqueFileHandle readPipe; + UniqueFileHandle writePipe; +#ifdef XP_WIN + ASSERT_TRUE(::CreatePipe(getter_Transfers(readPipe), + getter_Transfers(writePipe), nullptr, size)); + ASSERT_TRUE(::WriteFile(writePipe.get(), &i, size, nullptr, nullptr)); +#else + int fds[2]; + ASSERT_EQ(pipe(fds), 0); + readPipe.reset(fds[0]); + writePipe.reset(fds[1]); + ASSERT_EQ(write(writePipe.get(), &i, size), size); +#endif + descrs.AppendElement(FileDescriptor(std::move(readPipe))); + } + bool ok = mActor->SendManyHandles(descrs); + ASSERT_TRUE(ok); +} + +} // namespace mozilla::_ipdltest diff --git a/ipc/ipdl/test/gtest/moz.build b/ipc/ipdl/test/gtest/moz.build index c9ccbe8b4f20..1abd039e36b5 100644 --- a/ipc/ipdl/test/gtest/moz.build +++ b/ipc/ipdl/test/gtest/moz.build @@ -17,11 +17,13 @@ EXPORTS.mozilla._ipdltest += [ SOURCES += [ "IPDLUnitTest.cpp", "TestBasic.cpp", + "TestManyHandles.cpp", ] IPDL_SOURCES += [ "PIPDLUnitTest.ipdl", "PTestBasic.ipdl", + "PTestManyHandles.ipdl", ] include("/ipc/chromium/chromium-config.mozbuild")