Android的智能指针

Posted by hxg_ on April 23, 2017

安卓系统中的智能指针

背景

在使用C++来编写代码的过程中,指针使用不当造成内存泄漏一般就是因为new了一个对象并且使用完之后,忘记了delete这个对象,而造成系统崩溃一般就是因为一个地方delete了这个对象之后,其它地方还在继续使原来指向这个对象的指针。为了避免出现上述问题,一般的做法就是使用引用计数的方法,每当有一个指针指向了一个new出来的对象时,就对这个对象的引用计数增加1,每当有一个指针不再使用这个对象时,就对这个对象的引用计数减少1,每次减1之后,如果发现引用计数值为0时,那么,就要delete这个对象了,这样就避免了忘记delete对象或者这个对象被delete之后其它地方还在使用的问题了。但是,如何实现这个对象的引用计数呢?肯定不是由开发人员来手动地维护了,要开发人员时刻记住什么时候该对这个对象的引用计数加1,什么时候该对这个对象的引用计数减1,一来是不方便开发,二来是不可靠,一不小心哪里多加了一个1或者多减了一个1,就会造成灾难性的后果。这时候,智能指针就粉墨登场了。首先,智能指针是一个对象,不过这个对象代表的是另外一个真实使用的对象,当智能指针指向实际对象的时候,就是智能指针对象创建的时候,当智能指针不再指向实际对象的时候,就是智能指针对象销毁的时候,我们知道,在C++中,对象的创建和销毁时会分别自动地调用对象的构造函数和析构函数,这样,负责对真实对象的引用计数加1和减1的工作就落实到智能指针对象的构造函数和析构函数的身上了,这也是为什么称这个指针对象为智能指针的原因。
    在计算机科学领域中,提供垃圾收集(Garbage Collection)功能的系统框架,即提供对象托管功能的系统框架,例如Java应用程序框架,也是采用上述的引用计数技术方案来实现的,然而,简单的引用计数技术不能处理系统中对象间循环引用的情况。如:系统中有两个对象A和B,在对象A的内部引用了对象B,而在对象B的内部也引用了对象A。当两个对象A和B都不再使用时,垃圾收集系统会发现无法回收这两个对象的所占据的内存的,因为系统一次只能收集一个对象,而无论系统决定要收回对象A还是要收回对象B时,都会发现这个对象被其它的对象所引用,因而就都回收不了,这样就造成了内存泄漏。这样,就要采取另外的一种引用计数技术了,即对象的引用计数同时存在强引用和弱引用两种计数,例如,Apple公司提出的Cocoa框架,当父对象要引用子对象时,就对子对象使用强引用计数技术,而当子对象要引用父对象时,就对父对象使用弱引用计数技术,而当垃圾收集系统执行对象回收工作时,只要发现对象的强引用计数为0,而不管它的弱引用计数是否为0,都可以回收这个对象,但是,如果我们只对一个对象持有弱引用计数,当我们要使用这个对象时,就不直接使用了,必须要把这个弱引用升级成为强引用时,才能使用这个对象,在转换的过程中,如果对象已经不存在,那么转换就失败了,这时候就说明这个对象已经被销毁了,不能再使用了。

轻量级指针

引用计数器类LightRefBase,位置:system/core/include/utils/RefBase.h

template <class T>
class LightRefBase
{
public:
    inline LightRefBase() : mCount(0) { }
    inline void incStrong(__attribute__((unused)) const void* id) const {
        mCount.fetch_add(1, std::memory_order_relaxed);
    }
    inline void decStrong(__attribute__((unused)) const void* id) const {
        if (mCount.fetch_sub(1, std::memory_order_release) == 1) {
            std::atomic_thread_fence(std::memory_order_acquire);
            delete static_cast<const T*>(this);
        }
    }
    //! DEBUGGING ONLY: Get current strong ref count.
    inline int32_t getStrongCount() const {
        return mCount.load(std::memory_order_relaxed);
    }

    typedef LightRefBase<T> basetype;

protected:
    inline ~LightRefBase() { }

private:
    friend class ReferenceMover;
    inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { }
    inline static void renameRefId(T* ref,
            const void* old_id, const void* new_id) { }

private:
    mutable std::atomic<int32_t> mCount;
};

unused:This attribute, attached to a function, means that the function is meant to be possibly unused. GCC will not produce a warning for this function

此类只有一个成员变量mCount,即引用计数器,在构造方法中初始化为0。 此外,提供了incStrong和decStrong方法来操作此计数器的值。在decStrong方法中,若当前mCount的值为1,则delete此对象。

配合LightRefBase引用计数器使用的是sp类,位置:system/core/include/utils/StrongPointer.h

template<typename T>
class sp {
public:
    inline sp() : m_ptr(0) { }

    sp(T* other);
    sp(const sp<T>& other);
    sp(sp<T>&& other);
    template<typename U> sp(U* other);
    template<typename U> sp(const sp<U>& other);
    template<typename U> sp(sp<U>&& other);

    ~sp();

    // Assignment

    sp& operator = (T* other);
    sp& operator = (const sp<T>& other);
    sp& operator = (sp<T>&& other);

    template<typename U> sp& operator = (const sp<U>& other);
    template<typename U> sp& operator = (sp<U>&& other);
    template<typename U> sp& operator = (U* other);

    //! Special optimization for use by ProcessState (and nobody else).
    void force_set(T* other);

    // Reset

    void clear();

    // Accessors

    inline  T&      operator* () const  { return *m_ptr; }
    inline  T*      operator-> () const { return m_ptr;  }
    inline  T*      get() const         { return m_ptr; }

    // Operators

    COMPARE(==)
    COMPARE(!=)
    COMPARE(>)
    COMPARE(<)
    COMPARE(<=)
    COMPARE(>=)

private:    
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;
    void set_pointer(T* ptr);
    T* m_ptr;
};

同样,只看成员变量m_prt、构造函数、析构函数。

template<typename T>
sp<T>::sp(T* other)
        : m_ptr(other) {
    if (other)
        other->incStrong(this);
}

template<typename T>
sp<T>::sp(const sp<T>& other)
        : m_ptr(other.m_ptr) {
    if (m_ptr)
        m_ptr->incStrong(this);
}

template<typename T>
sp<T>::sp(sp<T>&& other)
        : m_ptr(other.m_ptr) {
    other.m_ptr = nullptr;
}

template<typename T> template<typename U>
sp<T>::sp(U* other)
        : m_ptr(other) {
    if (other)
        ((T*) other)->incStrong(this);
}

template<typename T> template<typename U>
sp<T>::sp(const sp<U>& other)
        : m_ptr(other.m_ptr) {
    if (m_ptr)
        m_ptr->incStrong(this);
}

template<typename T> template<typename U>
sp<T>::sp(sp<U>&& other)
        : m_ptr(other.m_ptr) {
    other.m_ptr = nullptr;
}

构造方法中,都是先初始化m_ptr,然后调用incStrong方法增加对象的引用计数。

template<typename T>
sp<T>::~sp() {
    if (m_ptr)
        m_ptr->decStrong(this);
}

析构函数中,调用decStrong方法减少引用计数。

强指针

引用计数器类RefBase,所在位置:system/core/include/utils/RefBase.h

class RefBase
{
public:
            void            incStrong(const void* id) const;
            void            decStrong(const void* id) const;
    
            void            forceIncStrong(const void* id) const;

            //! DEBUGGING ONLY: Get current strong ref count.
            int32_t         getStrongCount() const;

    class weakref_type
    {
    public:
        RefBase*            refBase() const;
        
        void                incWeak(const void* id);
        void                decWeak(const void* id);
        
        // acquires a strong reference if there is already one.
        bool                attemptIncStrong(const void* id);
        
        // acquires a weak reference if there is already one.
        // This is not always safe. see ProcessState.cpp and BpBinder.cpp
        // for proper use.
        bool                attemptIncWeak(const void* id);

        //! DEBUGGING ONLY: Get current weak ref count.
        int32_t             getWeakCount() const;

        //! DEBUGGING ONLY: Print references held on object.
        void                printRefs() const;

        //! DEBUGGING ONLY: Enable tracking for this object.
        // enable -- enable/disable tracking
        // retain -- when tracking is enable, if true, then we save a stack trace
        //           for each reference and dereference; when retain == false, we
        //           match up references and dereferences and keep only the 
        //           outstanding ones.
        
        void                trackMe(bool enable, bool retain);
    };
    
            weakref_type*   createWeak(const void* id) const;
            
            weakref_type*   getWeakRefs() const;

            //! DEBUGGING ONLY: Print references held on object.
    inline  void            printRefs() const { getWeakRefs()->printRefs(); }

            //! DEBUGGING ONLY: Enable tracking of object.
    inline  void            trackMe(bool enable, bool retain)
    { 
        getWeakRefs()->trackMe(enable, retain); 
    }

    typedef RefBase basetype;

protected:
                            RefBase();
    virtual                 ~RefBase();
    
    //! Flags for extendObjectLifetime()
    enum {
        OBJECT_LIFETIME_STRONG  = 0x0000,
        OBJECT_LIFETIME_WEAK    = 0x0001,
        OBJECT_LIFETIME_MASK    = 0x0001
    };
    
            void            extendObjectLifetime(int32_t mode);
            
    //! Flags for onIncStrongAttempted()
    enum {
        FIRST_INC_STRONG = 0x0001
    };
    
    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
    virtual void            onLastWeakRef(const void* id);

private:
    friend class weakref_type;
    class weakref_impl;
    
                            RefBase(const RefBase& o);
            RefBase&        operator=(const RefBase& o);

private:
    friend class ReferenceMover;

    static void renameRefs(size_t n, const ReferenceRenamer& renamer);

    static void renameRefId(weakref_type* ref,
            const void* old_id, const void* new_id);

    static void renameRefId(RefBase* ref,
            const void* old_id, const void* new_id);

        weakref_impl* const mRefs;
};

与LightRefBase类一样,提供了incStrong和decStrong方法来操作计数器。与LightRefBase不同在于,他没有直接提供一直整型对象来维护计数器,而且通过weakref_impl类型的成员变量mRefs来维护计数器.

weakref_impl明显为实现类,位置:system/core.libutils/RefBase.cpp


class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
    std::atomic<int32_t>    mStrong;
    std::atomic<int32_t>    mWeak;
    RefBase* const          mBase;
    std::atomic<int32_t>    mFlags;
    weakref_impl(RefBase* base)
        : mStrong(INITIAL_STRONG_VALUE)
        , mWeak(0)
        , mBase(base)
        , mFlags(0)
    {
    }
    void addStrongRef(const void* /*id*/) { }
    void removeStrongRef(const void* /*id*/) { }
    void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
    void addWeakRef(const void* /*id*/) { }
    void removeWeakRef(const void* /*id*/) { }
    void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
    void printRefs() const { }
    void trackMe(bool, bool) { }
}

以上为release版本的代码,方法均为空方法。 此类中提供了4个成员变量来维护引用计数:

	std::atomic<int32_t>    mStrong;
    std::atomic<int32_t>    mWeak;
    RefBase* const          mBase;
    std::atomic<int32_t>    mFlags;

其中,mStrong为对象的强引用计数,mWeak为对象的若引用计数。mFlags表示对象引用计数器所使用的策略,他的取值包括:

enum {
        OBJECT_LIFETIME_STRONG  = 0x0000,
        OBJECT_LIFETIME_WEAK    = 0x0001,
        OBJECT_LIFETIME_MASK    = 0x0001
    };
// In the OBJECT_LIFETIME_STRONG case, it is deallocated in the RefBase
// destructor iff the strong reference count was never incremented. The
// destructor can be invoked either from decStrong, or from decWeak if there
// was never a strong reference. If the reference count had been incremented,
// it is deallocated directly in decWeak, and hence still lives as long as
// the last weak reference.
// In the OBJECT_LIFETIME_WEAK case, it is always deallocated from the RefBase
// destructor, which is always invoked by decWeak. DecStrong explicitly avoids
// the deletion in this case.

强指针类sp,构造方法的实现:

template<typename T>  
sp<T>::sp(T* other)  
    : m_ptr(other)  
{  
    if (other) other->incStrong(this);  
} 

other继承RefBase类,incStrong方法的实现:

void RefBase::incStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->incWeak(id);
    
    refs->addStrongRef(id);
    const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);
    
    if (c != INITIAL_STRONG_VALUE)  {
        return;
    }

    int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
            std::memory_order_relaxed);
    // A decStrong() must still happen after us.

    refs->mBase->onFirstRef();
}

此方法中主要做了3件事:

1、增加弱引用计数;

weakref_impl* const refs = mRefs;
refs->incWeak(id);

2、增加强引用计数;

refs->addStrongRef(id);
const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);

3、判断是否为首次调用此对象的incStrong方法,如果是则调用对象的onFirstRef方法,让对象在被首次引用时做其他逻辑;

if (c != INITIAL_STRONG_VALUE)  {
        return;
}
    
int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
            std::memory_order_relaxed);
// A decStrong() must still happen after us.

refs->mBase->onFirstRef();

即:在构造方法中,强引用、弱引用计数+1。

强指针的析构函数:

template<typename T>
sp<T>::~sp() {
    if (m_ptr)
        m_ptr->decStrong(this);
}

m_ptr是继承RefBase类的对象,因此看RefBase重的decStrong方法。

void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->removeStrongRef(id);
    const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);
    ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
    if (c == 1) {
        std::atomic_thread_fence(std::memory_order_acquire);
        refs->mBase->onLastStrongRef(id);
        int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            delete this;
            // Since mStrong had been incremented, the destructor did not
            // delete refs.
        }
    }
    // Note that even with only strong reference operations, the thread
    // deallocating this may not be the same as the thread deallocating refs.
    // That's OK: all accesses to this happen before its deletion here,
    // and all accesses to refs happen before its deletion in the final decWeak.
    // The destructor can safely access mRefs because either it's deleting
    // mRefs itself, or it's running entirely before the final mWeak decrement.
    refs->decWeak(id);
}

在release版本中,removeStrongRef方法为空实现,实现强引用计数器-1的为:

const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);

-1之前发现强引用计数为1,则表示再没有地方引用此对象了,看flags情况是否删除此对象。

if (c == 1) {
        std::atomic_thread_fence(std::memory_order_acquire);
        refs->mBase->onLastStrongRef(id);
        int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            delete this;
            // Since mStrong had been incremented, the destructor did not
            // delete refs.
        }
    }

如果当前策略是OBJECT_LIFETIME_STRONG,则直接删除此对象,否则执行

refs->decWeak(id)

decWeak的实现:

void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->removeWeakRef(id);
    const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release);
    ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
    if (c != 1) return;
    atomic_thread_fence(std::memory_order_acquire);

    int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
    if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
        // This is the regular lifetime case. The object is destroyed
        // when the last strong reference goes away. Since weakref_impl
        // outlive the object, it is not destroyed in the dtor, and
        // we'll have to do it here.
        if (impl->mStrong.load(std::memory_order_relaxed)
                == INITIAL_STRONG_VALUE) {
            // Special case: we never had a strong reference, so we need to
            // destroy the object now.
            delete impl->mBase;
        } else {
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            delete impl;
        }
    } else {
        // This is the OBJECT_LIFETIME_WEAK case. The last weak-reference
        // is gone, we can destroy the object.
        impl->mBase->onLastWeakRef(id);
        delete impl->mBase;
    }
}

removeStrongRef一样,真正实现若引用计数-1的为:

const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release);

同时,-1之前判断是否为1,若不为1,则return。

if (c != 1) return;

如果对象的生命周期是受强引用计数器控制的,则:

if (impl->mStrong.load(std::memory_order_relaxed)
                == INITIAL_STRONG_VALUE) {
            // Special case: we never had a strong reference, so we need to
            // destroy the object now.
            delete impl->mBase;
        } else {
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            delete impl;
}

在这里分了两种情况:

1、强引用计数==INITIAL_STRONG_VALUE
2、强引用计数!=INITIAL_STRONG_VALUE

增加对象的弱引用计数有两种方式:

1、增加对象的强引用计数时,会同时增加弱引用计数;
2、使用弱指针指向对象,只增加弱引用计数;

若为第一种方式,则强引用计数必然为0,!=INITIAL_STRONG_VALUE,则此时不需要删除此对象,因为decStrong方法中会删除此对象,此时只需要删除weakref_impl对象。

delete impl->mBase;

若为第二种方式,则表示没有地方会删除此对象,因此需要delete impl.

即:

1、在OBJECT_LIFETIME_STRONG case下,强引用计数==0,delete此对象;
2、在OBJECT_LIFETIME_WEAK case下,强引用计数==0 && 弱引用计数==0,delete此对象。

弱指针

弱指针使用的引用计数器同强指针,是RefBase类。弱指针的位置:system/core/include/utils/RefBase.h

template <typename T>
class wp
{
public:
    typedef typename RefBase::weakref_type weakref_type;
    
    inline wp() : m_ptr(0) { }

    wp(T* other);
    wp(const wp<T>& other);
    wp(const sp<T>& other);
    template<typename U> wp(U* other);
    template<typename U> wp(const sp<U>& other);
    template<typename U> wp(const wp<U>& other);

    ~wp();
    
    // Assignment

    wp& operator = (T* other);
    wp& operator = (const wp<T>& other);
    wp& operator = (const sp<T>& other);
    
    template<typename U> wp& operator = (U* other);
    template<typename U> wp& operator = (const wp<U>& other);
    template<typename U> wp& operator = (const sp<U>& other);
    
    void set_object_and_refs(T* other, weakref_type* refs);

    // promotion to sp
    
    sp<T> promote() const;

    // Reset
    
    void clear();

    // Accessors
    
    inline  weakref_type* get_refs() const { return m_refs; }
    
    inline  T* unsafe_get() const { return m_ptr; }

    // Operators

    COMPARE_WEAK(==)
    COMPARE_WEAK(!=)
    COMPARE_WEAK(>)
    COMPARE_WEAK(<)
    COMPARE_WEAK(<=)
    COMPARE_WEAK(>=)

    inline bool operator == (const wp<T>& o) const {
        return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
    }
    template<typename U>
    inline bool operator == (const wp<U>& o) const {
        return m_ptr == o.m_ptr;
    }

    inline bool operator > (const wp<T>& o) const {
        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
    }
    template<typename U>
    inline bool operator > (const wp<U>& o) const {
        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
    }

    inline bool operator < (const wp<T>& o) const {
        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
    }
    template<typename U>
    inline bool operator < (const wp<U>& o) const {
        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
    }
                         inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
                         inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
                         inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }

private:
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;

    T*              m_ptr;
    weakref_type*   m_refs;
};

同强指针一样,m_ptr变量指向目标对象。此外还有一个weakref_type类型的成员变量m_refs

构造函数:

template<typename T>
wp<T>::wp(T* other)
    : m_ptr(other)
{
    if (other) m_refs = other->createWeak(this);
}

同强指针,other是继承自RefBase类,看RefBasecreateWeak方法。

RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
    mRefs->incWeak(id);
    return mRefs;
}

mRefsweakref_impl的指针,incWeak方法即为增加对象的弱引用计数。

void RefBase::weakref_type::incWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->addWeakRef(id);
    const int32_t c __unused = impl->mWeak.fetch_add(1,
            std::memory_order_relaxed);
    ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}

析构函数:

template<typename T>
wp<T>::~wp()
{
    if (m_ptr) m_refs->decWeak(this);
}

RefBase类的decWeak方法,再强指针中已介绍。

弱指针的特点是不能直接操作目标对象,是因为没用重载*->两个操作符。下面的是在StrongPointer中重载的操作符:

inline  T&      operator* () const  { return *m_ptr; }
inline  T*      operator-> () const { return m_ptr;  }

弱指针想要操作目标对象,可升级为强指针,通过如下方法:

template<typename T>
sp<T> wp<T>::promote() const
{
    sp<T> result;
    if (m_ptr && m_refs->attemptIncStrong(&result)) {
        result.set_pointer(m_ptr);
    }
    return result;
}

attemptIncStrong方法:

bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
    incWeak(id);
    
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    int32_t curCount = impl->mStrong.load(std::memory_order_relaxed);

    ALOG_ASSERT(curCount >= 0,
            "attemptIncStrong called on %p after underflow", this);

    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
        // we're in the easy/common case of promoting a weak-reference
        // from an existing strong reference.
        if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
                std::memory_order_relaxed)) {
            break;
        }
        // the strong count has changed on us, we need to re-assert our
        // situation. curCount was updated by compare_exchange_weak.
    }
    
    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
        // we're now in the harder case of either:
        // - there never was a strong reference on us
        // - or, all strong references have been released
        int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            // this object has a "normal" life-time, i.e.: it gets destroyed
            // when the last strong reference goes away
            if (curCount <= 0) {
                // the last strong-reference got released, the object cannot
                // be revived.
                decWeak(id);
                return false;
            }

            // here, curCount == INITIAL_STRONG_VALUE, which means
            // there never was a strong-reference, so we can try to
            // promote this object; we need to do that atomically.
            while (curCount > 0) {
                if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
                        std::memory_order_relaxed)) {
                    break;
                }
                // the strong count has changed on us, we need to re-assert our
                // situation (e.g.: another thread has inc/decStrong'ed us)
                // curCount has been updated.
            }

            if (curCount <= 0) {
                // promote() failed, some other thread destroyed us in the
                // meantime (i.e.: strong count reached zero).
                decWeak(id);
                return false;
            }
        } else {
            // this object has an "extended" life-time, i.e.: it can be
            // revived from a weak-reference only.
            // Ask the object's implementation if it agrees to be revived
            if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {
                // it didn't so give-up.
                decWeak(id);
                return false;
            }
            // grab a strong-reference, which is always safe due to the
            // extended life-time.
            curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
        }

        // If the strong reference count has already been incremented by
        // someone else, the implementor of onIncStrongAttempted() is holding
        // an unneeded reference.  So call onLastStrongRef() here to remove it.
        // (No, this is not pretty.)  Note that we MUST NOT do this if we
        // are in fact acquiring the first reference.
        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
            impl->mBase->onLastStrongRef(id);
        }
    }
    
    impl->addStrongRef(id);

    // curCount is the value of mStrong before we increment ed it.
    // Now we need to fix-up the count if it was INITIAL_STRONG_VALUE.
    // This must be done safely, i.e.: handle the case where several threads
    // were here in attemptIncStrong().
    // curCount > INITIAL_STRONG_VALUE is OK, and can happen if we're doing
    // this in the middle of another incStrong.  The subtraction is handled
    // by the thread that started with INITIAL_STRONG_VALUE.
    if (curCount == INITIAL_STRONG_VALUE) {
        impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
                std::memory_order_relaxed);
    }

    return true;
}

此方法为增加对象的强引用计数,有可能因为目标对象已经被delete掉等原因失败。函数开始,即增加对象的弱引用计数,当之后增加强引用计数失败时,会减少弱引用计数。

incWeak(id);

增加强引用计数的时候,会有两种情况:

1、对象正在被其他强指针引用,即:强引用计数大于0并不等于INITIAL_STRONG_VALUE
2、对象未被其他强指针引用

当为第1种情况时,则直接增加其强引用计数:

while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
        // we're in the easy/common case of promoting a weak-reference
        // from an existing strong reference.
        if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
                std::memory_order_relaxed)) {
            break;
        }
        // the strong count has changed on us, we need to re-assert our
        // situation. curCount was updated by compare_exchange_weak.
    }

当为第2种情况时,会有如下情况:

if(目标生命周期受强引用计数器控制){
	if(强引用计数<=0){
		decWeak(id);
		return false;
	}
	增加强引用计数;
	if(强引用计数<=0,即上一步增加失败){
		decWeak(id);
		return false;
	}
			
}else 目标生命周期受弱引用计数器控制{
	if(目标对象不允许onIncStrongAttempted){
		decWeak(id);
       	return false;
	}
	增加强引用计数;	
}

对应代码:

bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
        // we're now in the harder case of either:
        // - there never was a strong reference on us
        // - or, all strong references have been released
        int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
        
        //目标生命周期受强引用计数器控制
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            // this object has a "normal" life-time, i.e.: it gets destroyed
            // when the last strong reference goes away
            
            //强引用计数<=0
            if (curCount <= 0) {
                // the last strong-reference got released, the object cannot
                // be revived.
                decWeak(id);
                return false;
            }

            // here, curCount == INITIAL_STRONG_VALUE, which means
            // there never was a strong-reference, so we can try to
            // promote this object; we need to do that atomically.
            
            //强引用计数>0
            while (curCount > 0) {
                if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
                        std::memory_order_relaxed)) {
                    break;
                }
                // the strong count has changed on us, we need to re-assert our
                // situation (e.g.: another thread has inc/decStrong'ed us)
                // curCount has been updated.
            }

			//增加失败
            if (curCount <= 0) {
                // promote() failed, some other thread destroyed us in the
                // meantime (i.e.: strong count reached zero).
                decWeak(id);
                return false;
            }
        } else {
            // this object has an "extended" life-time, i.e.: it can be
            // revived from a weak-reference only.
            // Ask the object's implementation if it agrees to be revived
            
            //目标对象不允许onIncStrongAttempted
            if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {
                // it didn't so give-up.
                decWeak(id);
                return false;
            }
            // grab a strong-reference, which is always safe due to the
            // extended life-time.
            curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
        }

        // If the strong reference count has already been incremented by
        // someone else, the implementor of onIncStrongAttempted() is holding
        // an unneeded reference.  So call onLastStrongRef() here to remove it.
        // (No, this is not pretty.)  Note that we MUST NOT do this if we
        // are in fact acquiring the first reference.
        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
            impl->mBase->onLastStrongRef(id);
        }
    }
    
    impl->addStrongRef(id);

    // curCount is the value of mStrong before we increment ed it.
    // Now we need to fix-up the count if it was INITIAL_STRONG_VALUE.
    // This must be done safely, i.e.: handle the case where several threads
    // were here in attemptIncStrong().
    // curCount > INITIAL_STRONG_VALUE is OK, and can happen if we're doing
    // this in the middle of another incStrong.  The subtraction is handled
    // by the thread that started with INITIAL_STRONG_VALUE.
    if (curCount == INITIAL_STRONG_VALUE) {
        impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
                std::memory_order_relaxed);
    }

    return true;
}