Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d435894e authored by Steven Moreland's avatar Steven Moreland
Browse files

RefBase: document 0 strong count, wp<>::promote

Explanation within. This shows the errorprone behavior
of the implicit wp<> constructor and justifies why we
recommend wp<>::fromExisting.

Bug: 393013610
Test: libutils_binder_test
Change-Id: I323b2902f0ae58da8512bdbc80377b5c5865294d
parent 364d5dfb
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -265,6 +265,37 @@ TEST(RefBase, AssertWeakRefExistsDeath) {
    delete foo;
}

TEST(RefBase, NoStrongCountPromoteFromWeak) {
    bool isDeleted;
    Foo* foo = new Foo(&isDeleted);

    wp<Foo> weakFoo = wp<Foo>(foo);

    EXPECT_FALSE(isDeleted);

    {
        sp<Foo> strongFoo = weakFoo.promote();
        EXPECT_EQ(strongFoo, foo);
    }

    // this shows the justification of wp<>::fromExisting.
    // if you construct a wp<>, for instance in a constructor, and it is
    // accidentally promoted, that promoted sp<> will exclusively own
    // the object. If that happens during the initialization of the
    // object or in this scope, as you can see 'Foo* foo' is unowned,
    // then we are left with a deleted object, and we could not put it
    // into an sp<>.
    //
    // Consider the other implementation, where we disallow promoting
    // a wp<> if there are no strong counts. If we return null, then
    // the object would be unpromotable even though it hasn't been deleted.
    // This is also errorprone.
    //
    // attemptIncStrong aborting in this case is a backwards incompatible
    // change due to frequent use of wp<T>(this) in the constructor.
    EXPECT_TRUE(isDeleted);
}

TEST(RefBase, DoubleOwnershipDeath) {
    bool isDeleted;
    auto foo = sp<Foo>::make(&isDeleted);