diff --git a/libutils/binder/StrongPointer_test.cpp b/libutils/binder/StrongPointer_test.cpp index f27c1f1cc..aa993c3f8 100644 --- a/libutils/binder/StrongPointer_test.cpp +++ b/libutils/binder/StrongPointer_test.cpp @@ -106,3 +106,17 @@ TYPED_TEST(StrongPointer, AssertStrongRefExists) { EXPECT_DEATH(sp::fromExisting(foo), ""); delete foo; } + +TYPED_TEST(StrongPointer, release) { + bool isDeleted = false; + TypeParam* foo = nullptr; + { + sp sp1 = sp::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!"; +} diff --git a/libutils/binder/include/utils/StrongPointer.h b/libutils/binder/include/utils/StrongPointer.h index 54aa691e0..43c00c95a 100644 --- a/libutils/binder/include/utils/StrongPointer.h +++ b/libutils/binder/include/utils/StrongPointer.h @@ -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; }