admin管理员组文章数量:1130349
几个相关class的定义位置:
system/core/libutils/RefBase.cpp 其中定义了class RefBase::weakref_impl
system/core$ vim include/utils/StrongPointer.h 其中定义了class sp
以以下代码运行为例:
链接:http://blog.csdn/mfbao01/article/details/6255655
class WPTest : public RefBase {
public:
WPTest(){
LOGD("WPTest constructor");
}
virtual ~WPTest() {
LOGD("WPTest destructor");
}
virtual void onFirstRef() {
LOGD("first weak ptr ref callback");
}
virtual void onLastStrongRef(const void* id) {
LOGD("last strong ptr ref callback");
}
virtual void onLastWeakRef(const void* id) {
LOGD("last weak ptr ref callback");
}
};
int main()
{
WPTest *T = new WPTest();
{
wp<WPTest> weakp(T);
{
LOGD("promote to strong ptr.../n");
sp<WPTest> strongp = weakp.promote();
LOGD("strong ptr's lifetime is just about to finish .../n");
}
LOGD("weak ptr's lifetime is just about to finish .../n");
}
LOGD("weak ptr is out of scope./n");
return 0;
}
第一步:调用wp构造方法
system/core/include/utils/RefBase.h
template<typename T> template<typename U>
wp<T>::wp(U* other)
: m_ptr(other)
{
if (other) m_refs = other->createWeak(this);
}
m_refs为weakref_type类型的指针
上一步调了实例对像WPTest类的createWeak方法,但其中没有定义。对于用智能指针的类,都要继承类RefBase
此方法调的就是RefBase中的方法
system/core/libutils/RefBase.cpp
RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
mRefs->incWeak(id); //id为上面wp指针
return mRefs;
}
所以,m_refs = mRefs
mRefs是在RefBase构造方法中始初化的,RefBase构造方法为:
RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}
所以mRefs->incWeak就是调用了weakref_impl中的方法,weakref_impl定义在
system/core/libutils/RefBase.cpp
class RefBase::weakref_impl : public RefBase::weakref_typeincWeak方法的实现在类weakref_type中
void RefBase::weakref_type::incWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this); //将基类指针强制转换为派生类类型
impl->addWeakRef(id); //调用派生类的实现 ---[1]---
const int32_t c = android_atomic_inc(&impl->mWeak); ---[2]---
ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
---[1]--- 先看看impl->addWeakRef(id)其中id是上面wp的this指针,也就是类wp的地址
void addWeakRef(const void* id) {
addRef(&mWeakRefs, id, mWeak);
}
其中mWeakRefs为ref_entry结构体的指针,值为初始值NULL; mWeak为对像的引用计数值,为初始值0
void addRef(ref_entry** refs, const void* id, int32_t mRef)
{
if (mTrackEnabled) {
AutoMutex _l(mMutex);
ref_entry* ref = new ref_entry;
// Reference count at the time of the snapshot, but before the
// update. Positive value means we increment, negative--we
// decrement the reference count.
ref->ref = mRef;
ref->id = id;
#if DEBUG_REFS_CALLSTACK_ENABLED
ref->stack.update(2);
#endif
ref->next = *refs;
*refs = ref;
}
}
以上代码就是生成一个新的ref_entry结构用来存放对象的弱引用计数和wp的地址,新结构体放在最上面,也就是当前引用数和对应wp对象的一个记录信息
---[2]--- 下一步增加引用计数值,android_atomic_inc就是将impl中的mWeak变量数值加1,mWeak变量就是管理wp对象的引用计数
第二步:promote成强引用指针
system/core/include/utils/RefBase.h
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;
}
这里就申明了一个强引用sp类对象result,m_refs上面说了是weakref_type指针
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
incWeak(id); //其中id为新创建sp类result的地址,它会新建个结构体保存当前引用计数值和sp地址加入链表,并将弱引用计数加1
weakref_impl* const impl = static_cast<weakref_impl*>(this);
int32_t curCount = impl->mStrong;
......
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
if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == 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 (android_atomic_cmpxchg(curCount, curCount + 1,
&impl->mStrong) == 0) {
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 = impl->mStrong;
}
......
impl->addStrongRef(id);
#if PRINT_REFS
ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif
// 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 = impl->mStrong;
while (curCount >= INITIAL_STRONG_VALUE) {
ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE,
"attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE",
this);
if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
&impl->mStrong) == 0) {
break;
}
// the strong-count changed on us, we need to re-assert the situation,
// for e.g.: it's possible the fix-up happened in another thread.
curCount = impl->mStrong;
}
return true;
}
impl->mStrong的初始值为INITIAL_STRONG_VALUE
#define INITIAL_STRONG_VALUE (1<<28)
impl->mFlags为0并没有设置OBJECT_LIFETIME_WEAK值
android_atomic_cmpxchg(curCount, curCount + 1, &impl->mStrong)中将impl->mStrong的值设为了curCount+1
之后再通过
android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
&impl->mStrong)将curCount-INITIAL_STRONG_VALUE附给impl->mStrong, 实现强指针的计数。
几个相关class的定义位置:
system/core/libutils/RefBase.cpp 其中定义了class RefBase::weakref_impl
system/core$ vim include/utils/StrongPointer.h 其中定义了class sp
以以下代码运行为例:
链接:http://blog.csdn/mfbao01/article/details/6255655
class WPTest : public RefBase {
public:
WPTest(){
LOGD("WPTest constructor");
}
virtual ~WPTest() {
LOGD("WPTest destructor");
}
virtual void onFirstRef() {
LOGD("first weak ptr ref callback");
}
virtual void onLastStrongRef(const void* id) {
LOGD("last strong ptr ref callback");
}
virtual void onLastWeakRef(const void* id) {
LOGD("last weak ptr ref callback");
}
};
int main()
{
WPTest *T = new WPTest();
{
wp<WPTest> weakp(T);
{
LOGD("promote to strong ptr.../n");
sp<WPTest> strongp = weakp.promote();
LOGD("strong ptr's lifetime is just about to finish .../n");
}
LOGD("weak ptr's lifetime is just about to finish .../n");
}
LOGD("weak ptr is out of scope./n");
return 0;
}
第一步:调用wp构造方法
system/core/include/utils/RefBase.h
template<typename T> template<typename U>
wp<T>::wp(U* other)
: m_ptr(other)
{
if (other) m_refs = other->createWeak(this);
}
m_refs为weakref_type类型的指针
上一步调了实例对像WPTest类的createWeak方法,但其中没有定义。对于用智能指针的类,都要继承类RefBase
此方法调的就是RefBase中的方法
system/core/libutils/RefBase.cpp
RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
mRefs->incWeak(id); //id为上面wp指针
return mRefs;
}
所以,m_refs = mRefs
mRefs是在RefBase构造方法中始初化的,RefBase构造方法为:
RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}
所以mRefs->incWeak就是调用了weakref_impl中的方法,weakref_impl定义在
system/core/libutils/RefBase.cpp
class RefBase::weakref_impl : public RefBase::weakref_typeincWeak方法的实现在类weakref_type中
void RefBase::weakref_type::incWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this); //将基类指针强制转换为派生类类型
impl->addWeakRef(id); //调用派生类的实现 ---[1]---
const int32_t c = android_atomic_inc(&impl->mWeak); ---[2]---
ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
---[1]--- 先看看impl->addWeakRef(id)其中id是上面wp的this指针,也就是类wp的地址
void addWeakRef(const void* id) {
addRef(&mWeakRefs, id, mWeak);
}
其中mWeakRefs为ref_entry结构体的指针,值为初始值NULL; mWeak为对像的引用计数值,为初始值0
void addRef(ref_entry** refs, const void* id, int32_t mRef)
{
if (mTrackEnabled) {
AutoMutex _l(mMutex);
ref_entry* ref = new ref_entry;
// Reference count at the time of the snapshot, but before the
// update. Positive value means we increment, negative--we
// decrement the reference count.
ref->ref = mRef;
ref->id = id;
#if DEBUG_REFS_CALLSTACK_ENABLED
ref->stack.update(2);
#endif
ref->next = *refs;
*refs = ref;
}
}
以上代码就是生成一个新的ref_entry结构用来存放对象的弱引用计数和wp的地址,新结构体放在最上面,也就是当前引用数和对应wp对象的一个记录信息
---[2]--- 下一步增加引用计数值,android_atomic_inc就是将impl中的mWeak变量数值加1,mWeak变量就是管理wp对象的引用计数
第二步:promote成强引用指针
system/core/include/utils/RefBase.h
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;
}
这里就申明了一个强引用sp类对象result,m_refs上面说了是weakref_type指针
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
incWeak(id); //其中id为新创建sp类result的地址,它会新建个结构体保存当前引用计数值和sp地址加入链表,并将弱引用计数加1
weakref_impl* const impl = static_cast<weakref_impl*>(this);
int32_t curCount = impl->mStrong;
......
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
if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == 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 (android_atomic_cmpxchg(curCount, curCount + 1,
&impl->mStrong) == 0) {
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 = impl->mStrong;
}
......
impl->addStrongRef(id);
#if PRINT_REFS
ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif
// 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 = impl->mStrong;
while (curCount >= INITIAL_STRONG_VALUE) {
ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE,
"attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE",
this);
if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
&impl->mStrong) == 0) {
break;
}
// the strong-count changed on us, we need to re-assert the situation,
// for e.g.: it's possible the fix-up happened in another thread.
curCount = impl->mStrong;
}
return true;
}
impl->mStrong的初始值为INITIAL_STRONG_VALUE
#define INITIAL_STRONG_VALUE (1<<28)
impl->mFlags为0并没有设置OBJECT_LIFETIME_WEAK值
android_atomic_cmpxchg(curCount, curCount + 1, &impl->mStrong)中将impl->mStrong的值设为了curCount+1
之后再通过
android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
&impl->mStrong)将curCount-INITIAL_STRONG_VALUE附给impl->mStrong, 实现强指针的计数。
版权声明:本文标题:Android中wp promote为sp流程 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://it.en369.cn/jiaocheng/1763929102a2972336.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论