#include "RefBase.h"
#include "atomic.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <typeinfo>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
// ---------------------------------------------------------------------------
namespace android {
#define LOG_TAG "RefBase"
static void __android_log_assert(const char *cond, const char *tag, const char *fmt, ...);
#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
#ifndef LOG_FATAL_IF
#define LOG_FATAL_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)__android_log_assert(#cond, LOG_TAG, ## __VA_ARGS__)) \
: (void)0 )
#endif
#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
#define INITIAL_STRONG_VALUE (1<<28)
static void __android_log_assert(const char *cond, const char *tag, const char *fmt, ...) {
char buf[4096];
if (fmt) {
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
}
printf("%s \n", buf);
}
// ---------------------------------------------------------------------------
class RefBase::weakref_impl: public RefBase::weakref_type {
public:
volatile int32_t mStrong;
volatile int32_t mWeak;
RefBase* const mBase;
volatile 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) {
}
};
// ---------------------------------------------------------------------------
void RefBase::incStrong(const void* id) const {
weakref_impl* const refs = mRefs;
refs->incWeak(id);
refs->addStrongRef(id);
const int32_t c = android_atomic_inc(&refs->mStrong);
ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
printf("incStrong c=0x%x \n", c);
if (c != INITIAL_STRONG_VALUE) {
return;
}
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
printf("incStrong mStrong=0x%x \n", refs->mStrong);
refs->mBase->onFirstRef();
}
void RefBase::decStrong(const void* id) const {
weakref_impl* const refs = mRefs;
refs->removeStrongRef(id);
printf("decStrong mStrong=0x%x \n", refs->mStrong);
const int32_t c = android_atomic_dec(&refs->mStrong);
#if PRINT_REFS
ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
printf("decStrong c=0x%x \n", c);
if (c == 1) {
refs->mBase->onLastStrongRef(id);
printf("decStrong mFlags=%x \n", refs->mFlags);
if ((refs->mFlags & OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
printf("decStrong delete self object \n");
delete this;
}
}
refs->decWeak(id);
printf("decStrong after decWeak c=0x%x \n", c);
}
void RefBase::forceIncStrong(const void* id) const {
weakref_impl* const refs = mRefs;
refs->incWeak(id);
refs->addStrongRef(id);
const int32_t c = android_atomic_inc(&refs->mStrong);
ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", refs);
printf("forceIncStrong c=0x%x \n", c);
#if PRINT_REFS
ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
switch (c) {
case INITIAL_STRONG_VALUE:
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
// fall through...
case 0:
refs->mBase->onFirstRef();
}
}
int32_t RefBase::getStrongCount() const {
printf("getStrongCount mStrong=0x%x \n", mRefs->mStrong);
return mRefs->mStrong;
}
RefBase* RefBase::weakref_type::refBase() const {
return static_cast<const weakref_impl*> (this)->mBase;
}
void RefBase::weakref_type::incWeak(const void* id) {
weakref_impl* const impl = static_cast<weakref_impl*> (this);
impl->addWeakRef(id);
const int32_t c = android_atomic_inc(&impl->mWeak);
ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
printf("incWeak c=0x%x, mWeak=0x%x \n", c, impl->mWeak);
}
void RefBase::weakref_type::decWeak(const void* id) {
weakref_impl* const impl = static_cast<weakref_impl*> (this);
impl->removeWeakRef(id);
printf("decWeak mWeak=0x%x \n", impl->mWeak);
const int32_t c = android_atomic_dec(&impl->mWeak);
ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
printf("decWeak c=0x%x, mWeak=0x%x \n", c, impl->mWeak);
if (c != 1)
return;
printf("decWeak mFlags =0x%x \n", impl->mFlags);
if ((impl->mFlags & OBJECT_LIFETIME_WEAK) == 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.
printf("decWeak mStrong=0x%x \n", impl->mStrong);
if (impl->mStrong == INITIAL_STRONG_VALUE) {
// Special case: we never had a strong reference, so we need to
// destroy the object now.
printf("decWeak object now11 \n");
delete impl->mBase;
} else {
printf("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
} else {
// less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
impl->mBase->onLastWeakRef(id);
printf("call decWeak here(onLastWeakRef)");
if ((impl->mFlags & OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
// this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object.
printf("decWeak object now22 \n");
delete impl->mBase;
}
}
}
bool RefBase::weakref_type::attemptIncStrong(const void* id) {
incWeak(id);
weakref_impl* const impl = static_cast<weakref_impl*> (this);
int32_t curCount = impl->mStrong;
ALOG_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);
// 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);
#if PRINT_REFS
ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif
if (curCount == INITIAL_STRONG_VALUE) {
android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
impl->mBase->onFi
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
android_sptest.rar (18个子文件)
android_sptest
StrongPointer.h 5KB
atomic.h 2KB
RefBase.cpp 11KB
RefBase.h 13KB
.settings
org.eclipse.core.resources.prefs 57B
org.eclipse.cdt.managedbuilder.core.prefs 3KB
.project 3KB
.cproject 64KB
main.cpp 2KB
Debug
sources.mk 551B
RefBase.d 133B
subdir.mk 722B
objects.mk 239B
makefile 1KB
main.d 121B
RefBase.o 95KB
android_sptest.exe 209KB
main.o 87KB
共 18 条
- 1
资源评论
andyhuabing
- 粉丝: 703
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功