/*
 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
#include <wtf/MainThread.h>
#include <wtf/Noncopyable.h>

namespace WTF {

#if defined(NDEBUG) && !ENABLE(SECURITY_ASSERTIONS)
#define CHECK_REF_COUNTED_LIFECYCLE 0
#else
#define CHECK_REF_COUNTED_LIFECYCLE 1
#endif

// This base class holds the non-template methods and attributes.
// The RefCounted class inherits from it reducing the template bloat
// generated by the compiler (technique called template hoisting).
class RefCountedBase {
public:
    void ref() const
    {
        applyRefDerefThreadingCheck();

#if CHECK_REF_COUNTED_LIFECYCLE
        ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
        ASSERT(!m_adoptionIsRequired);
#endif
        ++m_refCount;
    }

    bool hasOneRef() const
    {
#if CHECK_REF_COUNTED_LIFECYCLE
        ASSERT(!m_deletionHasBegun);
#endif
        return m_refCount == 1;
    }

    unsigned refCount() const
    {
        return m_refCount;
    }

    void relaxAdoptionRequirement()
    {
#if CHECK_REF_COUNTED_LIFECYCLE
        ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
        ASSERT(m_adoptionIsRequired);
        m_adoptionIsRequired = false;
#endif
    }

    // Please only call this method if you really know that what you're doing is safe (e.g.
    // locking at call sites).
    void disableThreadingChecks()
    {
#if !ASSERT_DISABLED
        m_areThreadingChecksEnabled = false;
#endif
    }

    static void enableThreadingChecksGlobally()
    {
#if !ASSERT_DISABLED
        areThreadingChecksEnabledGlobally = true;
#endif
    }

protected:
    RefCountedBase()
        : m_refCount(1)
#if !ASSERT_DISABLED
        , m_isOwnedByMainThread(isMainThread())
#endif
#if CHECK_REF_COUNTED_LIFECYCLE
        , m_deletionHasBegun(false)
        , m_adoptionIsRequired(true)
#endif
    {
    }

    void applyRefDerefThreadingCheck() const
    {
#if !ASSERT_DISABLED
        if (hasOneRef()) {
            // Likely an ownership transfer across threads that may be safe.
            m_isOwnedByMainThread = isMainThread();
        } else if (areThreadingChecksEnabledGlobally && m_areThreadingChecksEnabled) {
            // If you hit this assertion, it means that the RefCounted object was ref/deref'd
            // from both the main thread and another in a way that is likely concurrent and unsafe.
            // Derive from ThreadSafeRefCounted and make sure the destructor is safe on threads
            // that call deref, or ref/deref from a single thread.
            ASSERT_WITH_MESSAGE(m_isOwnedByMainThread == isMainThread(), "Unsafe to ref/deref from different threads");
        }
#endif
    }

    ~RefCountedBase()
    {
#if CHECK_REF_COUNTED_LIFECYCLE
        ASSERT(m_deletionHasBegun);
        ASSERT(!m_adoptionIsRequired);
#endif
    }

    // Returns whether the pointer should be freed or not.
    bool derefBase() const
    {
        applyRefDerefThreadingCheck();

#if CHECK_REF_COUNTED_LIFECYCLE
        ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
        ASSERT(!m_adoptionIsRequired);
#endif

        ASSERT(m_refCount);
        unsigned tempRefCount = m_refCount - 1;
        if (!tempRefCount) {
#if CHECK_REF_COUNTED_LIFECYCLE
            m_deletionHasBegun = true;
#endif
            return true;
        }
        m_refCount = tempRefCount;
        return false;
    }

#if CHECK_REF_COUNTED_LIFECYCLE
    bool deletionHasBegun() const
    {
        return m_deletionHasBegun;
    }
#endif

private:

#if CHECK_REF_COUNTED_LIFECYCLE
    friend void adopted(RefCountedBase*);
#endif

    mutable unsigned m_refCount;
#if !ASSERT_DISABLED
    mutable bool m_isOwnedByMainThread;
    bool m_areThreadingChecksEnabled { true };
#endif
    WTF_EXPORT_PRIVATE static bool areThreadingChecksEnabledGlobally;
#if CHECK_REF_COUNTED_LIFECYCLE
    mutable bool m_deletionHasBegun;
    mutable bool m_adoptionIsRequired;
#endif
};

#if CHECK_REF_COUNTED_LIFECYCLE
inline void adopted(RefCountedBase* object)
{
    if (!object)
        return;
    ASSERT_WITH_SECURITY_IMPLICATION(!object->m_deletionHasBegun);
    object->m_adoptionIsRequired = false;
}
#endif

template<typename T, typename Deleter = std::default_delete<T>> class RefCounted : public RefCountedBase {
    WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED;
public:
    void deref() const
    {
        if (derefBase())
            Deleter()(const_cast<T*>(static_cast<const T*>(this)));
    }

protected:
    RefCounted() { }
    ~RefCounted()
    {
    }
};

} // namespace WTF

using WTF::RefCounted;
