From 8dd16259287f58f9273002717ec4d27e97127719 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 07:43:14 +0200 Subject: Merging upstream version 127.0. Signed-off-by: Daniel Baumann --- ipc/ipdl/test/gtest/PTestDestroyNested.ipdl | 18 ++++ ipc/ipdl/test/gtest/PTestDestroyNestedSub.ipdl | 19 ++++ ipc/ipdl/test/gtest/TestDestroyNested.cpp | 123 +++++++++++++++++++++++++ ipc/ipdl/test/gtest/moz.build | 3 + 4 files changed, 163 insertions(+) create mode 100644 ipc/ipdl/test/gtest/PTestDestroyNested.ipdl create mode 100644 ipc/ipdl/test/gtest/PTestDestroyNestedSub.ipdl create mode 100644 ipc/ipdl/test/gtest/TestDestroyNested.cpp (limited to 'ipc/ipdl/test/gtest') diff --git a/ipc/ipdl/test/gtest/PTestDestroyNested.ipdl b/ipc/ipdl/test/gtest/PTestDestroyNested.ipdl new file mode 100644 index 0000000000..1d58f1cf0c --- /dev/null +++ b/ipc/ipdl/test/gtest/PTestDestroyNested.ipdl @@ -0,0 +1,18 @@ +/* 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 protocol PTestDestroyNestedSub; + +namespace mozilla { +namespace _ipdltest { + +[ChildProc=any, ChildImpl=virtual, ParentImpl=virtual] +async protocol PTestDestroyNested { + manages PTestDestroyNestedSub; +child: + async PTestDestroyNestedSub(); +}; + +} // namespace _ipdltest +} // namespace mozilla diff --git a/ipc/ipdl/test/gtest/PTestDestroyNestedSub.ipdl b/ipc/ipdl/test/gtest/PTestDestroyNestedSub.ipdl new file mode 100644 index 0000000000..033c49261d --- /dev/null +++ b/ipc/ipdl/test/gtest/PTestDestroyNestedSub.ipdl @@ -0,0 +1,19 @@ +/* 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 protocol PTestDestroyNested; + +namespace mozilla { +namespace _ipdltest { + +[ChildProc=any, ChildImpl=virtual, ParentImpl=virtual] +async protocol PTestDestroyNestedSub { + manager PTestDestroyNested; +child: + + async __delete__(); +}; + +} // namespace _ipdltest +} // namespace mozilla diff --git a/ipc/ipdl/test/gtest/TestDestroyNested.cpp b/ipc/ipdl/test/gtest/TestDestroyNested.cpp new file mode 100644 index 0000000000..a348357b51 --- /dev/null +++ b/ipc/ipdl/test/gtest/TestDestroyNested.cpp @@ -0,0 +1,123 @@ +/* -*- 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/. */ + +/* + * Test an actor being destroyed during another ActorDestroy. + */ + +#include "gtest/gtest.h" + +#include "mozilla/_ipdltest/IPDLUnitTest.h" +#include "mozilla/_ipdltest/PTestDestroyNestedChild.h" +#include "mozilla/_ipdltest/PTestDestroyNestedParent.h" +#include "mozilla/_ipdltest/PTestDestroyNestedSubChild.h" +#include "mozilla/_ipdltest/PTestDestroyNestedSubParent.h" + +#include "mozilla/SpinEventLoopUntil.h" + +using namespace mozilla::ipc; + +namespace mozilla::_ipdltest { + +class TestDestroyNestedSubParent : public PTestDestroyNestedSubParent { + NS_INLINE_DECL_REFCOUNTING(TestDestroyNestedSubParent, override) + + void ActorDestroy(ActorDestroyReason aReason) override; + + bool mActorDestroyCalled = false; + bool mCloseManager = false; + + nsrefcnt GetRefCnt() const { return mRefCnt; } + + private: + ~TestDestroyNestedSubParent() = default; +}; + +class TestDestroyNestedSubChild : public PTestDestroyNestedSubChild { + NS_INLINE_DECL_REFCOUNTING(TestDestroyNestedSubChild, override) + private: + ~TestDestroyNestedSubChild() = default; +}; + +class TestDestroyNestedParent : public PTestDestroyNestedParent { + NS_INLINE_DECL_REFCOUNTING(TestDestroyNestedParent, override) + + void ActorDestroy(ActorDestroyReason aReason) override; + + bool mActorDestroyCalled = false; + + private: + ~TestDestroyNestedParent() = default; +}; + +class TestDestroyNestedChild : public PTestDestroyNestedChild { + NS_INLINE_DECL_REFCOUNTING(TestDestroyNestedChild, override) + + already_AddRefed AllocPTestDestroyNestedSubChild() + override { + return MakeAndAddRef(); + } + + private: + ~TestDestroyNestedChild() = default; +}; + +void TestDestroyNestedSubParent::ActorDestroy(ActorDestroyReason aReason) { + // Destroy our manager from within ActorDestroy() and assert that we don't + // re-enter. + EXPECT_FALSE(mActorDestroyCalled) << "re-entered ActorDestroy()"; + mActorDestroyCalled = true; + + if (mCloseManager) { + EXPECT_FALSE( + static_cast(Manager())->mActorDestroyCalled) + << "manager already destroyed"; + Manager()->Close(); + EXPECT_TRUE( + static_cast(Manager())->mActorDestroyCalled) + << "manager successfully destroyed"; + } + + // Make sure we also process any pending events, because we might be spinning + // a nested event loop within `ActorDestroy`. + NS_ProcessPendingEvents(nullptr); +} + +void TestDestroyNestedParent::ActorDestroy(ActorDestroyReason aReason) { + // Destroy our manager from within ActorDestroy() and assert that we don't + // re-enter. + EXPECT_FALSE(mActorDestroyCalled) << "re-entered ActorDestroy()"; + mActorDestroyCalled = true; +} + +IPDL_TEST(TestDestroyNested) { + auto p = MakeRefPtr(); + p->mCloseManager = true; + auto* rv1 = mActor->SendPTestDestroyNestedSubConstructor(p); + ASSERT_EQ(p, rv1) << "can't allocate Sub"; + + bool rv2 = PTestDestroyNestedSubParent::Send__delete__(p); + ASSERT_TRUE(rv2) + << "Send__delete__ failed"; + + ASSERT_TRUE(mActor->mActorDestroyCalled) + << "Parent not destroyed"; + ASSERT_TRUE(p->mActorDestroyCalled) + << "Sub not destroyed"; + + ASSERT_EQ(p->GetRefCnt(), 1u) << "Outstanding references to Sub remain"; + + // Try to allocate a new actor under the already-destroyed manager, and ensure + // that it is destroyed as expected. + auto p2 = MakeRefPtr(); + auto* rv3 = mActor->SendPTestDestroyNestedSubConstructor(p2); + ASSERT_EQ(rv3, nullptr) << "construction succeeded unexpectedly"; + + ASSERT_TRUE(p2->mActorDestroyCalled) + << "Sub not destroyed"; +} + +} // namespace mozilla::_ipdltest diff --git a/ipc/ipdl/test/gtest/moz.build b/ipc/ipdl/test/gtest/moz.build index 86fa2eca9e..5b60532026 100644 --- a/ipc/ipdl/test/gtest/moz.build +++ b/ipc/ipdl/test/gtest/moz.build @@ -22,6 +22,7 @@ SOURCES += [ "TestCrossProcessSemaphore.cpp", "TestDataStructures.cpp", "TestDescendant.cpp", + "TestDestroyNested.cpp", "TestEndpointOpens.cpp", "TestHangs.cpp", "TestInduceConnectionError.cpp", @@ -49,6 +50,8 @@ IPDL_SOURCES += [ "PTestDescendant.ipdl", "PTestDescendantSub.ipdl", "PTestDescendantSubsub.ipdl", + "PTestDestroyNested.ipdl", + "PTestDestroyNestedSub.ipdl", "PTestEndpointOpens.ipdl", "PTestEndpointOpensOpened.ipdl", "PTestHangs.ipdl", -- cgit v1.2.3