Loading libutils/binder/StrongPointer_test.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -106,3 +106,17 @@ TYPED_TEST(StrongPointer, AssertStrongRefExists) { EXPECT_DEATH(sp<TypeParam>::fromExisting(foo), ""); delete foo; } TYPED_TEST(StrongPointer, release) { bool isDeleted = false; TypeParam* foo = nullptr; { sp<TypeParam> sp1 = sp<TypeParam>::make(&isDeleted); ASSERT_EQ(1, sp1->getStrongCount()); foo = sp1.release(); } ASSERT_FALSE(isDeleted) << "release failed, deleted anyway when sp left scope"; ASSERT_EQ(1, foo->getStrongCount()) << "release mismanaged refcount"; foo->decStrong(nullptr); ASSERT_TRUE(isDeleted) << "foo was leaked!"; } libutils/binder/include/utils/StrongPointer.h +9 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,15 @@ public: void clear(); // Releases the ownership of the object managed by this instance of sp, if any. // The caller is now responsible for managing it. That is, the caller must ensure // decStrong() is called when the pointer is no longer used. [[nodiscard]] inline T* release() noexcept { auto ret = m_ptr; m_ptr = nullptr; return ret; } // Accessors inline T& operator* () const { return *m_ptr; } Loading Loading
libutils/binder/StrongPointer_test.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -106,3 +106,17 @@ TYPED_TEST(StrongPointer, AssertStrongRefExists) { EXPECT_DEATH(sp<TypeParam>::fromExisting(foo), ""); delete foo; } TYPED_TEST(StrongPointer, release) { bool isDeleted = false; TypeParam* foo = nullptr; { sp<TypeParam> sp1 = sp<TypeParam>::make(&isDeleted); ASSERT_EQ(1, sp1->getStrongCount()); foo = sp1.release(); } ASSERT_FALSE(isDeleted) << "release failed, deleted anyway when sp left scope"; ASSERT_EQ(1, foo->getStrongCount()) << "release mismanaged refcount"; foo->decStrong(nullptr); ASSERT_TRUE(isDeleted) << "foo was leaked!"; }
libutils/binder/include/utils/StrongPointer.h +9 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,15 @@ public: void clear(); // Releases the ownership of the object managed by this instance of sp, if any. // The caller is now responsible for managing it. That is, the caller must ensure // decStrong() is called when the pointer is no longer used. [[nodiscard]] inline T* release() noexcept { auto ret = m_ptr; m_ptr = nullptr; return ret; } // Accessors inline T& operator* () const { return *m_ptr; } Loading