// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FBL_REF_COUNTED_INTERNAL_H_
#define FBL_REF_COUNTED_INTERNAL_H_

#include <atomic>
#include <zircon/assert.h>
#include <zircon/compiler.h>

namespace fbl {
namespace internal {

// Adoption validation will help to catch:
// - Double-adoptions
// - AddRef/Release without adopting first
// - Re-wrapping raw pointers to destroyed objects
//
// It also provides some limited defense against
// - Wrapping bad pointers
template <bool EnableAdoptionValidator>
class RefCountedBase {
protected:
    constexpr RefCountedBase()
        : ref_count_(kPreAdoptSentinel) {}

    ~RefCountedBase() {
        if (EnableAdoptionValidator) {
            // Reset the ref-count back to the pre-adopt sentinel value so that we
            // have the best chance of catching a use-after-free situation, even if
            // we have a messed up mix of debug/release translation units being
            // linked together.
            ref_count_.store(kPreAdoptSentinel, std::memory_order_release);
        }
    }

    void AddRef() const {
        const int32_t rc = ref_count_.fetch_add(1, std::memory_order_relaxed);

        // This assertion will fire if either of the following occur.
        //
        // 1) someone calls AddRef() before the object has been properly
        // Adopted.
        //
        // 2) someone calls AddRef() on a ref-counted object that has
        // reached ref_count_ == 0 but has not been destroyed yet. This
        // could happen by manually calling AddRef(), or re-wrapping such a
        // pointer with WrapRefPtr() or RefPtr<T>(T*) (both of which call
        // AddRef()).
        //
        // Note: leave the ASSERT on in all builds.  The constant
        // EnableAdoptionValidator check above should cause this code path to be
        // pruned in release builds, but leaving this as an always on ASSERT
        // will mean that the tests continue to function even when built as
        // release.
        if (EnableAdoptionValidator) {
            ZX_ASSERT_MSG(rc >= 1, "count %d(0x%08x) < 1\n", rc, static_cast<uint32_t>(rc));
        }
    }

    // Returns true if the object should self-delete.
    bool Release() const __WARN_UNUSED_RESULT {
        const int32_t rc = ref_count_.fetch_sub(1, std::memory_order_release);

        // This assertion will fire if someone manually calls Release()
        // on a ref-counted object too many times, or if Release is called
        // before an object has been Adopted.
        //
        // Note: leave the ASSERT on in all builds.  The constant
        // EnableAdoptionValidator check above should cause this code path to be
        // pruned in release builds, but leaving this as an always on ASSERT
        // will mean that the tests continue to function even when built as
        // release.
        if (EnableAdoptionValidator) {
            ZX_ASSERT_MSG(rc >= 1, "count %d(0x%08x) < 1\n", rc, static_cast<uint32_t>(rc));
        }

        if (rc == 1) {
            atomic_thread_fence(std::memory_order_acquire);
            return true;
        }

        return false;
    }

    void Adopt() const {
        // TODO(johngro): turn this into an if-constexpr when we have moved up
        // to C++17
        if (EnableAdoptionValidator) {
            int32_t expected = kPreAdoptSentinel;
            bool res = ref_count_.compare_exchange_strong(expected, 1,
                                                          std::memory_order_acq_rel,
                                                          std::memory_order_acquire);
            // Note: leave the ASSERT on in all builds.  The constant
            // EnableAdoptionValidator check above should cause this code path
            // to be pruned in release builds, but leaving this as an always on
            // ASSERT will mean that the tests continue to function even when
            // built as release.
            ZX_ASSERT_MSG(res,
                          "count(0x%08x) != sentinel(0x%08x)\n",
                          static_cast<uint32_t>(expected),
                          static_cast<uint32_t>(kPreAdoptSentinel));
        } else {
            ref_count_.store(1, std::memory_order_release);
        }
    }

    // Current ref count. Only to be used for debugging purposes.
    int ref_count_debug() const {
        return ref_count_.load(std::memory_order_relaxed);
    }

    // Note:
    //
    // The PreAdoptSentinel value is chosen specifically to be negative when
    // stored as an int32_t, and as far away from becoming positive (via either
    // addition or subtraction) as possible.  These properties allow us to
    // combine the debug-build adopt sanity checks and the lifecycle sanity
    // checks into a single debug assert.
    //
    // If a user creates an object, but never adopts it, they would need to
    // perform 0x4000000 (about 1 billion) unchecked AddRef or Release
    // operations before making the internal ref_count become positive again.
    // At this point, even a checked AddRef or Release operation would fail to
    // detect the bad state of the system fails to detect the problem.
    //
    static constexpr int32_t kPreAdoptSentinel = static_cast<int32_t>(0xC0000000);
    mutable std::atomic_int32_t ref_count_;
};

} // namespace internal
} // namespace fbl

#endif  // FBL_REF_COUNTED_INTERNAL_H_
