Android上C++对象的wp提升为sp的过程
wp对象调用promote方法返回sp对象,如果sp指向的对象已经销毁,promote返回NULL
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;
}
可以将wp提升为sp的三种情况:
1、? 没有sp指向目标对象且mStrong == INITIAL_STRONG_VALUE
2、? 没有sp指向目标对象且mStrong == 0 且mFlags == OBJECT_LIFETIME_WEAK
3、有sp指向目标对象
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;
??? LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
?????????????? this);
??? while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
??????? if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
??????????? break;
??????? }
??????? curCount = impl->mStrong;
??? }
??
??? if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
??????? bool allow;
??????? if (curCount == INITIAL_STRONG_VALUE) {
??????????? // Attempting to acquire first strong reference...? this is allowed
??????????? // if the object does NOT have a longer lifetime (meaning the
??????????? // implementation doesn't need to see this), or if the implementation
??????????? // allows it to happen.
??????????? allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
????????????????? || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
??????? } else {
??????????? // Attempting to revive the object...? this is allowed
??????????? // if the object DOES have a longer lifetime (so we can safely
??????????? // call the object with only a weak ref) and the implementation
??????????? // allows it to happen.
??????????? allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
????????????????? && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
??????? }
??????? if (!allow) {
??????????? decWeak(id);
??????????? return false;
??????? }
??????? curCount = android_atomic_inc(&impl->mStrong);
?
??????? …
??????? }
??? }
??
??? impl->addStrongRef(id);
??? …
??? return true;
}