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

Commit 476dbc48 authored by Greg Kaiser's avatar Greg Kaiser
Browse files

SharedBuffer: Refactor release() logic

We refactor this mildly in the hopes of making this a little easier
to follow for future readers.  We also go through the dealloc()
method so if we decide to invoke the SharedBuffer destructor in
the future, we only need to remember it in one place.

In addition, this is slightly more efficient in the multi-owner
case, since we no longer subtract to 0 and then (redundantly) set the
reference count explicitly to 0 as well.

Change-Id: Ifc773bd7900c89c36ac24904b2716f02cb57c095
parent 54cf81e6
Loading
Loading
Loading
Loading
+17 −7
Original line number Original line Diff line number Diff line
@@ -111,16 +111,26 @@ void SharedBuffer::acquire() const {


int32_t SharedBuffer::release(uint32_t flags) const
int32_t SharedBuffer::release(uint32_t flags) const
{
{
    int32_t prev = 1;
    const bool useDealloc = ((flags & eKeepStorage) == 0);
    if (onlyOwner()
    if (onlyOwner()) {
            || (((prev = mRefs.fetch_sub(1, std::memory_order_release)) == 1)
        // Since we're the only owner, our reference count goes to zero.
                && (atomic_thread_fence(std::memory_order_acquire), true))) {
        mRefs.store(0, std::memory_order_relaxed);
        mRefs.store(0, std::memory_order_relaxed);
        if ((flags & eKeepStorage) == 0) {
        if (useDealloc) {
            free(const_cast<SharedBuffer*>(this));
            dealloc(this);
        }
        // As the only owner, our previous reference count was 1.
        return 1;
    }
    // There's multiple owners, we need to use an atomic decrement.
    int32_t prevRefCount = mRefs.fetch_sub(1, std::memory_order_release);
    if (prevRefCount == 1) {
        // We're the last reference, we need the acquire fence.
        atomic_thread_fence(std::memory_order_acquire);
        if (useDealloc) {
            dealloc(this);
        }
        }
    }
    }
    return prev;
    return prevRefCount;
}
}