/*
 * 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(isMainThreadIfInitialized())
        , m_areThreadingChecksEnabled(isMainThreadInitialized())
#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 = isMainThreadIfInitialized();
        } 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;
